Budget about twenty minutes, most of which is waiting for pip. If you've set up a Django project before, half of this will be familiar. If you haven't, follow it line by line and you'll be fine.
python --version in a terminal.pip --version.Unzip the folder you downloaded. Put it somewhere sensible like C:\projects\threatlens or ~/projects/threatlens. Avoid folder names with spaces in them — Python virtual environments get weird about that on Windows.
Open a terminal and cd into that folder. You should see manage.py sitting there when you run dir or ls. If you don't, you're one folder too high up.
Run this:
python -m venv venv
Then activate it. Windows:
venv\Scripts\activate
Mac or Linux:
source venv/bin/activate
You'll know it worked because (venv) shows up at the start of your terminal line. Every command after this needs that to be there.
pip install -r requirements.txt
This pulls in Django, Celery, django-celery-beat, requests, python-dotenv and the rest. Takes two or three minutes depending on your connection. Let it finish.
There's a file called .env.example in the project root. Copy it and rename the copy to just .env — no filename, just the extension. On Windows you may need to do this from the terminal because Explorer fights you on it:
copy .env.example .env
Open .env in your editor and fill in these three:
GROQ_API_KEY — from console.groq.com, powers the AI summariesMALWAREBAZAAR_API_KEY — from your abuse.ch accountABUSEIPDB_API_KEY — from abuseipdb.comLeave DJANGO_SECRET_KEY as whatever's in there for local development. You'll change it before deploying anywhere public.
python manage.py migrate
This creates db.sqlite3 with all the tables. No PostgreSQL setup, no database server to install, nothing. Takes about five seconds.
python manage.py createsuperuser
It'll ask for a username, email and password. The email can be blank. The password won't show as you type it — that's normal, keep typing. Remember what you set, because every page in this app requires a login.
This is the fun part. Run:
python manage.py fetch_all_feeds
It'll work through NVD, CISA KEV, MITRE ATT&CK, MalwareBazaar and AbuseIPDB in sequence, printing what it's ingesting as it goes. First run takes two to three minutes because MITRE's STIX bundle is a big download.
If you'd rather run them one at a time to see what each does:
python manage.py fetch_nvd_cves
python manage.py fetch_cisa_kev
python manage.py fetch_mitre_attack
python manage.py fetch_malwarebazaar
python manage.py fetch_abuseipdb
All of them upsert on the source's own ID, so running any of them again is completely safe. No duplicates, ever.
python manage.py runserver
Open http://127.0.0.1:8000 in your browser, log in with the superuser you made, and the dashboard should load with a populated feed.
CVE-2024 into the search box. Results should filter as you type, before you press Enter.If all five of those work, you're done. Go make your report.
Your virtual environment isn't active. Look at your terminal — do you see (venv) at the start of the line? If not, re-run the activate command from Step 2. This is far and away the most common issue and it catches everyone at least once.
Your Groq key is missing or wrong. Open .env, check GROQ_API_KEY is filled in with no quotes and no trailing spaces, then restart runserver — Django only reads the env file at startup, so changes need a restart. If the key is right and it still fails, the model name may have moved on; set GROQ_MODEL=openai/gpt-oss-120b explicitly in .env.
abuse.ch made authentication mandatory on all requests, so an empty MALWAREBAZAAR_API_KEY now fails where it used to work. Get a free key from your abuse.ch account and paste it in.
Expected. Celery doesn't officially support Windows anymore. You don't need it for the app to work — the fetch commands run fine on their own. If your report needs the scheduling section demonstrated, run Celery on WSL or on the VPS instead. Don't burn your evening on this one.
Only bother with this on Linux or a VPS. Get Redis running, then in three separate terminals:
celery -A threatlens worker --loglevel=INFO
celery -A threatlens beat --scheduler django_celery_beat.schedulers:DatabaseScheduler --loglevel=INFO
python manage.py setup_periodic_tasks
That last command only needs running once — it registers the 15 to 30 minute schedule in the database. After that you can change the intervals from Django admin at /admin/django_celery_beat/periodictask/ without touching any code.
Our team is here to assist you with installation and setup.