electblake commited on
Commit
60d4ffd
·
1 Parent(s): b443080

refactor(gradio): focus app on structured extraction

Browse files

Remove the content task and Markdown outputs so the Space exposes one structured extraction pipeline with one JSON result. Update examples and documentation to match the simplified API.

Files changed (2) hide show
  1. README.md +3 -3
  2. app/gradio.py +14 -36
README.md CHANGED
@@ -10,14 +10,14 @@ app_file: app.py
10
  pinned: false
11
  models:
12
  - numind/NuExtract3
13
- short_description: Extract Markdown or JSON from documents with NuExtract3.
14
  ---
15
 
16
  # NuMark
17
 
18
- NuMark is a Gradio app for extracting Markdown or structured JSON from document images with [NuExtract3](https://huggingface.co/numind/NuExtract3).
19
 
20
- Upload a receipt, invoice, or other document image, optionally add accompanying text, and choose either content extraction or schema-guided structured extraction.
21
 
22
  The inference function uses Hugging Face ZeroGPU dynamic GPU allocation. Select ZeroGPU in the Space hardware settings before launching the app.
23
 
 
10
  pinned: false
11
  models:
12
  - numind/NuExtract3
13
+ short_description: Extract structured JSON from documents with NuExtract3.
14
  ---
15
 
16
  # NuMark
17
 
18
+ NuMark is a Gradio app for extracting structured JSON from document images with [NuExtract3](https://huggingface.co/numind/NuExtract3).
19
 
20
+ Upload a receipt, invoice, or other document image, optionally add accompanying text, and choose a JSON template for schema-guided structured extraction.
21
 
22
  The inference function uses Hugging Face ZeroGPU dynamic GPU allocation. Select ZeroGPU in the Space hardware settings before launching the app.
23
 
app/gradio.py CHANGED
@@ -262,7 +262,7 @@ def run_nuextract(messages, **chat_template_kwargs):
262
  )[0].strip()
263
 
264
 
265
- def extract(image, text, mode, template, enable_thinking):
266
  result = run_nuextract(
267
  [
268
  {
@@ -273,21 +273,18 @@ def extract(image, text, mode, template, enable_thinking):
273
  ],
274
  }
275
  ],
276
- mode=mode,
277
  template=template,
278
  enable_thinking=enable_thinking,
279
  )
280
 
281
- if mode == "content":
282
- return result, result, gr.skip()
283
-
284
- return gr.skip(), gr.skip(), json.loads(result)
285
 
286
 
287
  with gr.Blocks(title="NuMarkApp") as demo:
288
  gr.Markdown(
289
  "# NuMarkApp\n"
290
- "Extract Markdown or structured JSON from an image and optional text using "
291
  "[numind/NuExtract3](https://huggingface.co/numind/NuExtract3)."
292
  )
293
  with gr.Row():
@@ -298,11 +295,6 @@ with gr.Blocks(title="NuMarkApp") as demo:
298
  placeholder="Add text to process alongside the image",
299
  lines=3,
300
  )
301
- mode = gr.Radio(
302
- ["content", "structured"],
303
- value="content",
304
- label="Task",
305
- )
306
  enable_thinking = gr.Checkbox(label="Enable thinking")
307
  template_preset = gr.Dropdown(
308
  choices=list(structured_json_templates),
@@ -317,22 +309,13 @@ with gr.Blocks(title="NuMarkApp") as demo:
317
  lines=18,
318
  info="Used for structured extraction. Edit the example to match your document.",
319
  )
320
- run = gr.Button("Extract", variant="primary")
321
- with gr.Column(), gr.Tabs():
322
- with gr.Tab("Content"):
323
- markdown_text = gr.Textbox(
324
- label="Markdown source",
325
- lines=28,
326
- buttons=["copy"],
327
- )
328
- with gr.Accordion("Markdown preview (optional)", open=False):
329
- markdown_preview = gr.Markdown()
330
- with gr.Tab("Structured"):
331
- structured_output = gr.JSON(
332
- label="Structured JSON",
333
- open=True,
334
- show_indices=True,
335
- )
336
 
337
  gr.Examples(
338
  examples=[
@@ -345,7 +328,6 @@ with gr.Blocks(title="NuMarkApp") as demo:
345
  / "receipt-ocr-original.webp"
346
  ),
347
  "",
348
- "structured",
349
  False,
350
  ],
351
  [
@@ -357,7 +339,6 @@ with gr.Blocks(title="NuMarkApp") as demo:
357
  / "invoice-with-items.png"
358
  ),
359
  "",
360
- "structured",
361
  False,
362
  ],
363
  [
@@ -369,7 +350,6 @@ with gr.Blocks(title="NuMarkApp") as demo:
369
  / "BankStatementChequing.png"
370
  ),
371
  "",
372
- "structured",
373
  False,
374
  ],
375
  [
@@ -381,7 +361,6 @@ with gr.Blocks(title="NuMarkApp") as demo:
381
  / "bank statement blog image.webp"
382
  ),
383
  "",
384
- "structured",
385
  False,
386
  ],
387
  *[
@@ -389,7 +368,6 @@ with gr.Blocks(title="NuMarkApp") as demo:
389
  default_structured_json_template,
390
  str(path),
391
  "",
392
- "content",
393
  False,
394
  ]
395
  for path in sorted(
@@ -402,7 +380,7 @@ with gr.Blocks(title="NuMarkApp") as demo:
402
  )
403
  ],
404
  ],
405
- inputs=[template_preset, image, text, mode, enable_thinking],
406
  )
407
 
408
  template_preset.change(
@@ -413,8 +391,8 @@ with gr.Blocks(title="NuMarkApp") as demo:
413
 
414
  run.click(
415
  extract,
416
- inputs=[image, text, mode, template, enable_thinking],
417
- outputs=[markdown_preview, markdown_text, structured_output],
418
  api_name="extract",
419
  )
420
 
 
262
  )[0].strip()
263
 
264
 
265
+ def extract(image, text, template, enable_thinking):
266
  result = run_nuextract(
267
  [
268
  {
 
273
  ],
274
  }
275
  ],
276
+ mode="structured",
277
  template=template,
278
  enable_thinking=enable_thinking,
279
  )
280
 
281
+ return json.loads(result)
 
 
 
282
 
283
 
284
  with gr.Blocks(title="NuMarkApp") as demo:
285
  gr.Markdown(
286
  "# NuMarkApp\n"
287
+ "Extract structured JSON from an image and optional text using "
288
  "[numind/NuExtract3](https://huggingface.co/numind/NuExtract3)."
289
  )
290
  with gr.Row():
 
295
  placeholder="Add text to process alongside the image",
296
  lines=3,
297
  )
 
 
 
 
 
298
  enable_thinking = gr.Checkbox(label="Enable thinking")
299
  template_preset = gr.Dropdown(
300
  choices=list(structured_json_templates),
 
309
  lines=18,
310
  info="Used for structured extraction. Edit the example to match your document.",
311
  )
312
+ run = gr.Button("Extract structured JSON", variant="primary")
313
+ with gr.Column():
314
+ structured_output = gr.JSON(
315
+ label="Structured JSON",
316
+ open=True,
317
+ show_indices=True,
318
+ )
 
 
 
 
 
 
 
 
 
319
 
320
  gr.Examples(
321
  examples=[
 
328
  / "receipt-ocr-original.webp"
329
  ),
330
  "",
 
331
  False,
332
  ],
333
  [
 
339
  / "invoice-with-items.png"
340
  ),
341
  "",
 
342
  False,
343
  ],
344
  [
 
350
  / "BankStatementChequing.png"
351
  ),
352
  "",
 
353
  False,
354
  ],
355
  [
 
361
  / "bank statement blog image.webp"
362
  ),
363
  "",
 
364
  False,
365
  ],
366
  *[
 
368
  default_structured_json_template,
369
  str(path),
370
  "",
 
371
  False,
372
  ]
373
  for path in sorted(
 
380
  )
381
  ],
382
  ],
383
+ inputs=[template_preset, image, text, enable_thinking],
384
  )
385
 
386
  template_preset.change(
 
391
 
392
  run.click(
393
  extract,
394
+ inputs=[image, text, template, enable_thinking],
395
+ outputs=structured_output,
396
  api_name="extract",
397
  )
398