📤 Upload
Drag & drop or click to browse
PDF, PNG, JPG (max 50MB)Processing...
📊 Extraction Results
Upload a document to see extraction results
""" FastAPI Application Factory Creates and configures the FastAPI application. """ from __future__ import annotations import logging from contextlib import asynccontextmanager from pathlib import Path from typing import TYPE_CHECKING from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from fastapi.responses import HTMLResponse from .config import AppConfig, default_config from .routes import create_api_router from .services import InferenceService if TYPE_CHECKING: from collections.abc import AsyncGenerator logger = logging.getLogger(__name__) def create_app(config: AppConfig | None = None) -> FastAPI: """ Create and configure FastAPI application. Args: config: Application configuration. Uses default if not provided. Returns: Configured FastAPI application """ config = config or default_config # Create inference service inference_service = InferenceService( model_config=config.model, storage_config=config.storage, ) @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: """Application lifespan manager.""" logger.info("Starting Invoice Inference API...") # Initialize inference service on startup try: inference_service.initialize() logger.info("Inference service ready") except Exception as e: logger.error(f"Failed to initialize inference service: {e}") # Continue anyway - service will retry on first request yield logger.info("Shutting down Invoice Inference API...") # Create FastAPI app app = FastAPI( title="Invoice Field Extraction API", description=""" REST API for extracting fields from Swedish invoices. ## Features - YOLO-based field detection - OCR text extraction - Field normalization and validation - Visualization of detections ## Supported Fields - InvoiceNumber - InvoiceDate - InvoiceDueDate - OCR (reference number) - Bankgiro - Plusgiro - Amount - supplier_org_number (Swedish organization number) - customer_number - payment_line (machine-readable payment code) """, version="1.0.0", lifespan=lifespan, ) # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Mount static files for results config.storage.result_dir.mkdir(parents=True, exist_ok=True) app.mount( "/static/results", StaticFiles(directory=str(config.storage.result_dir)), name="results", ) # Include API routes api_router = create_api_router(inference_service, config.storage) app.include_router(api_router) # Root endpoint - serve HTML UI @app.get("/", response_class=HTMLResponse) async def root() -> str: """Serve the web UI.""" return get_html_ui() return app def get_html_ui() -> str: """Generate HTML UI for the web application.""" return """
Upload a Swedish invoice (PDF or image) to extract fields automatically
Drag & drop or click to browse
PDF, PNG, JPG (max 50MB)Processing...
Upload a document to see extraction results