Django>=5.1,<7.0 djangorestframework==3.17.1 djangorestframework-simplejwt[crypto]==5.5.1 psycopg[binary]==3.3.3 django-cors-headers==4.9.0 drf-spectacular==0.29.0 ruff==0.15.9 pytest-django==4.12.0 django-filter==25.2 python-dotenv==1.2.2 PyYAML>=6.0,<7.0 # Module 5 checkpoint auto-import โ€” fetch + parse course-outline pages # (schema.org/Course JSON-LD via Coursera/DataCamp, generic HTML fallback, # YouTube Data API, freeCodeCamp GitHub JSON). No headless browser. `requests` # is already present transitively (transformers/huggingface); pinned direct # since the importers import it explicitly. `lxml` is the bs4 parser backend. requests>=2.31 beautifulsoup4>=4.12,<5.0 # Module 8 (resume parsing) โ€” lexical layer. pdfplumber>=0.11,<1.0 rapidfuzz>=3.0,<4.0 # Module 8 full NER fallback chain (Nucha BERT -> JobBERT -> SkillNER -> SBERT+pgvector). # CPU-only torch wheel to avoid the ~2 GB CUDA payload. Verified 2026-04-22 as # installable end-to-end on Python 3.13.11 on Windows. --extra-index-url https://download.pytorch.org/whl/cpu torch>=2.11,<3.0 transformers>=4.44,<5.0 sentence-transformers>=3.0,<4.0 skillNer>=1.0.3 # skillNer transitively imports IPython (notebook display helpers) at extractor # construction time โ€” without this pin every resume upload logs # "ner.skillner: raised No module named 'IPython', skipping" and layer 3 goes # dark. See research/06-dataset-sourcing.md ยง5 NER fallback chain. ipython>=8.0,<9.0 spacy>=3.8,<4.0 pgvector>=0.3.6,<1.0 # Deployment (HF Spaces Docker + Neon Postgres). Additive only; unused locally # (runserver/local Postgres keep working). gunicorn = WSGI server, whitenoise = # static file serving (Django admin/DRF) without nginx, dj-database-url = parse # Neon's single DATABASE_URL. gunicorn>=23.0 whitenoise>=6.8 dj-database-url>=2.3