""" EaseMed Universal Document Parser - Gradio entrypoint. Used for a Gradio-SDK Hugging Face Space (no Docker access required). See main.py for the FastAPI/Docker entrypoint. Every Gradio app automatically exposes a programmatic API for its functions (visible at /?view=api). The Next.js backend calls this via the @gradio/client package rather than a plain multipart POST, since Gradio's wire format differs from a simple REST endpoint. """ import os import gradio as gr try: import spaces SPACES_AVAILABLE = True except ImportError: SPACES_AVAILABLE = False import parser_core as core if SPACES_AVAILABLE: # This Space's hardware tier is ZeroGPU, which requires at least one # @spaces.GPU-decorated function to be detected at startup or the app # is killed with "No @spaces.GPU function detected during startup" - # even though this parser is pure CPU work and never actually needs a # GPU allocation. This function exists solely to satisfy that check # and is never called. @spaces.GPU def _zerogpu_startup_probe(): return True def parse_rfq(file_path: str): if not file_path: return { "title": "Error Parsing", "description": "No file provided", "sections": [], "line_items": [], "fields": [], "provider": "self-hosted", } with open(file_path, "rb") as f: content = f.read() filename = os.path.basename(file_path) try: return core.parse_document(content, filename) except core.UnsupportedFileType as e: return { "title": "Error Parsing", "description": str(e), "sections": [], "line_items": [], "fields": [], "provider": "self-hosted", } demo = gr.Interface( fn=parse_rfq, inputs=gr.File(label="Requirements Document (PDF/Image/Word/Excel)", type="filepath"), outputs=gr.JSON(label="Parsed RFQ Data"), title="EaseMed Universal Document Parser", description=( "Upload a procurement requisition document (PDF, image, .docx, " ".xlsx) to extract structured medicine line items " "(name, dosage, form, quantity, category)." ), api_name="parse_rfq", ) if __name__ == "__main__": # ssr_mode disabled: it spawns a Node.js SSR proxy in front of the # Python server, which exits immediately in this Space's Docker image # (no visible error, just an immediate "Stopping Node.js server..."). # Plain client-side rendering doesn't need Node at all. demo.launch(ssr_mode=False)