""" DocuLens — Standalone FastAPI entry point for Hugging Face Spaces. Pure FastAPI server served by uvicorn on port 7860 (HF Spaces default). No Gradio dependency — just the REST API. """ import os import logging from fastapi import FastAPI from fastapi.responses import JSONResponse # --------------------------------------------------------------------------- # Structured logging — configure once, before anything else logs # --------------------------------------------------------------------------- LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO").upper() LOG_FORMAT = os.environ.get( "LOG_FORMAT", "%(asctime)s [%(levelname)s] %(name)s: %(message)s", ) logging.basicConfig( level=getattr(logging, LOG_LEVEL, logging.INFO), format=LOG_FORMAT, datefmt="%Y-%m-%d %H:%M:%S", ) # Quieten noisy third-party loggers for _noisy in ("httpx", "httpcore", "urllib3", "uvicorn.access"): logging.getLogger(_noisy).setLevel(logging.WARNING) logger = logging.getLogger(__name__) # --------------------------------------------------------------------------- # FastAPI application # --------------------------------------------------------------------------- app = FastAPI( title="DocuLens", description="AI-Powered Invoice & Document Extraction API", version="1.2.0", ) # --------------------------------------------------------------------------- # CORS — applied BEFORE startup (unlike the Gradio version, this works) # --------------------------------------------------------------------------- from api import add_cors_middleware add_cors_middleware(app) # --------------------------------------------------------------------------- # Mount all API routers # --------------------------------------------------------------------------- from api import api_router from api_runs import runs_router from api_prompts import prompts_router from api_chat import chat_router from api_webhooks import webhooks_router from api_export import export_router from api_batch import batch_router from api_tiers import tiers_router from api_golden import golden_router app.include_router(api_router) app.include_router(runs_router) app.include_router(prompts_router) app.include_router(chat_router) app.include_router(webhooks_router) app.include_router(export_router) app.include_router(batch_router) app.include_router(tiers_router) app.include_router(golden_router) # --------------------------------------------------------------------------- # Root route — useful for health probes and quick verification # --------------------------------------------------------------------------- @app.get("/") async def root(): return JSONResponse( { "service": "DocuLens", "version": "1.2.0", "status": "running", "docs": "/docs", "health": "/api/v1/health", } ) # --------------------------------------------------------------------------- # Entry point — HF Spaces uses port 7860 by default # --------------------------------------------------------------------------- if __name__ == "__main__": import uvicorn port = int(os.environ.get("PORT", "7860")) logger.info("Starting DocuLens on port %d", port) uvicorn.run( "main:app", host="0.0.0.0", port=port, log_level=LOG_LEVEL.lower(), )