Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.
Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.
- ☑ Retrieve job listings from the Adzuna API
- ☑ Store essential job-lead information in SQLite
- ☑ Prevent duplicate listings from being saved
- ☑ Search using user-provided keywords and locations
- ☑ Display leads through a paginated web dashboard
- ☑ Filter leads by status
- ☑ Update leads as new, saved, applied, or archived
- ☑ Export all or status-filtered leads to CSV
- ☑ Permanently delete archived leads with confirmation
- ☑ Protect active leads from permanent deletion
- Python 3.13+
- FastAPI
- SQLite
- Jinja2
- HTML and CSS
- JavaScript
- HTTPX
- pytest
- uv
Before running the application, you will need:
- Python 3.13 or newer
- The uv package manager
- An Adzuna developer account with an application ID and API key
Clone the repository:
git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScoutInstall the project dependencies:
uv syncCopy .env.example to a new file named .env, then add your Adzuna credentials:
ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_keyThe .env file and local SQLite databases are excluded from version control.
Start the development server:
uv run fastapi devOpen the dashboard at:
http://127.0.0.1:8000
FastAPI’s interactive API documentation is available at:
http://127.0.0.1:8000/docs
The SQLite database and required table are created automatically when the application starts.
- Enter job-search keywords and a location.
- Select Refresh Jobs to retrieve current listings from Adzuna.
- Review the imported leads on the dashboard.
- Change a lead’s status to new, saved, applied, or archived.
- Filter the dashboard using the status tabs.
- Export all visible categories or the currently filtered status to CSV.
- Permanently delete an archived lead using its trash button.
Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.
| Method | Endpoint | Purpose |
|---|---|---|
GET | / | Display the web dashboard |
GET | /health | Check application health |
GET | /job-leads | Return all stored job leads |
POST | /job-leads/refresh | Retrieve and import listings from Adzuna |
PATCH | /job-leads/{job_lead_id}/status | Update a lead’s status |
DELETE | /job-leads/{job_lead_id} | Permanently delete an archived lead |
GET | /job-leads/export | Download all or status-filtered leads as CSV |
Run the complete automated test suite:
uv run pytest -vThe current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.
- ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
- ☐ Add explainable match estimates using a user-defined skills profile
- ☐ Add configurable search preferences
- ☐ Deploy the application with persistent database storage
