from __future__ import annotations import gradio as gr from drawing_intelligence.config import MODEL_CHOICES, SETTINGS from drawing_intelligence.exporting import TABLE_COLUMNS from drawing_intelligence.ui import ( APP_CSS, export_excel_ui, export_json_ui, extract_ui, load_sample_ui, page_ui, preview_file_ui, select_row_ui, summary_ui, ) def build_app() -> gr.Blocks: theme = gr.themes.Base( primary_hue=gr.themes.colors.red, neutral_hue=gr.themes.colors.slate, font=["Inter", "Segoe UI", "Arial", "sans-serif"], font_mono=["Roboto Mono", "Consolas", "monospace"], ).set( body_background_fill="#ffffff", body_text_color="#171d26", button_primary_background_fill="#b5121b", button_primary_background_fill_hover="#8f0d14", button_primary_border_color="#b5121b", block_border_color="#dce1e8", block_shadow="none", input_border_color="#d8dde5", ) with gr.Blocks( title="Drawing Intelligence", theme=theme, css=APP_CSS, fill_width=True, ) as app: session = gr.State(value=None) gr.HTML( """

Drawing Intelligence

Ballooned drawing parameter extraction

""" ) with gr.Group(elem_classes=["control-strip"]): with gr.Row(equal_height=True): drawing = gr.File( label="Upload ballooned drawing", file_types=[".pdf", ".png", ".jpg", ".jpeg", ".tif", ".tiff"], type="filepath", scale=5, ) model = gr.Dropdown( choices=list(MODEL_CHOICES), value=list(MODEL_CHOICES)[0], label="Hugging Face model", interactive=True, scale=3, ) dpi = gr.Dropdown( choices=[150, 200, 300, 450, 600], value=SETTINGS.default_dpi, label="Render DPI", scale=2, ) extract = gr.Button( "Extract parameters", variant="primary", elem_classes=["primary-action"], scale=3, ) with gr.Row(): sample = gr.Button("Load demonstration drawing", size="sm") readiness = gr.Markdown( "Upload a ballooned PDF or image to begin.", show_label=False, container=False, ) with gr.Accordion("Advanced processing settings", open=False): with gr.Row(): max_pages = gr.Slider( 1, SETTINGS.max_pages, value=min(3, SETTINGS.max_pages), step=1, label="Maximum pages", ) tile_size = gr.Slider( 1024, 2560, value=1800, step=128, label="AI tile size (pixels)", ) overlap = gr.Slider( 0, 35, value=18, step=1, label="Tile overlap (%)", ) with gr.Group(elem_classes=["workspace-shell"]): with gr.Row(equal_height=True): with gr.Column(scale=11, min_width=480, elem_classes=["workspace-column"]): with gr.Row(): page = gr.Slider( 1, 1, value=1, step=1, label="Page", visible=False ) viewer = gr.Image( label="Drawing review", show_label=False, type="pil", height=685, elem_id="drawing-viewer", ) with gr.Column(scale=9, min_width=460, elem_classes=["workspace-column"]): gr.HTML('
Characteristics
') characteristics = gr.Dataframe( headers=TABLE_COLUMNS, value=[], interactive=True, wrap=True, show_label=False, row_count=(10, "dynamic"), col_count=(len(TABLE_COLUMNS), "fixed"), pinned_columns=2, column_widths=[ 78, 62, 72, 120, 130, 240, 90, 95, 95, 95, 95, 78, 65, 115, 115, 115, 90, 105, 95, 160, 140, 220, 95, 115, 260, 120, ], elem_id="characteristics-table", ) gr.HTML( """
AI output is never approved automatically. Confirm every requirement against the controlled drawing before changing Status to Verified.
""" ) with gr.Tabs(): with gr.Tab("Drawing information"): metadata = gr.Markdown("No extraction has been run.") with gr.Tab("General notes"): notes = gr.Markdown("No extraction has been run.") with gr.Tab("Raw model output"): raw_output = gr.Code(language="json", value="[]", lines=18) with gr.Group(elem_classes=["bottom-strip"]): with gr.Row(equal_height=True): summary = gr.HTML( '
0 extracted' 'ยท' '0 need review
' ) excel_button = gr.Button("Export Excel", variant="secondary") json_button = gr.Button("Export JSON", variant="secondary") with gr.Row(): excel_file = gr.File(label="Excel export", interactive=False) json_file = gr.File(label="JSON export", interactive=False) sample.click( load_sample_ui, outputs=[drawing, viewer, readiness], api_name=False, ) drawing.change( preview_file_ui, inputs=[drawing], outputs=[viewer, readiness], api_name=False, ) extract.click( extract_ui, inputs=[drawing, model, dpi, max_pages, tile_size, overlap], outputs=[ viewer, characteristics, summary, metadata, notes, raw_output, session, page, ], api_name="extract", ) page.change( page_ui, inputs=[page, session], outputs=[viewer], api_name=False, ) characteristics.select( select_row_ui, inputs=[session, characteristics, page], outputs=[viewer, page], api_name=False, ) characteristics.change( summary_ui, inputs=[characteristics, session], outputs=[summary], api_name=False, ) excel_button.click( export_excel_ui, inputs=[characteristics, session], outputs=[excel_file], api_name="export_excel", ) json_button.click( export_json_ui, inputs=[characteristics, session], outputs=[json_file], api_name="export_json", ) return app.queue(default_concurrency_limit=1, max_size=12) demo = build_app() if __name__ == "__main__": demo.launch(show_api=False)