electblake's picture
Rename-image-data-extractor-skill
d96e2e1 verified
Raw
History Blame Contribute Delete
5.75 kB
import zipfile
from pathlib import Path
import gradio as gr
from model import extract, generate_template
templates_directory = Path(__file__).parent / "data" / "templates"
structured_json_templates = {
"Basic receipt": (templates_directory / "basic-receipt.json").read_text(
encoding="utf-8"
),
"Invoice with line items": (
templates_directory / "invoice-with-line-items.json"
).read_text(encoding="utf-8"),
"Basic bank statement": (
templates_directory / "basic-bank-statement.json"
).read_text(encoding="utf-8"),
"Advanced bank statement": (
templates_directory / "advanced-bank-statement.json"
).read_text(encoding="utf-8"),
"Model task catalog": (
templates_directory / "model-task-catalog.json"
).read_text(encoding="utf-8"),
"Todo list": (templates_directory / "todo-list.json").read_text(
encoding="utf-8"
),
}
default_structured_json_template = "Invoice with line items"
def download_agentskill(include_all_skills):
skill_folders = (
sorted(path for path in Path(".agents/skills").iterdir() if path.is_dir())
if include_all_skills
else [Path(".agents/skills/image-data-extractor")]
)
for skill_folder in skill_folders:
with zipfile.ZipFile(
f"{skill_folder.name}.zip", "w", compression=zipfile.ZIP_DEFLATED
) as archive:
for path in skill_folder.rglob("*"):
archive.write(path, path.relative_to(".agents/skills"))
return [f"{skill_folder.name}.zip" for skill_folder in skill_folders]
with gr.Blocks(title="Image Data Extractor") as demo:
gr.Markdown(
"# Image Data Extractor\n"
"Extract structured JSON from an image and optional text using "
"[numind/NuExtract3](https://huggingface.co/numind/NuExtract3)."
)
with gr.Row():
with gr.Column():
image = gr.Image(label="Document image", type="pil", height=430)
text = gr.Textbox(
label="Document text (optional)",
placeholder="Add text to process alongside the image",
lines=3,
)
enable_thinking = gr.Checkbox(label="Enable thinking")
template_preset = gr.Dropdown(
choices=list(structured_json_templates),
value=default_structured_json_template,
label="JSON template preset",
info="Choose a starting structure, then edit it below.",
)
generate_template_button = gr.Button("Generate template from Image")
with gr.Accordion(
"Structured JSON template", open=False
) as template_accordion:
template = gr.Textbox(
label="Structured JSON template",
value=structured_json_templates[default_structured_json_template],
lines=18,
info="Used for structured extraction. Edit the example to match your document.",
)
run = gr.Button("Extract Image Data", variant="primary")
with gr.Column():
structured_output = gr.JSON(
label="Structured JSON",
open=True,
show_indices=True,
)
gr.Markdown(
"## Install the agent skill\n"
"Download the ZIP, extract it, and place its skill folders in your "
"project's `.agents/skills/` directory. Agents should read the "
"`SKILL.md` and use it whenever a task requires structured extraction "
"from an image. Keep **Include All Skills** checked to download every "
"skill as its own ZIP file."
)
include_all_skills = gr.Checkbox(
label="Include All Skills",
value=True,
)
download_agentskill_button = gr.Button("Download agent skill")
download_agentskill_file = gr.File(
label="Agent skill ZIPs",
file_count="multiple",
)
gr.Examples(
examples=[
[
preset,
str(Path(__file__).parent / "data" / "samples" / filename),
"",
False,
]
for preset, filename in [
("Basic receipt", "receipt-ocr-original.webp"),
("Invoice with line items", "invoice-with-items.png"),
("Advanced bank statement", "BankStatementChequing.png"),
("Basic bank statement", "bank statement blog image.webp"),
("Model task catalog", "tags.png"),
("Todo list", "task-list.png"),
]
],
inputs=[template_preset, image, text, enable_thinking],
)
template_preset.change(
structured_json_templates.__getitem__,
inputs=template_preset,
outputs=template,
api_name="select_structured_json_template",
)
download_agentskill_button.click(
download_agentskill,
inputs=include_all_skills,
outputs=download_agentskill_file,
api_name="download_agentskill",
)
generate_template_button.click(
lambda: gr.Accordion(open=True),
outputs=template_accordion,
api_visibility="private",
show_progress="hidden",
).then(
generate_template,
inputs=image,
outputs=template,
api_name="generate_template",
)
run.click(
extract,
inputs=[image, text, template, enable_thinking],
outputs=structured_output,
api_name="extract",
)
if __name__ == "__main__":
demo.launch()