breakpointsoftware/document-parser
0
1from __future__ import annotations2 3import os4 5# Avoid the Node.js SSR proxy in hosted environments where it can terminate unexpectedly.6os.environ["GRADIO_SSR_MODE"] = "false"7 8import gradio as gr9 10from document_orchestrator import orchestrate_all_active_tenants11from google_sheets_service import GoogleSheetsConfigError, append_row_to_google_sheet12 13try:14 import spaces # type: ignore[import-not-found]15except ImportError:16 spaces = None17 18custom_css = """19.cell-menu, .cell-menu-button {20 display: none !important;21}22"""23 24 25def gpu_decorator(fn):26 if spaces is None:27 return fn28 return spaces.GPU(fn)29 30@gpu_decorator31def run_orchestrator_endpoint(api_key: str) -> dict:32 """Multi-tenant orchestration endpoint - processes all active tenants and their rules."""33 expected_api_key = str(os.getenv("ORCHESTRATOR_API_KEY") or "").strip()34 provided_api_key = str(api_key or "").strip()35 36 if provided_api_key != expected_api_key:37 return {38 "ok": False,39 "error": "Unauthorized: invalid API key.",40 }41 42 model_name = os.getenv("OPENAI_MODEL", "gpt-4o")43 try:44 # Load all active tenants from Firebase45 return orchestrate_all_active_tenants(46 model=model_name,47 include_subfolders=True,48 send_to_sheet=True,49 )50 except Exception as exc:51 return {52 "ok": False,53 "error": str(exc),54 }55 56 57def build_app() -> gr.Blocks:58 with gr.Blocks(title="Procesador de Documentos") as demo:59 gr.Markdown("# Procesador de Comprobantes de Compra\nRevisa documentos Parsed/Modified y envia los seleccionados.")60 61 with gr.Accordion("Orquestador API - Multi Tenant", open=False):62 gr.Markdown("Endpoint publico para ejecutar escaneo + parseo + persistencia del orquestador en modo multi-tenant (carga todos los tenants activos de Firebase).")63 64 mt_orchestrator_api_key = gr.Textbox(65 label="API Key",66 type="password",67 value="",68 )69 mt_orchestrator_button = gr.Button("Ejecutar orquestador (Multi Tenant)", variant="primary")70 mt_orchestrator_output = gr.JSON(label="Resultado orquestacion")71 72 mt_orchestrator_button.click(73 run_orchestrator_endpoint,74 inputs=[mt_orchestrator_api_key],75 outputs=[mt_orchestrator_output],76 api_name="orchestrate_all_tenants",77 )78 79 return demo80 81 82demo = build_app()83 84 85if __name__ == "__main__":86 launch_kwargs = {"theme": gr.themes.Soft(), "show_error": True}87 88 # Spaces manages networking itself; local runs keep explicit host/port.89 if os.getenv("SPACE_ID"):90 try:91 demo.launch(css=custom_css, ssr_mode=False, **launch_kwargs)92 except TypeError:93 # Backward-compatible fallback if this Gradio build does not accept ssr_mode.94 demo.launch(css=custom_css, **launch_kwargs)95 else:96 try:97 demo.launch(css=custom_css, server_name="0.0.0.0", server_port=7860, ssr_mode=False, **launch_kwargs)98 except TypeError:99 demo.launch(css=custom_css, server_name="0.0.0.0", server_port=7860, **launch_kwargs)100 