Job API

job_api.py provides programmatic access to the scored jobs in ~/.jobserve.gdbm. It supports three deployment modes (CLI, WSGI, FastAPI) and four output formats (JSON, CSV, YAML, XML).

Current Deployment

Running as a FastAPI server on the home machine, reverse-proxied from cv.critchley.biz/jobs. Not yet set up to start on boot — either needs a systemd unit or a rewrite as a pure WSGI script behind Apache httpd.

Deployment Modes

CLI: python3 job_api.py --days 14 --min-score 6 --format csvWSGI: application(environ, start_response) callable, config via env vars JOBSERVE_DBFILE, JOBSERVE_DAYS, JOBSERVE_MIN_SCORE, JOBSERVE_REFRESH_TIMEOUTFastAPI: uvicorn job_api:app, endpoint GET /jobs with query params ?days=&min_score=, content negotiation via Accept header. Also has GET /health.

Content Negotiation

Format is selected by Accept header (WSGI/FastAPI) or --format flag (CLI).Accept: text/csv → CSVAccept: application/yaml → YAML (requires PyYAML)Accept: application/xml or text/xml → XMLDefault: JSONImplemented via FORMATTERS dict mapping content-type to (formatter_fn, mime_string) and ACCEPT_MATCHERS list for header parsing.

Database Locking

Opens database read-only. If gdata raises GDataLockedError (another process writing), returns 503 Service Unavailable with Retry-After and Refresh headers so the client (or browser) retries automatically. The locked response is formatted in whatever content type was negotiated.

Filtering Logic

Includes: scored jobs (has scored_job field) with score >= min_score from last N days.Excludes: unclassified emails, application confirmations, unscored records.Output fields per job: message_id, score, reference, job_title, company, age (human-readable), location, salary, date, job_url, score_reason.

Module-Level Python API

get_jobs_data(db_path, days, min_score) → dict with status/count/jobs — primary programmatic interface.get_jobs_output(db_path, days, min_score, format) → formatted string.build_success_payload(db_path, days, min_score, accept_header) → (body, content_type) — shared by WSGI and FastAPI paths.

TODO

• Set up auto-start (systemd unit or rewrite as Apache WSGI script)• Add applications endpoint (currently only scored jobs are exposed)• Consider authentication (currently open on reverse proxy)

version 1