--- title: Docling Multi-Template Extraction API emoji: 📄 colorFrom: blue colorTo: green sdk: docker pinned: false license: apache-2.0 --- # Docling Multi-Template Document Extraction API 🚀 Deploy Docling on Hugging Face Spaces with dynamic template matching for invoice and payment advice extraction. ## Features - 🔄 **Dynamic Template Discovery**: Automatically detects and loads templates from the `templates/` directory - 🎯 **Smart Name Matching**: Works with any naming convention (snake_case, kebab-case, PascalCase) - 🤖 **Auto-Detection**: Automatically identifies document types from content - 📊 **Structured JSON Output**: Extract invoices, payment advices, and custom documents to JSON - 🌐 **REST API**: Easy integration with n8n, Make, Zapier, or custom workflows - 🎨 **Web UI**: Built-in Gradio interface for testing ## Quick Start ### Deploy to Hugging Face Spaces 1. **Create a new Space:** - Go to [huggingface.co/spaces](https://huggingface.co/spaces) - Click "Create new Space" - Name: `docling-api` (or your preferred name) - SDK: **Docker** - Hardware: **CPU basic (free tier)** - 2 vCPU, 16 GB RAM 2. **Clone and push code:** ```bash git clone https://huggingface.co/spaces/YOUR-USERNAME/docling-api cd docling-api # Copy all files from this project # (app.py, templates/, requirements.txt, Dockerfile, README.md) git add . git commit -m "Initial deployment" git push ``` 3. **Wait for build** (5-10 minutes for first deployment) 4. **Your API is live at:** `https://YOUR-USERNAME-docling-api.hf.space` ## API Endpoints ### Extract Document Data ```http POST /api/extract Content-Type: multipart/form-data Query Parameters: - template_type: auto | payment_advice | invoice | custom_template ``` **Example with curl:** ```bash curl -X POST "https://YOUR-SPACE.hf.space/api/extract?template_type=auto" \ -F "file=@invoice.pdf" ``` **Response:** ```json { "success": true, "template_used": "invoice", "data": { "bill_no": "JRPL14725-26", "bill_date": "03-12-2025", "total_amount": 16618.0, "seller": { "name": "Jobuss Resources Pvt Ltd", "gst_no": "27AAECJ2353C1ZX" }, "buyer": { "name": "Reliance Industries Limited", "vendor_code": "3347687" } }, "filename": "invoice.pdf" } ``` ### List Available Templates ```http GET /api/templates ``` ### Template Variations ```http GET /api/templates/variations ``` ## Flexible Naming All these work identically: ```bash ?template_type=payment_advice # snake_case ?template_type=payment-advice # kebab-case ?template_type=PaymentAdvice # PascalCase ?template_type=PAYMENT_ADVICE # UPPER_CASE ``` ## Using with n8n ### Setup HTTP Request Node 1. **Method:** POST 2. **URL:** `https://YOUR-SPACE.hf.space/api/extract` 3. **Query Parameters:** - Name: `template_type` - Value: `auto` (or specific template name) 4. **Body Content Type:** Multipart-Form-Data 5. **Body Parameters:** - Name: `file` - Type: `n8n Binary File` - Input Data Field Name: `data` (or your binary field) ### Example n8n Workflow ``` [Trigger/File Input] ↓ [HTTP Request - Docling API] ↓ [Code Node - Parse Response] ↓ [Database/Spreadsheet Output] ``` ### Parse Response in Code Node (n8n) ```javascript // Access the extracted data const response = $input.item.json; if (response.success) { const data = response.data; return { invoice_number: data.bill_no, date: data.bill_date, amount: data.total_amount, vendor: data.seller?.name, all_data: data }; } ``` ## Adding Custom Templates Create a new file in `templates/` directory: ### Example: `templates/purchase_order_template.py` ```python from pydantic import BaseModel, Field from typing import Optional, List class POLineItem(BaseModel): item_code: Optional[str] = Field(default=None) description: Optional[str] = Field(default=None) quantity: Optional[float] = Field(default=None) unit_price: Optional[float] = Field(default=None) total: Optional[float] = Field(default=None) class Vendor(BaseModel): vendor_id: Optional[str] = Field(default=None) name: Optional[str] = Field(default=None) address: Optional[str] = Field(default=None) class PurchaseOrder(BaseModel): document_type: str = Field(default="purchase_order") po_number: Optional[str] = Field(default=None) po_date: Optional[str] = Field(default=None) delivery_date: Optional[str] = Field(default=None) vendor: Optional[Vendor] = Field(default=None) subtotal: Optional[float] = Field(default=None) tax_amount: Optional[float] = Field(default=None) total_amount: Optional[float] = Field(default=None) line_items: Optional[List[POLineItem]] = Field(default=[]) ``` **That's it!** The template is automatically discovered and available at: ``` ?template_type=purchase_order ``` ## Template Naming Convention File must follow this pattern: - **Filename:** `{template_name}_template.py` - **Class name:** PascalCase version of template_name (e.g., `PurchaseOrder`) - **Must inherit from:** `pydantic.BaseModel` Examples: - `payment_advice_template.py` → class `PaymentAdvice` - `invoice_template.py` → class `Invoice` - `purchase_order_template.py` → class `PurchaseOrder` ## Auto-Detection Keywords Edit `template_router.py` to add detection rules: ```python detection_rules = { "payment_advice": ["payment advice", "payment document"], "invoice": ["tax invoice", "bill no", "invoice date"], "purchase_order": ["purchase order", "po number"], "your_custom_type": ["your", "keywords", "here"], } ``` ## Web Interface Access the Gradio UI at: `https://YOUR-SPACE.hf.space/gradio` - Upload documents - Select template or use auto-detect - View extracted JSON instantly ## Supported Document Formats - PDF documents - Images (PNG, JPG, JPEG) - DOCX (requires additional configuration) ## Hardware Requirements ### Free Tier (CPU basic) - ✅ Standard invoices (1-5 pages) - ✅ Payment advices - ✅ Simple documents - ⚠️ Large PDFs may timeout (30s limit) ### Upgraded Tier (Recommended for production) - CPU basic upgrade: 4 vCPU, 16 GB RAM - Faster processing - Handle larger documents ## Troubleshooting ### Template Not Found Error ```json {"detail": "Template 'xyz' not found. Available templates: payment_advice, invoice"} ``` **Solution:** Check filename matches `{name}_template.py` pattern ### Timeout Errors **Solution:** Upgrade to larger hardware tier or reduce document size ### Import Errors **Solution:** Ensure all dependencies in `requirements.txt` and rebuild Space ## API Rate Limits Hugging Face Spaces free tier: - No official rate limit - Fair usage policy applies - For production: Consider Hugging Face Pro ($9/month) ## Local Development ```bash # Clone repository git clone https://huggingface.co/spaces/YOUR-USERNAME/docling-api cd docling-api # Install dependencies pip install -r requirements.txt # Run locally uvicorn app:app --host 0.0.0.0 --port 7860 --reload ``` Access at: `http://localhost:7860` ## Environment Variables Optional configurations (add in Space settings): ```bash # Logging level LOG_LEVEL=INFO # Max file size (MB) MAX_FILE_SIZE=50 ``` ## Security Notes - ⚠️ Free tier Spaces are public by default - 🔒 For sensitive documents, use private Spaces (Hugging Face Pro) - 🔐 Consider adding API key authentication for production ## Contributing Add new templates or improve detection logic: 1. Fork the Space 2. Add your template in `templates/` 3. Update detection rules in `template_router.py` 4. Test with sample documents 5. Submit pull request ## License Apache 2.0 ## Support - Documentation: [Docling GitHub](https://github.com/docling-project/docling) - Issues: Create issue in your Space repository - Community: Hugging Face Discord ## Credits Built with: - [Docling](https://github.com/docling-project/docling) - Document processing - [FastAPI](https://fastapi.tiangolo.com/) - Web framework - [Gradio](https://gradio.app/) - Web interface - [Pydantic](https://docs.pydantic.dev/) - Data validation --- **Made with ❤️ for the document automation community**