# How the FastAPI PDF Conversion Server Works in opendataloader-pdf

> Learn how the FastAPI server in opendataloader-pdf enables PDF conversion via POST /v1/convert/file. Discover its singleton DocumentConverter handling multipart uploads and structured JSON output.

- Repository: [opendataloader-project/opendataloader-pdf](https://github.com/opendataloader-project/opendataloader-pdf)
- Tags: how-to-guide
- Published: 2026-03-20

---

**The FastAPI PDF conversion server exposes document processing through a singleton `DocumentConverter` instance that handles multipart file uploads at `POST /v1/convert/file`, returning structured JSON representations of PDF content.**

The `opendataloader-project/opendataloader-pdf` repository implements a production-ready HTTP interface for PDF document conversion using FastAPI. This lightweight service wraps the Docling conversion engine, providing a scalable endpoint that processes uploads and returns standardized document structures without reinitializing the heavy conversion backend for each request.

## FastAPI Application Architecture

The server architecture centers on efficient resource management and clean route separation. All core logic resides in **[`python/opendataloader-pdf/src/opendataloader_pdf/hybrid_server.py`](https://github.com/opendataloader-project/opendataloader-pdf/blob/main/python/opendataloader-pdf/src/opendataloader_pdf/hybrid_server.py)**, which implements the application factory pattern and lifespan management.

### Server Bootstrap and Route Registration

The `create_app()` function initializes the FastAPI instance (titled *"Docling Fast Server"*) and registers the HTTP interface. According to the source code at lines **55‑66**, the application exposes two endpoints:

- **`GET /health`** – Returns a simple status check for load balancers and monitoring
- **`POST /v1/convert/file`** – Accepts multipart PDF uploads and triggers the conversion pipeline

This registration pattern keeps the application factory clean while ensuring all routes are documented in the automatic OpenAPI schema generated by FastAPI.

### Singleton DocumentConverter Pattern

To avoid the expensive overhead of reinitializing the Docling engine per request, the server uses a module-level `converter` variable managed by an async lifespan context manager. As implemented at lines **74‑88**, the `lifespan` handler calls `create_converter()` during startup, passing CLI-derived options for OCR and enrichments, then stores the result in the global `converter` variable.

This singleton pattern ensures that heavy model loading happens exactly once during the server's lifespan, making the **FastAPI PDF conversion** endpoint capable of handling high-throughput scenarios without memory bloat or initialization delays.

## PDF Conversion Endpoint Implementation

The core conversion logic resides in the `convert_file` route handler, which orchestrates validation, temporary file management, and response formatting.

### Request Handling and Validation

The `convert_file` endpoint (defined at lines **16‑31** and implemented through **98‑107**) processes incoming requests through a strict pipeline:

1. **File size validation** – Enforces the `MAX_FILE_SIZE` limit of 100 MiB to prevent resource exhaustion
2. **Temporary file creation** – Writes the multipart upload to a secure temp file on disk
3. **Conversion execution** – Invokes `converter.convert(tmp_path, page_range=…)` with optional page range filtering
4. **Performance tracking** – Measures processing time for observability

The endpoint accepts two form fields: `files` (required multipart upload) and `page_ranges` (optional string specifying which pages to process, e.g., `"1-5"`).

### Response Structure and Formatting

After conversion, the server sanitizes Unicode content and builds a structured JSON payload using the `build_conversion_response` helper (lines **73‑80**). The response follows the DoclingDocument schema and includes:

- **`status`** – Either *success*, *partial_success*, or error states
- **`errors`** – Detailed messages when conversion issues occur
- **`failed_pages`** – Array of page numbers that failed during *partial_success* scenarios
- **`processing_time`** – Duration in seconds for performance monitoring

The JSON output is generated via `document.export_to_dict()`, ensuring compatibility with downstream document processing pipelines.

## Starting and Using the Server

Deploy the server using the provided CLI entry point, then interact with it via HTTP clients or programmatic Python requests.

### Install and Launch

```bash
pip install "opendataloader-pdf[hybrid]"
opendataloader-pdf-hybrid --port 5002   # Binds to 0.0.0.0:5002 by default

```

### Convert PDFs with cURL

Send multipart requests directly to the conversion endpoint:

```bash
curl -X POST "http://localhost:5002/v1/convert/file" \
     -F "files=@/path/to/document.pdf" \
     -F "page_ranges=1-5" \
     -H "Accept: application/json"

```

### Python Client Integration

Use the `requests` library to process PDFs programmatically:

```python
import requests

url = "http://localhost:5002/v1/convert/file"
files = {"files": open("sample.pdf", "rb")}
data = {"page_ranges": "1-3"}          # Optional page filtering

resp = requests.post(url, files=files, data=data)
print(resp.status_code)                # 200 on success

print(resp.json())                     # Structured DoclingDocument JSON

```

### Health Check Endpoint

Verify service availability before submitting conversion jobs:

```bash
curl http://localhost:5002/health

# {"status":"ok"}

```

## Summary

- **The FastAPI server** in [`hybrid_server.py`](https://github.com/opendataloader-project/opendataloader-pdf/blob/main/hybrid_server.py) exposes PDF conversion through a singleton `DocumentConverter` managed by a lifespan context manager (lines **74‑88**).
- **Two routes** handle all traffic: `GET /health` for monitoring and `POST /v1/convert/file` for document processing (lines **55‑66**).
- **Request validation** enforces a 100 MiB file size limit and optional page range filtering before executing conversion.
- **Responses follow the DoclingDocument schema**, including status codes, error details, failed page arrays, and processing timestamps via `build_conversion_response`.

## Frequently Asked Questions

### What is the endpoint URL for PDF conversion?

The conversion endpoint is available at `POST /v1/convert/file` on whichever host and port the server binds to (default `0.0.0.0:5002`). This path accepts multipart form data containing the PDF file and optional page range specifications.

### How does the server handle large PDF files?

The server validates uploads against a `MAX_FILE_SIZE` constant of 100 MiB before writing them to temporary storage. Files exceeding this limit are rejected immediately to prevent memory pressure and disk exhaustion on the host system.

### Can I convert specific page ranges within a PDF?

Yes. The `convert_file` endpoint accepts an optional `page_ranges` form field (e.g., `"1-5"` or `"3,7,10-15"`) that it passes directly to the underlying `converter.convert()` method. This allows selective processing of large documents without converting unnecessary pages.

### What response format does the conversion endpoint return?

The endpoint returns a structured JSON object containing the DoclingDocument representation via `document.export_to_dict()`, plus metadata fields including `status`, `errors`, `failed_pages`, and `processing_time`. This schema is compatible with the Docling document processing ecosystem and suitable for downstream NLP pipelines.