Spaces:
Runtime error
Runtime error
Download app.py from sdudeja/agentic-extractor: direct link, hf CLI and curl.
- Browser
- Download file 4.7 kB
-
https://huggingface.co/spaces/sdudeja/agentic-extractor/resolve/main/app.py
- Command line
-
hf download hf://spaces/sdudeja/agentic-extractor/app.py
-
curl -L -o app.py https://huggingface.co/spaces/sdudeja/agentic-extractor/resolve/main/app.py
4.7 kB
| """ | |
| DocuLens β Hugging Face Spaces entry point (Gradio SDK wrapper). | |
| HF free-tier Spaces only support Gradio/Streamlit SDK, not Docker. | |
| This file creates a minimal Gradio UI and mounts all FastAPI API routes | |
| onto the same server, so the REST API works exactly as before. | |
| How it works: | |
| 1. Build a FastAPI app with all DocuLens API routes. | |
| 2. Create a minimal Gradio Blocks UI. | |
| 3. Mount Gradio onto the FastAPI app via gr.mount_gradio_app(). | |
| 4. Expose the combined ASGI app as `app` β HF Spaces detects and | |
| serves it automatically. We do NOT call uvicorn.run() or | |
| demo.launch() ourselves β HF handles that. | |
| The `demo` variable is renamed to `_gradio_ui` so HF's runner doesn't | |
| auto-launch it separately (which would cause a port conflict). | |
| """ | |
| import os | |
| import logging | |
| # --------------------------------------------------------------------------- | |
| # 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__) | |
| # --------------------------------------------------------------------------- | |
| # 1. Build the FastAPI app with all API routes (same as main.py) | |
| # --------------------------------------------------------------------------- | |
| from fastapi import FastAPI | |
| from fastapi.responses import JSONResponse | |
| fastapi_app = FastAPI( | |
| title="DocuLens", | |
| description="AI-Powered Invoice & Document Extraction API", | |
| version="1.2.0", | |
| ) | |
| # CORS | |
| from api import add_cors_middleware | |
| add_cors_middleware(fastapi_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 | |
| fastapi_app.include_router(api_router) | |
| fastapi_app.include_router(runs_router) | |
| fastapi_app.include_router(prompts_router) | |
| fastapi_app.include_router(chat_router) | |
| fastapi_app.include_router(webhooks_router) | |
| fastapi_app.include_router(export_router) | |
| fastapi_app.include_router(batch_router) | |
| fastapi_app.include_router(tiers_router) | |
| fastapi_app.include_router(golden_router) | |
| async def health(): | |
| return JSONResponse( | |
| { | |
| "service": "DocuLens", | |
| "version": "1.2.0", | |
| "status": "running", | |
| "docs": "/docs", | |
| } | |
| ) | |
| # --------------------------------------------------------------------------- | |
| # 2. Create a minimal Gradio UI (required by HF Spaces free-tier SDK) | |
| # --------------------------------------------------------------------------- | |
| import gradio as gr | |
| # Use _gradio_ui (not `demo`) to prevent HF from auto-launching it | |
| # separately β we mount it onto our FastAPI app below instead. | |
| with gr.Blocks(title="DocuLens", theme=gr.themes.Soft()) as _gradio_ui: | |
| gr.Markdown( | |
| """ | |
| # DocuLens API | |
| AI-Powered Invoice & Document Extraction. | |
| **API Documentation:** Navigate to [`/docs`](/docs) for the interactive | |
| Swagger UI, or [`/redoc`](/redoc) for ReDoc. | |
| **Health check:** [`/health`](/health) | |
| """ | |
| ) | |
| # --------------------------------------------------------------------------- | |
| # 3. Mount Gradio onto the FastAPI app so both coexist on the same server. | |
| # --------------------------------------------------------------------------- | |
| app = gr.mount_gradio_app(fastapi_app, _gradio_ui, path="/") | |
| # --------------------------------------------------------------------------- | |
| # 4. Start the server β no __main__ guard. | |
| # | |
| # HF's `gradio` CLI may import rather than exec the file, so | |
| # `if __name__ == "__main__"` can be skipped. We start uvicorn | |
| # unconditionally on port 7860 (HF's health-check port). | |
| # The Gradio Blocks is named `_gradio_ui` (not `demo`) to prevent | |
| # HF from auto-launching a second server that would conflict. | |
| # --------------------------------------------------------------------------- | |
| import uvicorn | |
| port = int(os.environ.get("PORT", "7860")) | |
| logger.info("Starting DocuLens on port %d", port) | |
| uvicorn.run(app, host="0.0.0.0", port=port) | |