visual-parser 2.2.1__py3-none-any.whl → 2.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- visual_parser/__init__.py +1 -1
- visual_parser/cli.py +10 -0
- visual_parser/cli_main.py +10 -0
- visual_parser/config.py +9 -0
- visual_parser/pipeline.py +1 -0
- visual_parser/text_extractor.py +5 -1
- {visual_parser-2.2.1.dist-info → visual_parser-2.2.2.dist-info}/METADATA +9 -5
- {visual_parser-2.2.1.dist-info → visual_parser-2.2.2.dist-info}/RECORD +12 -12
- {visual_parser-2.2.1.dist-info → visual_parser-2.2.2.dist-info}/WHEEL +0 -0
- {visual_parser-2.2.1.dist-info → visual_parser-2.2.2.dist-info}/entry_points.txt +0 -0
- {visual_parser-2.2.1.dist-info → visual_parser-2.2.2.dist-info}/licenses/LICENSE +0 -0
- {visual_parser-2.2.1.dist-info → visual_parser-2.2.2.dist-info}/top_level.txt +0 -0
visual_parser/__init__.py
CHANGED
visual_parser/cli.py
CHANGED
|
@@ -111,6 +111,15 @@ def _build_arg_parser() -> argparse.ArgumentParser:
|
|
|
111
111
|
metavar="N",
|
|
112
112
|
help="Overlap characters between adjacent chunks (default: 100).",
|
|
113
113
|
)
|
|
114
|
+
text_group.add_argument(
|
|
115
|
+
"--nougat-crop-margin",
|
|
116
|
+
action="store_true",
|
|
117
|
+
help=(
|
|
118
|
+
"Let Nougat autocrop whitespace margins (its own default). "
|
|
119
|
+
"Off by default -- autocropping can silently crop into real "
|
|
120
|
+
"content on unusual page layouts."
|
|
121
|
+
),
|
|
122
|
+
)
|
|
114
123
|
|
|
115
124
|
# ---- Vision LLM ---------------------------------------------------------
|
|
116
125
|
vision_group = p.add_argument_group("Vision LLM (figure descriptions & metadata)")
|
|
@@ -366,6 +375,7 @@ def main(argv=None) -> int:
|
|
|
366
375
|
nougat_model = args.nougat_model,
|
|
367
376
|
chunk_size = args.chunk_size,
|
|
368
377
|
chunk_overlap = args.chunk_overlap,
|
|
378
|
+
nougat_crop_margin = args.nougat_crop_margin,
|
|
369
379
|
vision_provider = args.vision_provider,
|
|
370
380
|
gpt_vision_model = args.vision_model if args.vision_provider == "gpt" else "gpt-5.4",
|
|
371
381
|
gemini_vision_model = args.vision_model if args.vision_provider == "gemini" else "gemini-3.8-flash",
|
visual_parser/cli_main.py
CHANGED
|
@@ -109,6 +109,15 @@ def _build_arg_parser() -> argparse.ArgumentParser:
|
|
|
109
109
|
metavar="N",
|
|
110
110
|
help="Overlap characters between adjacent chunks (default: 100).",
|
|
111
111
|
)
|
|
112
|
+
text_group.add_argument(
|
|
113
|
+
"--nougat-crop-margin",
|
|
114
|
+
action="store_true",
|
|
115
|
+
help=(
|
|
116
|
+
"Let Nougat autocrop whitespace margins (its own default). "
|
|
117
|
+
"Off by default -- autocropping can silently crop into real "
|
|
118
|
+
"content on unusual page layouts."
|
|
119
|
+
),
|
|
120
|
+
)
|
|
112
121
|
|
|
113
122
|
vision_group = parser.add_argument_group("Vision LLM (figure descriptions & metadata)")
|
|
114
123
|
vision_group.add_argument(
|
|
@@ -282,6 +291,7 @@ def main(argv=None) -> int:
|
|
|
282
291
|
nougat_model=args.nougat_model,
|
|
283
292
|
chunk_size=args.chunk_size,
|
|
284
293
|
chunk_overlap=args.chunk_overlap,
|
|
294
|
+
nougat_crop_margin=args.nougat_crop_margin,
|
|
285
295
|
vision_provider=args.vision_provider,
|
|
286
296
|
gpt_vision_model=args.vision_model if args.vision_provider == "gpt" else "gpt-5.4",
|
|
287
297
|
gemini_vision_model=(
|
visual_parser/config.py
CHANGED
|
@@ -79,6 +79,14 @@ class ParserConfig:
|
|
|
79
79
|
nougat_model: str = "facebook/nougat-small"
|
|
80
80
|
"""HuggingFace model identifier for Nougat."""
|
|
81
81
|
|
|
82
|
+
nougat_crop_margin: bool = False
|
|
83
|
+
"""
|
|
84
|
+
Passed through to Nougat's image processor as do_crop_margin. False
|
|
85
|
+
(default) matches this package's long-standing behavior -- autocropping
|
|
86
|
+
whitespace margins can silently crop into real content on unusual page
|
|
87
|
+
layouts. Set True to opt into Nougat's own autocrop behavior instead.
|
|
88
|
+
"""
|
|
89
|
+
|
|
82
90
|
chunk_size: int = 500
|
|
83
91
|
"""Target character count per text chunk."""
|
|
84
92
|
|
|
@@ -186,6 +194,7 @@ class ParserConfig:
|
|
|
186
194
|
output_dir = os.getenv("VISUAL_PARSER_OUTPUT_DIR", ""),
|
|
187
195
|
text_mode = os.getenv("VISUAL_PARSER_TEXT_MODE", "nougat"), # type: ignore[arg-type]
|
|
188
196
|
nougat_model = os.getenv("VISUAL_PARSER_NOUGAT_MODEL", "facebook/nougat-small"),
|
|
197
|
+
nougat_crop_margin = os.getenv("VISUAL_PARSER_NOUGAT_CROP_MARGIN", "false").lower() == "true",
|
|
189
198
|
chunk_size = int(os.getenv("VISUAL_PARSER_CHUNK_SIZE", "500")),
|
|
190
199
|
chunk_overlap = int(os.getenv("VISUAL_PARSER_CHUNK_OVERLAP", "100")),
|
|
191
200
|
vision_provider = os.getenv("VISUAL_PARSER_VISION_PROVIDER", "gpt"), # type: ignore[arg-type]
|
visual_parser/pipeline.py
CHANGED
|
@@ -501,6 +501,7 @@ def run_pipeline(config: Optional[ParserConfig] = None) -> Dict:
|
|
|
501
501
|
chunk_size = config.chunk_size,
|
|
502
502
|
chunk_overlap = config.chunk_overlap,
|
|
503
503
|
max_workers = config.max_workers,
|
|
504
|
+
nougat_crop_margin = config.nougat_crop_margin,
|
|
504
505
|
)
|
|
505
506
|
print(nougat_summary)
|
|
506
507
|
except Exception as exc:
|
visual_parser/text_extractor.py
CHANGED
|
@@ -69,6 +69,7 @@ def nougat_extract_pdfs(
|
|
|
69
69
|
chunk_size: int = 500,
|
|
70
70
|
chunk_overlap: int = 100,
|
|
71
71
|
max_workers: int = 4,
|
|
72
|
+
nougat_crop_margin: bool = False,
|
|
72
73
|
) -> Tuple[str, List[str], List[str], int]:
|
|
73
74
|
"""
|
|
74
75
|
Extract text from each PDF in *only_process_these* using the Nougat model,
|
|
@@ -83,6 +84,9 @@ def nougat_extract_pdfs(
|
|
|
83
84
|
chunk_size: Characters per chunk.
|
|
84
85
|
chunk_overlap: Overlap between adjacent chunks.
|
|
85
86
|
max_workers: Thread-pool size for parallel PDF processing.
|
|
87
|
+
nougat_crop_margin: Passed through to Nougat's image processor as
|
|
88
|
+
do_crop_margin (default False -- see
|
|
89
|
+
ParserConfig.nougat_crop_margin's docstring).
|
|
86
90
|
|
|
87
91
|
Always resumes against the 04_processed_pdfs.txt registry -- callers
|
|
88
92
|
that want a PDF reprocessed must first clear its existing chunks and
|
|
@@ -124,7 +128,7 @@ def nougat_extract_pdfs(
|
|
|
124
128
|
pixel_values = processor(
|
|
125
129
|
images=image,
|
|
126
130
|
return_tensors="pt",
|
|
127
|
-
do_crop_margin=
|
|
131
|
+
do_crop_margin=nougat_crop_margin,
|
|
128
132
|
).pixel_values.to(device)
|
|
129
133
|
except TypeError:
|
|
130
134
|
pixel_values = processor(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: visual-parser
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Standalone Visual-RAG PDF Parser - text extraction and Vision-LLM figure descriptions to JSONL
|
|
5
5
|
Author: Zavier N. Ndum
|
|
6
6
|
Author-email: zavier.ndum@tamu.edu
|
|
@@ -50,7 +50,7 @@ Dynamic: license-file
|
|
|
50
50
|

|
|
51
51
|

|
|
52
52
|
|
|
53
|
-
`visual-parser` converts PDFs into a multi-modal JSONL knowledge base (text chunks, figure descriptions, metadata). It was extracted from [RADIANT-LLM](https://github.com/SmartLabNuclear/RADIANT_LLM) as a standalone PDF-ingestion tool, independent of any chatbot.
|
|
53
|
+
`visual-parser` converts PDFs (and standalone images alongside them) into a multi-modal JSONL knowledge base (text chunks, figure descriptions, standalone image descriptions, metadata). It was extracted from [RADIANT-LLM](https://github.com/SmartLabNuclear/RADIANT_LLM) as a standalone PDF-ingestion tool, independent of any chatbot.
|
|
54
54
|
|
|
55
55
|
1) Run `visual-parser` on curated PDFs to generate JSONL KB files.
|
|
56
56
|
2) Point any downstream RAG system at the generated KB — RADIANT-LLM, AutoSAM, and AutoFLUKA all consume the identical JSONL/registry format, so the same KB works with any of them without re-parsing.
|
|
@@ -72,10 +72,11 @@ Dynamic: license-file
|
|
|
72
72
|
|
|
73
73
|
By default, the pipeline writes:
|
|
74
74
|
- `01_chunks_kb.jsonl`: chunked text extracted from PDFs (Nougat by default).
|
|
75
|
-
- `02_visuals_kb.jsonl`: figure/page visual descriptions (Vision LLM).
|
|
75
|
+
- `02_visuals_kb.jsonl`: figure/page visual descriptions (Vision LLM), one row per figure found in a PDF.
|
|
76
76
|
- `03_metadata_kb.jsonl`: document metadata rows (title/author/etc.).
|
|
77
|
+
- `image_descriptions.jsonl`: one holistic description per **standalone image** file found alongside your PDFs in `--input-dir` (not a PDF's own figures) — auto-detected by extension, no separate flag needed; disable with `--skip-images`.
|
|
77
78
|
|
|
78
|
-
Alongside the KB, the pipeline also writes
|
|
79
|
+
Alongside the KB, the pipeline also writes bookkeeping files: `04_processed_pdfs.txt` / `parsed_images.txt` (track which PDFs/images have already been processed, so re-runs skip them unless `--rebuild` or `--redo NAME`) and `05_pipeline.log` (run log at the verbosity set by `--log-level`, default `ERROR`).
|
|
79
80
|
|
|
80
81
|
## API Keys (.env)
|
|
81
82
|
|
|
@@ -262,6 +263,7 @@ Text extraction:
|
|
|
262
263
|
- `--nougat-model facebook/nougat-small`
|
|
263
264
|
- `--chunk-size 500`
|
|
264
265
|
- `--chunk-overlap 100`
|
|
266
|
+
- `--nougat-crop-margin` (off by default — lets Nougat autocrop whitespace margins instead of this package's long-standing uncropped behavior; autocropping can silently crop into real content on unusual page layouts)
|
|
265
267
|
|
|
266
268
|
Vision LLM:
|
|
267
269
|
- `--vision-provider gpt|gemini|ollama` (default: `gpt`) — see [Local Ollama vision provider](#local-ollama-vision-provider) for the `ollama` option
|
|
@@ -273,8 +275,10 @@ Vision LLM:
|
|
|
273
275
|
|
|
274
276
|
Performance / misc:
|
|
275
277
|
- `--max-workers 4`
|
|
276
|
-
- `--rebuild` (reprocess everything; ignore `04_processed_pdfs.txt`)
|
|
278
|
+
- `--rebuild` (reprocess everything; ignore `04_processed_pdfs.txt`/`parsed_images.txt`)
|
|
279
|
+
- `--redo NAME` (surgically clear one PDF/image's rows from every KB file + both registries, so it's reprocessed fresh on the next run — a targeted alternative to `--rebuild`)
|
|
277
280
|
- `--skip-text` (skip text extraction and resume only the vision steps; use after an interrupted run)
|
|
281
|
+
- `--skip-images` (don't process standalone images in `--input-dir`, PDFs only)
|
|
278
282
|
- `--list-models` — print the live, currently-available vision models for whichever provider(s) you have a key configured for, then exit (no PDF processing). Reflects Portkey's catalog too when that's active.
|
|
279
283
|
- `--version` / `-V`
|
|
280
284
|
- `--log-level DEBUG|INFO|WARNING|ERROR` (default: `ERROR`)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
visual_parser/__init__.py,sha256=
|
|
1
|
+
visual_parser/__init__.py,sha256=A1YmiufPZJW4uHVo2hfds0NX0ixxg3fDU7DpfMnPU6E,858
|
|
2
2
|
visual_parser/__main__.py,sha256=-p6rqjrnsjrtu71eFtmZdqFI1NgHXX9ASOnjuGqghNo,168
|
|
3
|
-
visual_parser/cli.py,sha256=
|
|
4
|
-
visual_parser/cli_main.py,sha256=
|
|
5
|
-
visual_parser/config.py,sha256=
|
|
3
|
+
visual_parser/cli.py,sha256=nU9SAnaWR9J3WzhKOgO1qHL-9kA1RKntR5L2pVz1zX8,16049
|
|
4
|
+
visual_parser/cli_main.py,sha256=SdABWlUeGDNnVSzUZ8Nky5cxUvsxwJsMuzGliYJFYzk,11805
|
|
5
|
+
visual_parser/config.py,sha256=mu52rGN1keQtho70IUP7kPuS6Wykpcc-gv3z0irg70c,12140
|
|
6
6
|
visual_parser/figure_describer.py,sha256=q7Jsccsn5iGK4sCbsVOD4EzLuycbvBeBSYtHX0e9jPw,13470
|
|
7
7
|
visual_parser/image_describer.py,sha256=nkwqK4aDcwYjuBLCjV2AmZShzCT_pdUkPZJLy2KaV9M,13859
|
|
8
8
|
visual_parser/image_tracker.py,sha256=MyQiUyqnW6b7e7R7yIefJ0k15OO0WEkK5wMiRD2nmfU,2496
|
|
@@ -14,13 +14,13 @@ visual_parser/nougat_engine.py,sha256=o9u9XTxOL1EAo63mVARVt4z1IxfDMpvjhMD4URfTx1
|
|
|
14
14
|
visual_parser/ollama_local.py,sha256=YQi1oT4OZcuxrp2yCVN5wo49jl9k7f6dvVFGt108v8g,13883
|
|
15
15
|
visual_parser/openai_gateway.py,sha256=XebNY3qOY1I1SdrLFqw9yeax2_IwOSZyVi_XYWfYXj0,3683
|
|
16
16
|
visual_parser/pdf_tracker.py,sha256=VDn5TOFVATNIcTjLt3i-HK99mtMEsu0Y9IRZGPb-a-g,4616
|
|
17
|
-
visual_parser/pipeline.py,sha256=
|
|
17
|
+
visual_parser/pipeline.py,sha256=Bh03FO3ylIsC1bfRITvffGzL-e5r07dKVzgHEiNRK6Y,30944
|
|
18
18
|
visual_parser/prompts.py,sha256=hdjDUZjF0A9eugm6qt4K5E1qnqMO1JE9_mTDAGS7sgg,11186
|
|
19
|
-
visual_parser/text_extractor.py,sha256=
|
|
19
|
+
visual_parser/text_extractor.py,sha256=kMmjTvTnPJBsFTIv5qN49v88k1SJhQMtTob8_LT1tfE,17491
|
|
20
20
|
visual_parser/vision_llm.py,sha256=TXiitsDAMIdo9fbzYVKqd-0sGt-hqiJryMU481eo1SM,17429
|
|
21
|
-
visual_parser-2.2.
|
|
22
|
-
visual_parser-2.2.
|
|
23
|
-
visual_parser-2.2.
|
|
24
|
-
visual_parser-2.2.
|
|
25
|
-
visual_parser-2.2.
|
|
26
|
-
visual_parser-2.2.
|
|
21
|
+
visual_parser-2.2.2.dist-info/licenses/LICENSE,sha256=OEJRtZkWILIqPizQxk1m2CjYi1czEKW15RKX6WgLVBE,11344
|
|
22
|
+
visual_parser-2.2.2.dist-info/METADATA,sha256=WJGuFZVprE2_nb1BdBpwDnDFpV1J78AJ_Ntz-mjYnK8,16422
|
|
23
|
+
visual_parser-2.2.2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
24
|
+
visual_parser-2.2.2.dist-info/entry_points.txt,sha256=yypghqnxA-nSiyoDyhlg99SK9vfOzloFwUiiwRw4EWI,62
|
|
25
|
+
visual_parser-2.2.2.dist-info/top_level.txt,sha256=_aaZ41uFRN_WX-616YvmcXIroNq4k4m6Ph6FGetxLYY,14
|
|
26
|
+
visual_parser-2.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|