rehan953 commited on
Commit
43fa232
Β·
verified Β·
1 Parent(s): 6edb1f6

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +73 -51
app.py CHANGED
@@ -3,7 +3,6 @@ import yaml
3
  import re
4
  import os
5
 
6
- # Paths from installed glmocr package
7
  import glmocr
8
  GLMOCR_BASE = os.path.dirname(glmocr.__file__)
9
  config_path = os.path.join(GLMOCR_BASE, "config.yaml")
@@ -13,8 +12,8 @@ formatter_path = os.path.join(GLMOCR_BASE, "postprocess", "result_formatter.py")
13
  with open(config_path, "r") as f:
14
  config = yaml.safe_load(f)
15
 
16
- config["pipeline"]["maas"]["enabled"] = True
17
- config["pipeline"]["maas"]["api_key"] = "4570c28bdea5493c9efae9dae68edc66.sGbA9DLlcX1GlvqV"
18
 
19
  config["pipeline"]["result_formatter"]["abandon"] = [
20
  "number", "footnote", "aside_text",
@@ -50,9 +49,8 @@ print("βœ… result_formatter.py fixed")
50
  ABANDON = set(config["pipeline"]["result_formatter"]["abandon"])
51
 
52
  # ── STEP 3: Extract header/footer from PDF text layer ─────────
53
- # The MaaS API only returns 'text' and 'table' labels β€” it never
54
- # labels anything as 'header' or 'footer'. So we extract those
55
- # directly from the PDF text layer using PyMuPDF instead.
56
  def extract_pdf_headers(path):
57
  import fitz
58
  page_headers = []
@@ -60,9 +58,7 @@ def extract_pdf_headers(path):
60
  for page in doc:
61
  page_rect = page.rect
62
  page_height = page_rect.height
63
- # Top 12% = header area
64
  header_rect = fitz.Rect(0, 0, page_rect.width, page_height * 0.12)
65
- # Bottom 12% = footer area
66
  footer_rect = fitz.Rect(0, page_height * 0.88, page_rect.width, page_height)
67
  header_text = page.get_text(clip=header_rect).strip()
68
  footer_text = page.get_text(clip=footer_rect).strip()
@@ -70,7 +66,29 @@ def extract_pdf_headers(path):
70
  doc.close()
71
  return page_headers
72
 
73
- # ── STEP 4: Main OCR function ─────────────────────────────────
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  def run_ocr(uploaded_file):
75
  if uploaded_file is None:
76
  return "Please upload a file.", "No regions detected."
@@ -80,7 +98,6 @@ def run_ocr(uploaded_file):
80
 
81
  path = uploaded_file.name if hasattr(uploaded_file, "name") else str(uploaded_file)
82
 
83
- # Convert PDF to images + extract headers from text layer
84
  if path.lower().endswith(".pdf"):
85
  import fitz
86
  pdf_headers = extract_pdf_headers(path)
@@ -92,30 +109,26 @@ def run_ocr(uploaded_file):
92
  pix.save(img_path)
93
  page_images.append(img_path)
94
  doc.close()
95
- result = parse(page_images)
 
 
 
96
  else:
97
  pdf_headers = []
98
- result = parse(path)
99
-
100
- # Parse result
101
- pages_data = result.json_result if hasattr(result, "json_result") else []
102
- if not isinstance(pages_data, list):
103
- pages_data = [pages_data] if pages_data else []
104
 
105
  total_headers = 0
106
  total_footers = 0
107
  all_markdown = []
108
  all_summary = []
109
 
110
- for page_num, page_regions in enumerate(pages_data):
111
- if not isinstance(page_regions, list):
112
- page_regions = [page_regions] if page_regions else []
113
-
114
  page_md = []
115
- page_summary = [f"── PAGE {page_num + 1} of {len(pages_data)} ──"]
116
 
117
  # Inject header/footer from PDF text layer
118
- # (API never returns these as separate labeled regions)
119
  if pdf_headers and page_num < len(pdf_headers):
120
  hdr = pdf_headers[page_num]["header"]
121
  ftr = pdf_headers[page_num]["footer"]
@@ -128,38 +141,47 @@ def run_ocr(uploaded_file):
128
  page_md.append("<!-- FOOTER -->\n" + ftr)
129
  page_summary.append("🟒 FOOTER: " + ftr[:100])
130
 
131
- # Process API regions (text, table, etc.)
132
- for region in page_regions:
133
- if not isinstance(region, dict):
134
- continue
135
- label = region.get("label", "text")
136
- content = str(region.get("content", ""))
137
-
138
- if label in ABANDON:
139
- continue
140
-
141
- # API returns 'header'/'footer' labels in some docs
142
- # Keep them too in case the API does label them
143
- if label == "header":
144
- total_headers += 1
145
- page_summary.append("πŸ”΅ HEADER (API): " + content[:100])
146
- page_md.append("<!-- HEADER -->\n" + content)
147
- elif label == "footer":
148
- total_footers += 1
149
- page_summary.append("🟒 FOOTER (API): " + content[:100])
150
- page_md.append("<!-- FOOTER -->\n" + content)
151
- else:
152
- page_summary.append("[" + label + "]: " + content[:100])
153
- page_md.append(content)
 
 
 
 
 
 
 
 
 
154
 
155
  all_markdown.append("\n\n".join(page_md))
156
  all_summary.extend(page_summary)
157
  all_summary.append("")
158
 
159
  summary = (
160
- "Total pages : " + str(len(pages_data)) + "\n"
161
- "Headers found : " + str(total_headers) + "\n"
162
- "Footers found : " + str(total_footers) + "\n"
163
  + "─" * 40 + "\n"
164
  + "\n".join(all_summary)
165
  )
@@ -171,7 +193,7 @@ def run_ocr(uploaded_file):
171
  import traceback
172
  return "Error: " + str(e) + "\n\n" + traceback.format_exc(), "Failed."
173
 
174
- # ── STEP 5: Gradio UI ─────────────────────────────────────────
175
  with gr.Blocks(title="GLM-OCR β€” MaaS (Header & Footer)") as demo:
176
  gr.Markdown("""
177
  # πŸ” GLM-OCR β€” Zhipu MaaS
@@ -196,4 +218,4 @@ with gr.Blocks(title="GLM-OCR β€” MaaS (Header & Footer)") as demo:
196
  run_btn.click(fn=run_ocr, inputs=file_input,
197
  outputs=[markdown_out, regions_out])
198
 
199
- demo.launch()
 
3
  import re
4
  import os
5
 
 
6
  import glmocr
7
  GLMOCR_BASE = os.path.dirname(glmocr.__file__)
8
  config_path = os.path.join(GLMOCR_BASE, "config.yaml")
 
12
  with open(config_path, "r") as f:
13
  config = yaml.safe_load(f)
14
 
15
+ config["pipeline"]["maas"]["enabled"] = True
16
+ config["pipeline"]["maas"]["api_key"] = "4570c28bdea5493c9efae9dae68edc66.sGbA9DLlcX1GlvqV"
17
 
18
  config["pipeline"]["result_formatter"]["abandon"] = [
19
  "number", "footnote", "aside_text",
 
49
  ABANDON = set(config["pipeline"]["result_formatter"]["abandon"])
50
 
51
  # ── STEP 3: Extract header/footer from PDF text layer ─────────
52
+ # The MaaS API only returns 'text' and 'table' labels.
53
+ # Headers and footers are extracted directly from the PDF using PyMuPDF.
 
54
  def extract_pdf_headers(path):
55
  import fitz
56
  page_headers = []
 
58
  for page in doc:
59
  page_rect = page.rect
60
  page_height = page_rect.height
 
61
  header_rect = fitz.Rect(0, 0, page_rect.width, page_height * 0.12)
 
62
  footer_rect = fitz.Rect(0, page_height * 0.88, page_rect.width, page_height)
63
  header_text = page.get_text(clip=header_rect).strip()
64
  footer_text = page.get_text(clip=footer_rect).strip()
 
66
  doc.close()
67
  return page_headers
68
 
69
+ # ── STEP 4: Parse one page result into regions list ───────────
70
+ # result from parse() is a LIST of PipelineResult objects (one per page)
71
+ # Each PipelineResult has:
72
+ # .json_result β†’ list of region dicts with 'label' and 'content'
73
+ # .markdown_result β†’ plain markdown string
74
+ def get_page_regions(page_result):
75
+ # Try json_result first (structured regions)
76
+ if hasattr(page_result, "json_result"):
77
+ jr = page_result.json_result
78
+ if isinstance(jr, list) and len(jr) > 0:
79
+ # json_result is a list of lists (one list per page image)
80
+ # since we pass one image per call, take index 0
81
+ regions = jr[0] if isinstance(jr[0], list) else jr
82
+ if isinstance(regions, list):
83
+ return regions, "json"
84
+ # Fallback to markdown_result
85
+ if hasattr(page_result, "markdown_result"):
86
+ md = page_result.markdown_result
87
+ if md and isinstance(md, str) and md.strip():
88
+ return md.strip(), "raw"
89
+ return [], "empty"
90
+
91
+ # ── STEP 5: Main OCR function ─────────────────────────────────
92
  def run_ocr(uploaded_file):
93
  if uploaded_file is None:
94
  return "Please upload a file.", "No regions detected."
 
98
 
99
  path = uploaded_file.name if hasattr(uploaded_file, "name") else str(uploaded_file)
100
 
 
101
  if path.lower().endswith(".pdf"):
102
  import fitz
103
  pdf_headers = extract_pdf_headers(path)
 
109
  pix.save(img_path)
110
  page_images.append(img_path)
111
  doc.close()
112
+ # parse() returns a LIST β€” one PipelineResult per page
113
+ results = parse(page_images)
114
+ if not isinstance(results, list):
115
+ results = [results]
116
  else:
117
  pdf_headers = []
118
+ results = parse(path)
119
+ if not isinstance(results, list):
120
+ results = [results]
 
 
 
121
 
122
  total_headers = 0
123
  total_footers = 0
124
  all_markdown = []
125
  all_summary = []
126
 
127
+ for page_num, page_result in enumerate(results):
 
 
 
128
  page_md = []
129
+ page_summary = [f"── PAGE {page_num + 1} of {len(results)} ──"]
130
 
131
  # Inject header/footer from PDF text layer
 
132
  if pdf_headers and page_num < len(pdf_headers):
133
  hdr = pdf_headers[page_num]["header"]
134
  ftr = pdf_headers[page_num]["footer"]
 
141
  page_md.append("<!-- FOOTER -->\n" + ftr)
142
  page_summary.append("🟒 FOOTER: " + ftr[:100])
143
 
144
+ # Get regions from this page result
145
+ data, dtype = get_page_regions(page_result)
146
+
147
+ if dtype == "json":
148
+ for region in data:
149
+ if not isinstance(region, dict):
150
+ continue
151
+ label = region.get("label", "text")
152
+ content = str(region.get("content", ""))
153
+
154
+ if label in ABANDON:
155
+ continue
156
+
157
+ if label == "header":
158
+ total_headers += 1
159
+ page_summary.append("πŸ”΅ HEADER (API): " + content[:100])
160
+ page_md.append("<!-- HEADER -->\n" + content)
161
+ elif label == "footer":
162
+ total_footers += 1
163
+ page_summary.append("🟒 FOOTER (API): " + content[:100])
164
+ page_md.append("<!-- FOOTER -->\n" + content)
165
+ else:
166
+ page_summary.append("[" + label + "]: " + content[:100])
167
+ page_md.append(content)
168
+
169
+ elif dtype == "raw":
170
+ page_md.append(data)
171
+ page_summary.append("[markdown output]")
172
+ page_summary.append("Content length: " + str(len(data)) + " chars")
173
+
174
+ else:
175
+ page_summary.append("[empty page]")
176
 
177
  all_markdown.append("\n\n".join(page_md))
178
  all_summary.extend(page_summary)
179
  all_summary.append("")
180
 
181
  summary = (
182
+ "Total pages : " + str(len(results)) + "\n"
183
+ + "Headers found : " + str(total_headers) + "\n"
184
+ + "Footers found : " + str(total_footers) + "\n"
185
  + "─" * 40 + "\n"
186
  + "\n".join(all_summary)
187
  )
 
193
  import traceback
194
  return "Error: " + str(e) + "\n\n" + traceback.format_exc(), "Failed."
195
 
196
+ # ── STEP 6: Gradio UI ─────────────────────────────────────────
197
  with gr.Blocks(title="GLM-OCR β€” MaaS (Header & Footer)") as demo:
198
  gr.Markdown("""
199
  # πŸ” GLM-OCR β€” Zhipu MaaS
 
218
  run_btn.click(fn=run_ocr, inputs=file_input,
219
  outputs=[markdown_out, regions_out])
220
 
221
+ demo.launch()