ngohel58's picture
Upload 25 files
e425536 verified
Raw History Blame Contribute Delete
8.96 kB
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(
"""
<header class="app-header">
<h1>Drawing Intelligence</h1>
<p>Ballooned drawing parameter extraction</p>
</header>
"""
)
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('<div class="review-heading">Characteristics</div>')
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(
"""
<div class="assurance-note">
AI output is never approved automatically. Confirm every requirement
against the controlled drawing before changing Status to Verified.
</div>
"""
)
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(
'<div class="status-summary"><span class="status-count">0 extracted</span>'
'<span class="status-separator">·</span>'
'<span class="status-review">0 need review</span></div>'
)
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)