MCPcopy Create free account
hub / github.com/ScienciaLAB/document-qa / process_structure

Method process_structure

document_qa/grobid_processors.py:159–226  ·  view source on GitHub ↗

Send a PDF to GROBID and return structured content. Args: input_path: Path to the PDF file. coordinates: If ``True``, include bounding-box coordinate strings in each passage (needed for PDF highlighting). Returns: dict or None: A

(self, input_path, coordinates=False)

Source from the content-addressed store, hash-verified

157 self.grobid_client = grobid_client
158
159 def process_structure(self, input_path, coordinates=False):
160 """Send a PDF to GROBID and return structured content.
161
162 Args:
163 input_path: Path to the PDF file.
164 coordinates: If ``True``, include bounding-box coordinate
165 strings in each passage (needed for PDF highlighting).
166
167 Returns:
168 dict or None: A dict with keys:
169
170 - ``"biblio"`` — bibliographic metadata (title, authors, DOI, …).
171 - ``"passages"`` — list of passage dicts, each containing
172 ``text``, ``type``, ``section``, ``subSection``,
173 ``passage_id``, and ``coordinates``.
174 - ``"filename"`` — stem of the PDF filename.
175
176 Returns ``None`` if GROBID returns a non-200 status.
177 """
178 try:
179 pdf_file, status, text = self.grobid_client.process_pdf(
180 "processFulltextDocument",
181 input_path,
182 consolidate_header=True,
183 consolidate_citations=False,
184 segment_sentences=False,
185 tei_coordinates=coordinates,
186 include_raw_citations=False,
187 include_raw_affiliations=False,
188 generateIDs=True,
189 )
190 except requests.exceptions.RequestException as exc:
191 # Transport-level failure (connection refused, timeout, …).
192 # Local/usage errors (bad path, parsing bugs) are intentionally
193 # not caught here so they surface with their real traceback.
194 raise GrobidServiceError("Grobid service did not respond.") from exc
195
196 if status != 200:
197 # Grobid attaches a human-readable reason to error responses
198 # (e.g. a 500 body explaining what went wrong). Surface it
199 # alongside the status code instead of discarding it.
200 reason = text.strip() if text else ""
201 message = f"Grobid service returned status {status}."
202 if reason:
203 message += f" {reason}"
204 raise GrobidServiceError(message, status_code=status)
205
206 # Grobid can answer 200 with an empty body (e.g. it gave up on the PDF).
207 if not text or not text.strip():
208 raise GrobidServiceError("Grobid returned an empty response.", status_code=status)
209
210 # A truncated/corrupted TEI payload makes the XML parser blow up; map
211 # that to a clear service error instead of an opaque parsing traceback.
212 try:
213 document_object = self.parse_grobid_xml(text, coordinates=coordinates)
214 except GrobidServiceError:
215 raise
216 except Exception as exc:

Callers 1

process_singleMethod · 0.95

Calls 4

parse_grobid_xmlMethod · 0.95
GrobidServiceErrorClass · 0.85
process_pdfMethod · 0.80
getMethod · 0.80

Tested by

no test coverage detected