Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI-Powered Job & Skill Intelligence System

A local MVP for exploring job-market skill demand and identifying role-specific learning gaps. It combines a FastAPI backend, SQLite persistence, and a static dashboard frontend.

What the MVP does

  • Discovers job pages with Exa and retrieves available page text/highlights.
  • Applies conservative, deterministic job-quality ranking: obvious search/navigation noise is removed while borderline results can remain for review.
  • Deduplicates job pages globally by normalized source URL, so the same job is stored only once.
  • Associates a reused job with every search run that returned it, so repeated searches still have usable analytics and skill-gap results.
  • Extracts job title, company, location, employment type, experience, qualifications, and normalized technical skills with deterministic rules.
  • Stores jobs, search runs, skills, profiles, and resume metadata in SQLite.
  • Shows per-search-run market intelligence: skill demand, top companies, and locations.
  • Supports local user profiles, manual profile skills, and PDF/DOCX resume skill extraction.
  • Compares profile skills with a selected search run to produce matched skills, missing skills, and demand-based priorities.
  • Generates deterministic learning recommendations by default. Optional OpenAI recommendations can provide validated explanation and practice text.

Prerequisites

  • Python 3.10 or newer
  • pip
  • An Exa API key for live job searches

Local setup

From the project root:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt

Create a local configuration file:

Copy-Item .env.example .env

Set EXA_API_KEY in .env before performing live job searches. Keep API keys and other secrets only in .env; it is ignored by Git.

Start the application:

uvicorn app.main:app --reload

Open:

Configuration

All configuration is loaded from .env.

Setting Purpose Default
APP_NAME Application name reported by the API. AI-Powered Job & Skill Intelligence System
APP_VERSION Application version reported by the API. 0.1.0
DATABASE_URL SQLAlchemy database URL. This MVP uses local SQLite by default. sqlite:///./job_intelligence.db
EXA_API_KEY Required only for live Exa job searches. Empty
LLM_API_KEY Optional OpenAI API key for recommendation narratives. Empty
LLM_MODEL Optional OpenAI model name; must be set with LLM_API_KEY to enable LLM narratives. Empty
LLM_TIMEOUT_SECONDS Timeout for the optional OpenAI request. 15
UPLOAD_DIR Local directory for uploaded resume files. uploads
MAX_UPLOAD_SIZE_MB Maximum accepted PDF/DOCX resume size in MB. 5

The app works without OpenAI configuration: it uses deterministic recommendations. The optional recommendation service receives structured skill-gap data only; it does not receive raw resume text.

Typical dashboard flow

  1. Create a profile and enter manual skills, or upload a PDF/DOCX resume.
  2. Search for a target role such as Python Developer Fresher.
  3. Review newly saved job pages and their extracted fields/skills.
  4. Review market skill demand, leading companies, and locations for that search run.
  5. Run skill-gap analysis with the profile and search-run IDs prefilled by the dashboard.

Repeated searches preserve global job URL deduplication. Existing jobs are reused and linked to the new search run, so its analytics remain available without duplicating job records.

API examples

Search for jobs:

Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8000/api/jobs/search `
  -ContentType "application/json" `
  -Body '{"role":"Python Developer Fresher","num_results":5}'

Create a profile:

Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8000/api/profiles `
  -ContentType "application/json" `
  -Body '{"name":"Asha","target_role":"Python Developer"}'

Inspect a search run:

Invoke-RestMethod "http://127.0.0.1:8000/api/analysis/overview?search_run_id=1"
Invoke-RestMethod "http://127.0.0.1:8000/api/analysis/skills?search_run_id=1"

Run skill-gap analysis:

Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8000/api/analysis/skill-gap `
  -ContentType "application/json" `
  -Body '{"profile_id":1,"search_run_id":1}'

To refresh extracted fields and skills for stored jobs without calling Exa:

Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8000/api/jobs/process `
  -ContentType "application/json" `
  -Body '{}'

Privacy and local storage

Resume files and their extracted text are stored locally using the configured upload directory and local database. Resume text is processed locally for skill detection and is not sent to Exa or to the optional LLM recommendation service. The optional recommendation service receives structured skill-gap information, such as canonical skill names and demand figures.

SQLite lifecycle

This is a local SQLite MVP. On startup, create_all() creates missing tables, but it does not migrate or alter existing table schemas.

For development, if existing local data is not needed, stop the server, remove the local database, and restart the application so the tables are recreated:

Remove-Item .\job_intelligence.db
uvicorn app.main:app --reload

This reset removes stored database data. Uploaded resume files in UPLOAD_DIR are separate local files and should be removed manually only if they are no longer needed.

Testing

With the virtual environment activated:

python -m pytest

Project layout

  • app/api: FastAPI routes
  • app/models: SQLAlchemy models
  • app/schemas: API request/response schemas
  • app/services: job discovery, extraction, analysis, profiles, resumes, and recommendations
  • app/repositories: database query helpers
  • frontend: dashboard HTML, CSS, and JavaScript
  • tests: automated unit and API workflow tests

Known limitations

  • Scanned or image-only PDFs are not OCR processed.
  • DOCX table content is not currently extracted.
  • Only skills in app/data/skill_taxonomy.json can be detected.
  • Job and company extraction is deterministic and conservative; unusual job-page formats can produce incomplete fields.
  • Recommendation quality depends on the extracted job and skill data.
  • SQLite is suitable for this local MVP, not production-scale deployment.
  • Automated tests mock external Exa and OpenAI behavior; they do not guarantee external provider availability.
  • Browser/E2E tests are not currently implemented.

About

AI-powered job intelligence platform that discovers job opportunities, extracts structured requirements, analyzes market demand, identifies skill gaps, and provides personalized recommendations.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages