A small FastAPI service for uploading PDF files, extracting table rows with pdfplumber, and using the Gemini API to identify and normalize table headers from the first page image.
The current API exposes a health/root endpoint and a PDF parsing endpoint. It is designed to support a frontend client, such as a Next.js app, that sends PDF files and receives structured JSON containing detected headers and extracted table rows.
pdf-parser-service/
├── main.py # FastAPI app, CORS middleware, and API routes
├── parser/
│ ├── __init__.py
│ └── parser.py # PDF image/table extraction logic
├── gemini/
│ ├── __init__.py
│ └── gemini.py # Gemini API integration for header extraction
├── app/
│ ├── routers/ # Conventional FastAPI router modules
│ ├── models/ # Database/domain models
│ ├── schemas/ # Pydantic request/response schemas
│ └── services/ # Business logic/service modules
├── tests/ # Test suite
├── ARCHITECTURE # Short architecture notes
├── requirements.txt # Legacy pip requirements
├── pyproject.toml # Project metadata, dependencies, and tooling config
├── .env.example # Environment variable template
├── .gitignore
└── .vscode/
└── settings.json # Optional editor defaults
Note: app/, routers/, models/, schemas/, and services/ are included as a conventional FastAPI scaffold for future organization. The existing source code remains unchanged.
- Python 3.11 or newer
- A Gemini API key
- System packages required by
pdfplumber/PDF rendering in your environment
Create and activate a virtual environment:
python3.11 -m venv .venv
source .venv/bin/activateInstall dependencies:
pip install -e .Alternatively, install from the legacy requirements file:
pip install -r requirements.txtCreate your local environment file:
cp .env.example .envThen set GEMINI_API_KEY in .env.
The service currently reads the following environment variable:
| Variable | Required | Description |
|---|---|---|
GEMINI_API_KEY |
Yes | API key used by google-genai for Gemini header extraction. |
CORS is currently configured in main.py with allow_origins=["*"]. For production, restrict this to the actual frontend domain.
Development server with reload:
uvicorn main:app --reloadEquivalent FastAPI CLI command:
fastapi dev main.pyProduction-style Uvicorn command:
uvicorn main:app --host 0.0.0.0 --port 8000The API will be available at:
GET /- health messagePOST /parse-pdf- multipart PDF upload using form fieldfile
Example request:
curl -X POST "http://127.0.0.1:8000/parse-pdf" \
-F "file=@/path/to/file.pdf"parser.Parserwrites uploaded PDFs and first-page images to temporary files during processing.gemini.get_header_JSON_Listsends the first page image to Gemini and requests a JSON array of normalized headers.- Table rows are extracted with
pdfplumber. - Future source refactors can move
main.pyintoapp/main.py, split endpoints intoapp/routers/, and move parsing/Gemini logic underapp/services/.
A tests/ directory is included for future tests. Once tests are added, run them with:
pytest