Ingest API β Backend (Python) Quickstart
Purpose
- FastAPI service that ingests a URL or PDF, creates embeddings (Mistral), and upserts vectors to Pinecone.
Key files
ingest_api.pyβ main FastAPI service (endpoints, job tracking, OCR fallback).pdf-to-pinecone.py,3-embedding-pinecone.pyβ original CLI scripts (reference).
Environment variables (required)
PINECONE_API_KEYβ Pinecone API keyPINECONE_HOSTβ Pinecone host URLPINECONE_INDEXβ Pinecone index nameMISTRAL_API_KEYβ Mistral embeddings API keyADMIN_API_KEYorADMIN_API_KEYSβ comma-separated admin keys forx-api-key
Optional / OCR
TESSERACT_PATHβ path to Tesseract executable (default:C:\Program Files\Tesseract-OCR\tesseract.exe)POPPLER_PATHβ popplerbinpath forpdf2image(default:C:\poppler\Library\bin)OCR_LANGβ tesseract languages (e.g.ben+eng)
Install & run
- Create venv and install deps:
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
pip install pdf2image pytesseract
- Start service:
uvicorn ingest_api:app --host 0.0.0.0 --port 8000
API endpoints
POST
/ingest/url- Headers:
x-api-key: <ADMIN_API_KEY> - Body JSON:
{ "url":"https://...", "namespace":"workspace", "webhook_url":"https://..." } - Response:
202 { "status":"accepted","job_id":"..." }
- Headers:
POST
/ingest/pdf- Headers:
x-api-key: <ADMIN_API_KEY> - Multipart form:
file(PDF), optionalnamespace, optionalwebhook_url - Response:
202 { "status":"accepted","job_id":"..." }
- Headers:
GET
/jobs/{job_id}- Headers:
x-api-key: <ADMIN_API_KEY> - Returns job status and result JSON
- Headers:
Webhook
- If
webhook_urlprovided in request, backend POSTs job result{ job_id, status, result, error }when finished (best-effort).
OCR notes
- service tries
pdfplumberfirst; if pages appear scanned/non-text it falls back topdf2image + pytesseract. - Install Tesseract + Poppler on server for OCR.
Production recommendations
- Do not expose
ADMIN_API_KEYto browsers. Use a server-side proxy (Next.js, Supabase function, etc.). - Replace in-memory
JOBSwith persistent store (Supabase/Redis/Postgres) to survive restarts. - Use a task queue (Celery/RQ) for retries/long-running jobs in production.
Example curl
curl -X POST http://localhost:8000/ingest/url \
-H "Content-Type: application/json" \
-H "x-api-key: supersecret" \
-d '{"url":"https://example.com/article","namespace":"workspace"}'
curl -X POST http://localhost:8000/ingest/pdf \
-H "x-api-key: supersecret" \
-F "file=@/path/to/file.pdf" \
-F "namespace=workspace"
See also: INGEST_API.md for general integration notes and Next.js example in admin-nextjs-example/.