Documentation

Installation Guide

ThreatLens Live Cyber Threat Intelligence Dashboard

Step-by-step Setup Verified Instructions Chat Support
Back to Project
Complete Guide

Getting ThreatLens Running

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.

Before You Start — Prerequisites

  • Python 3.10 or newer. Grab it from python.org. During installation on Windows, tick the box that says "Add Python to PATH" — if you miss it, nothing in this guide will work and you'll spend an hour confused. Check with python --version in a terminal.
  • pip — comes bundled with Python. Verify with pip --version.
  • A code editor. VS Code is free and fine.
  • Three free API keys. Sign up at abuse.ch (MalwareBazaar), abuseipdb.com, and console.groq.com. All free, all take two minutes each. Do this first so you're not context-switching later.
  • Redis — only if you want the automatic scheduling. Skip it for now.

Step 1 — Extract the project

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.

Step 2 — Create the virtual environment

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.

Step 3 — Install the dependencies

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.

Step 4 — Set up your environment variables

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 summaries
  • MALWAREBAZAAR_API_KEY — from your abuse.ch account
  • ABUSEIPDB_API_KEY — from abuseipdb.com

Leave DJANGO_SECRET_KEY as whatever's in there for local development. You'll change it before deploying anywhere public.

Step 5 — Build the database

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.

Step 6 — Create your login

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.

Step 7 — Pull the actual threat data

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.

Step 8 — Start it up

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.

How to Check It's Actually Working

  1. The main feed has threat cards in it, not an empty state.
  2. Leave the tab open for 30 seconds and watch the feed refresh on its own — that's the HTMX polling.
  3. Type CVE-2024 into the search box. Results should filter as you type, before you press Enter.
  4. Open the map page. Countries should be shaded, not blank grey.
  5. Click any threat card, then hit the AI Summary button. You should get a paragraph back in a few seconds.

If all five of those work, you're done. Go make your report.

Things That Usually Go Wrong

"ModuleNotFoundError: No module named django"

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.

The AI Summary button returns an error inside the card

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.

fetch_malwarebazaar returns a 401 or unauthorized error

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.

Celery won't start on Windows

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.

Optional — Turning On Automatic Refresh

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.

Need Help?

Our team is here to assist you with installation and setup.

Chat with Us