Spaces:
Running
Running
| """ | |
| app.py - Entry point for Hugging Face Spaces. | |
| On Hugging Face Spaces, Gradio runs as the primary app on port 7860. | |
| FastAPI runs as a background thread on port 8000 internally. | |
| The Gradio UI talks to FastAPI on localhost:8000 (same machine). | |
| This is the same architecture as local development — it works perfectly | |
| on HF Spaces because both processes run on the same container. | |
| """ | |
| import logging | |
| import os | |
| import sys | |
| import tempfile | |
| import threading | |
| import time | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s [%(levelname)s] %(name)s - %(message)s", | |
| handlers=[logging.StreamHandler(sys.stdout)], | |
| ) | |
| logger = logging.getLogger(__name__) | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| from config import config | |
| def validate_environment(): | |
| if not config.GROQ_API_KEY or config.GROQ_API_KEY in ("", "your_groq_api_key_here"): | |
| logger.warning("=" * 60) | |
| logger.warning("GROQ_API_KEY not set. Using extractive fallback LLM.") | |
| logger.warning("Add GROQ_API_KEY in Space Settings > Repository secrets.") | |
| logger.warning("=" * 60) | |
| def run_fastapi(): | |
| """Run FastAPI backend on port 8000 in a background thread.""" | |
| import uvicorn | |
| logger.info(f"Starting FastAPI on port {config.API_PORT} ...") | |
| uvicorn.run( | |
| "api:app", | |
| host="0.0.0.0", | |
| port=config.API_PORT, | |
| log_level="warning", | |
| reload=False, | |
| ) | |
| def wait_for_api(): | |
| """Wait until FastAPI is ready before launching Gradio.""" | |
| import requests as req | |
| url = f"http://127.0.0.1:{config.API_PORT}/health" | |
| for _ in range(60): | |
| try: | |
| if req.get(url, timeout=2).status_code == 200: | |
| logger.info("FastAPI is ready.") | |
| return True | |
| except Exception: | |
| pass | |
| time.sleep(1) | |
| logger.warning("FastAPI did not start in 60s. Gradio launching anyway.") | |
| return False | |
| if __name__ == "__main__": | |
| validate_environment() | |
| os.makedirs(config.CACHE_DIR, exist_ok=True) | |
| os.makedirs(config.REPORTS_DIR, exist_ok=True) | |
| logger.info("DocVision OCR - Hugging Face Spaces") | |
| logger.info(f" FastAPI -> http://localhost:{config.API_PORT}") | |
| logger.info(f" Gradio -> http://0.0.0.0:7860") | |
| # Start FastAPI in background thread | |
| api_thread = threading.Thread(target=run_fastapi, daemon=True, name="fastapi") | |
| api_thread.start() | |
| # Wait for FastAPI to be healthy | |
| wait_for_api() | |
| # Launch Gradio on port 7860 — this is the port HF Spaces exposes | |
| import gradio as gr | |
| from ui import CSS, create_interface | |
| demo = create_interface() | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_error=True, | |
| ssr_mode=False, | |
| theme=gr.themes.Soft(), | |
| css=CSS, | |
| ) |