KarthiEz commited on
Commit
218d1fa
·
verified ·
1 Parent(s): 17e6b8d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -16
app.py CHANGED
@@ -775,6 +775,52 @@ def invoice_text_to_json(
775
  final_json = _prune_empty_items(final_json)
776
  return final_json
777
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778
  # ---------- Gradio UI ----------
779
  TITLE = "docTR OCR — Text Extractor"
780
  DESC = (
@@ -785,28 +831,43 @@ DESC = (
785
  with gr.Blocks(theme="soft", title=TITLE) as demo:
786
  gr.Markdown(f"# {TITLE}\n{DESC}")
787
 
788
- with gr.Row():
789
- inp = gr.File(label="Upload image/PDF", file_types=[".png", ".jpg", ".jpeg", ".tif", ".tiff", ".pdf"])
790
- out = gr.Code(label="Extracted JSON", language="json")
791
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
792
 
793
- run_btn = gr.Button("Run OCR", variant="primary")
794
- run_btn.click(fn=run_ocr, inputs=inp, outputs=out)
795
 
796
- gr.Examples(
797
- examples=[
798
- # You can drop a couple of public sample URLs here if desired,
799
- # but Spaces won't auto-download without code. Leave empty by default.
800
- ],
801
- inputs=inp,
802
  outputs=out,
803
- cache_examples=False,
804
- label="(Optional) Examples"
805
  )
806
 
807
  gr.Markdown(
808
- "Tip: For multi-page PDFs, the output shows a **PAGE BREAK** separator between pages.\n"
809
- "For production pipelines, capture this output and route it to your parsing/LLM layer."
810
  )
811
 
812
  if __name__ == "__main__":
 
775
  final_json = _prune_empty_items(final_json)
776
  return final_json
777
 
778
+ from typing import Optional
779
+
780
+ # ----- replace old run_ocr with unified dispatcher -----
781
+ def run_pipeline(file: Optional[gr.File], raw_txt: Optional[str]) -> str:
782
+ """
783
+ Orchestrates two intake lanes:
784
+ 1) If raw_txt is provided (non-empty), skip OCR → directly map to schema.
785
+ 2) Else, run OCR on the uploaded file and map to schema.
786
+ """
787
+ raw_txt = (raw_txt or "").strip()
788
+
789
+ # Lane A: Raw text → JSON
790
+ if raw_txt:
791
+ try:
792
+ result_json = invoice_text_to_json(raw_txt)
793
+ return json.dumps(result_json, indent=2, ensure_ascii=False)
794
+ except Exception as e:
795
+ return f"Error while converting pasted text to JSON schema: {e}"
796
+
797
+ # Lane B: File → OCR → JSON
798
+ if not file:
799
+ return "No input received. Upload an image/PDF or paste raw text."
800
+
801
+ try:
802
+ name = (file.name or "").lower()
803
+
804
+ # Load as DocumentFile (handles PNG/JPG/PDF)
805
+ if name.endswith(".pdf"):
806
+ doc = DocumentFile.from_pdf(file=file.name)
807
+ else:
808
+ doc = DocumentFile.from_images([file.name])
809
+
810
+ # Inference
811
+ result = MODEL(doc)
812
+ exported = result.export()
813
+ text = _collect_text_from_export(exported)
814
+ if not text:
815
+ return "No text detected by OCR."
816
+
817
+ result_json = invoice_text_to_json(text)
818
+ return json.dumps(result_json, indent=2, ensure_ascii=False)
819
+
820
+ except Exception as e:
821
+ return f"OCR pipeline error: {e}"
822
+
823
+
824
  # ---------- Gradio UI ----------
825
  TITLE = "docTR OCR — Text Extractor"
826
  DESC = (
 
831
  with gr.Blocks(theme="soft", title=TITLE) as demo:
832
  gr.Markdown(f"# {TITLE}\n{DESC}")
833
 
834
+ with gr.TabbedInterface(
835
+ [
836
+ gr.TabItem("Upload File"),
837
+ gr.TabItem("Paste Raw Text")
838
+ ],
839
+ tab_names=["Upload File", "Paste Raw Text"]
840
+ ) as tabs:
841
+ with tabs.children[0]:
842
+ inp = gr.File(
843
+ label="Upload image/PDF",
844
+ file_types=[".png", ".jpg", ".jpeg", ".tif", ".tiff", .".pdf"]
845
+ )
846
+ # hidden paired textbox to keep a single click path
847
+ raw_txt_hidden = gr.Textbox(visible=False)
848
+
849
+ with tabs.children[1]:
850
+ # expose text lane; hide file lane counterpart
851
+ raw_txt = gr.Textbox(
852
+ label="Paste raw invoice text (we’ll map directly to JSON schema)",
853
+ lines=18,
854
+ placeholder="Paste the OCR’d/plain text of the invoice here…"
855
+ )
856
+ file_hidden = gr.File(visible=False)
857
 
858
+ out = gr.Code(label="Extracted JSON", language="json")
859
+ run_btn = gr.Button("Generate JSON", variant="primary")
860
 
861
+ # One button → unified function; we pass both lanes (visible/hidden)
862
+ run_btn.click(
863
+ fn=run_pipeline,
864
+ inputs=[inp, raw_txt],
 
 
865
  outputs=out,
 
 
866
  )
867
 
868
  gr.Markdown(
869
+ "ℹ️ **Usage:** Prefer the *Paste Raw Text* tab when you already have text and only need schema mapping. "
870
+ "If both file and text are provided, we’ll **prioritize the pasted text** by design to collapse cycle time."
871
  )
872
 
873
  if __name__ == "__main__":