vlmparse 0.1.4__py3-none-any.whl → 0.1.6__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.
- vlmparse/cli.py +26 -96
- vlmparse/clients/chandra.py +1 -1
- vlmparse/clients/deepseekocr.py +51 -51
- vlmparse/clients/docling.py +2 -2
- vlmparse/clients/dotsocr.py +20 -7
- vlmparse/clients/hunyuanocr.py +2 -1
- vlmparse/clients/mineru.py +18 -19
- vlmparse/clients/olmocr.py +1 -1
- vlmparse/clients/openai_converter.py +14 -4
- vlmparse/clients/paddleocrvl.py +2 -1
- vlmparse/converter_with_server.py +38 -11
- vlmparse/data_model/document.py +11 -1
- vlmparse/registries.py +3 -7
- vlmparse/servers/docker_server.py +16 -2
- vlmparse/servers/utils.py +3 -2
- {vlmparse-0.1.4.dist-info → vlmparse-0.1.6.dist-info}/METADATA +22 -6
- vlmparse-0.1.6.dist-info/RECORD +36 -0
- vlmparse/benchpdf2md/bench_tests/benchmark_tsts.py +0 -1763
- vlmparse/benchpdf2md/bench_tests/utils.py +0 -0
- vlmparse/benchpdf2md/create_dataset.py +0 -60
- vlmparse/benchpdf2md/olmocrbench/katex/__init__.py +0 -1
- vlmparse/benchpdf2md/olmocrbench/katex/render.py +0 -592
- vlmparse/benchpdf2md/olmocrbench/repeatdetect.py +0 -175
- vlmparse/benchpdf2md/olmocrbench/run_olmocr_bench.py +0 -256
- vlmparse/benchpdf2md/olmocrbench/tests.py +0 -1334
- vlmparse/benchpdf2md/run_benchmark.py +0 -296
- vlmparse/benchpdf2md/st_visu_benchmark/app.py +0 -271
- vlmparse/benchpdf2md/st_visu_benchmark/highligh_text.py +0 -117
- vlmparse/benchpdf2md/st_visu_benchmark/test_form.py +0 -95
- vlmparse/benchpdf2md/st_visu_benchmark/ui_elements.py +0 -20
- vlmparse/benchpdf2md/st_visu_benchmark/utils.py +0 -50
- vlmparse/benchpdf2md/utils.py +0 -56
- vlmparse-0.1.4.dist-info/RECORD +0 -51
- {vlmparse-0.1.4.dist-info → vlmparse-0.1.6.dist-info}/WHEEL +0 -0
- {vlmparse-0.1.4.dist-info → vlmparse-0.1.6.dist-info}/entry_points.txt +0 -0
- {vlmparse-0.1.4.dist-info → vlmparse-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {vlmparse-0.1.4.dist-info → vlmparse-0.1.6.dist-info}/top_level.txt +0 -0
vlmparse/data_model/document.py
CHANGED
|
@@ -41,6 +41,10 @@ class Page(VLMParseBaseModel):
|
|
|
41
41
|
buffer_image: Optional[Image.Image | str | dict] = None
|
|
42
42
|
latency: Optional[float] = None
|
|
43
43
|
"""Time taken to process the page in seconds."""
|
|
44
|
+
prompt_tokens: Optional[int] = None
|
|
45
|
+
completion_tokens: Optional[int] = None
|
|
46
|
+
"""Include reasoning tokens"""
|
|
47
|
+
reasoning_tokens: Optional[int] = None
|
|
44
48
|
|
|
45
49
|
@property
|
|
46
50
|
def image(self):
|
|
@@ -66,7 +70,7 @@ class Page(VLMParseBaseModel):
|
|
|
66
70
|
|
|
67
71
|
image = self.image
|
|
68
72
|
|
|
69
|
-
if layout:
|
|
73
|
+
if layout and image is not None:
|
|
70
74
|
if self.items is None:
|
|
71
75
|
return image
|
|
72
76
|
items = self.items
|
|
@@ -85,6 +89,9 @@ class Page(VLMParseBaseModel):
|
|
|
85
89
|
)
|
|
86
90
|
return image
|
|
87
91
|
|
|
92
|
+
def to_markdown(self, **kwargs):
|
|
93
|
+
return self.text if self.text is not None else ""
|
|
94
|
+
|
|
88
95
|
|
|
89
96
|
class Document(VLMParseBaseModel):
|
|
90
97
|
file_path: str
|
|
@@ -104,6 +111,9 @@ class Document(VLMParseBaseModel):
|
|
|
104
111
|
page.error is not None for page in self.pages
|
|
105
112
|
)
|
|
106
113
|
|
|
114
|
+
def to_markdown(self, **kwargs):
|
|
115
|
+
return "\n\n".join([page.to_markdown(**kwargs) for page in self.pages])
|
|
116
|
+
|
|
107
117
|
def to_zip(
|
|
108
118
|
self,
|
|
109
119
|
file_path,
|
vlmparse/registries.py
CHANGED
|
@@ -77,9 +77,7 @@ class ConverterConfigRegistry:
|
|
|
77
77
|
"""Register a config factory for a model name."""
|
|
78
78
|
self._registry[model_name] = config_factory
|
|
79
79
|
|
|
80
|
-
def get(
|
|
81
|
-
self, model_name: str, uri: str | None = None
|
|
82
|
-
) -> OpenAIConverterConfig | None:
|
|
80
|
+
def get(self, model_name: str, uri: str | None = None) -> OpenAIConverterConfig:
|
|
83
81
|
"""Get config for a model name. Returns default if not registered."""
|
|
84
82
|
if model_name in self._registry:
|
|
85
83
|
return self._registry[model_name](uri=uri)
|
|
@@ -108,6 +106,7 @@ for gemini_model in [
|
|
|
108
106
|
"gemini-2.5-flash",
|
|
109
107
|
"gemini-2.5-flash-lite",
|
|
110
108
|
"gemini-3-pro-preview",
|
|
109
|
+
"gemini-3-flash-preview",
|
|
111
110
|
]:
|
|
112
111
|
converter_config_registry.register(
|
|
113
112
|
gemini_model,
|
|
@@ -120,12 +119,9 @@ for gemini_model in [
|
|
|
120
119
|
),
|
|
121
120
|
)
|
|
122
121
|
for openai_model in [
|
|
123
|
-
"gpt-5.
|
|
124
|
-
"gpt-5.1-mini",
|
|
125
|
-
"gpt-5.1-nano",
|
|
122
|
+
"gpt-5.2",
|
|
126
123
|
"gpt-5",
|
|
127
124
|
"gpt-5-mini",
|
|
128
|
-
"gpt-5-nano",
|
|
129
125
|
]:
|
|
130
126
|
converter_config_registry.register(
|
|
131
127
|
openai_model,
|
|
@@ -47,6 +47,20 @@ class DockerServerConfig(BaseModel):
|
|
|
47
47
|
"""Build command for container. Override in subclasses for specific logic."""
|
|
48
48
|
return self.command_args if self.command_args else None
|
|
49
49
|
|
|
50
|
+
def update_command_args(
|
|
51
|
+
self,
|
|
52
|
+
vllm_kwargs: dict | None = None,
|
|
53
|
+
forget_predefined_vllm_kwargs: bool = False,
|
|
54
|
+
) -> list[str]:
|
|
55
|
+
if vllm_kwargs is not None:
|
|
56
|
+
new_kwargs = [f"--{k}={v}" for k, v in vllm_kwargs.items()]
|
|
57
|
+
if forget_predefined_vllm_kwargs:
|
|
58
|
+
self.command_args = new_kwargs
|
|
59
|
+
else:
|
|
60
|
+
self.command_args.extend(new_kwargs)
|
|
61
|
+
|
|
62
|
+
return self.command_args
|
|
63
|
+
|
|
50
64
|
def get_volumes(self) -> dict | None:
|
|
51
65
|
"""Setup volumes for container. Override in subclasses for specific logic."""
|
|
52
66
|
return self.volumes
|
|
@@ -78,7 +92,7 @@ class VLLMDockerServerConfig(DockerServerConfig):
|
|
|
78
92
|
from vlmparse.clients.openai_converter import LLMParams
|
|
79
93
|
|
|
80
94
|
return LLMParams(
|
|
81
|
-
base_url=f"http://localhost:{self.docker_port}
|
|
95
|
+
base_url=f"http://localhost:{self.docker_port}{self.get_base_url_suffix()}",
|
|
82
96
|
model_name=self.default_model_name,
|
|
83
97
|
)
|
|
84
98
|
|
|
@@ -144,7 +158,7 @@ class ConverterServer:
|
|
|
144
158
|
"""Start the Docker server."""
|
|
145
159
|
if self._server_context is not None:
|
|
146
160
|
logger.warning("Server already started")
|
|
147
|
-
return self.base_url
|
|
161
|
+
return self.base_url, self._container
|
|
148
162
|
|
|
149
163
|
# Use the generic docker_server for all server types
|
|
150
164
|
self._server_context = docker_server(config=self.config, cleanup=self.auto_stop)
|
vlmparse/servers/utils.py
CHANGED
|
@@ -3,9 +3,8 @@ import time
|
|
|
3
3
|
from contextlib import contextmanager
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
from loguru import logger
|
|
7
|
-
|
|
8
6
|
import docker
|
|
7
|
+
from loguru import logger
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def _ensure_image_exists(
|
|
@@ -230,6 +229,8 @@ def get_model_from_uri(uri: str) -> str:
|
|
|
230
229
|
for container in containers:
|
|
231
230
|
c_uri = container.labels.get("vlmparse_uri")
|
|
232
231
|
c_model = container.labels.get("vlmparse_model_name")
|
|
232
|
+
if c_uri is not None:
|
|
233
|
+
c_uri = c_uri.replace("localhost", "0.0.0.0")
|
|
233
234
|
|
|
234
235
|
# Check if user URI matches container URI (ignoring /v1 suffix if missing)
|
|
235
236
|
if c_uri and (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vlmparse
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Requires-Python: >=3.
|
|
3
|
+
Version: 0.1.6
|
|
4
|
+
Requires-Python: >=3.11.0
|
|
5
5
|
Description-Content-Type: text/markdown
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Requires-Dist: devtools>=0.12.2
|
|
@@ -72,6 +72,19 @@ Supported Converters:
|
|
|
72
72
|
|
|
73
73
|
## Installation
|
|
74
74
|
|
|
75
|
+
Simplest solution with only the cli:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uv tool install vlmparse
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If you want to run the granite-docling model or use the streamlit viewing app:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
uv tool install vlmparse[docling_core,st_app]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
If you prefer cloning the repository and using the local version:
|
|
75
88
|
```bash
|
|
76
89
|
uv sync
|
|
77
90
|
```
|
|
@@ -86,10 +99,11 @@ Activate the virtual environment:
|
|
|
86
99
|
```bash
|
|
87
100
|
source .venv/bin/activate
|
|
88
101
|
```
|
|
89
|
-
Other solution: append uv run to all the commands below.
|
|
90
102
|
|
|
91
103
|
## CLI Usage
|
|
92
104
|
|
|
105
|
+
Note that you can bypass the previous installation step and just add uvx before each of the commands below.
|
|
106
|
+
|
|
93
107
|
### Convert PDFs
|
|
94
108
|
|
|
95
109
|
With a general VLM (requires setting your api key as an environment variable):
|
|
@@ -185,11 +199,13 @@ server.stop()
|
|
|
185
199
|
```
|
|
186
200
|
|
|
187
201
|
|
|
188
|
-
Converter with automatic server
|
|
202
|
+
Converter with automatic server management:
|
|
189
203
|
|
|
190
204
|
```python
|
|
191
205
|
from vlmparse.converter_with_server import ConverterWithServer
|
|
192
206
|
|
|
193
|
-
|
|
194
|
-
documents = converter_with_server.parse(inputs=["file1.pdf", "file2.pdf"], out_folder="./output")
|
|
207
|
+
with ConverterWithServer(model="mineru2.5") as converter_with_server:
|
|
208
|
+
documents = converter_with_server.parse(inputs=["file1.pdf", "file2.pdf"], out_folder="./output")
|
|
195
209
|
```
|
|
210
|
+
|
|
211
|
+
Note that if you pass an uri of a vllm server to `ConverterWithServer`, the model name is inferred automatically and no server is started.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
vlmparse/base_model.py,sha256=4U4UPe8SNArliKnUf8pp8zQugWYsnhg9okylt7mrW1U,381
|
|
2
|
+
vlmparse/build_doc.py,sha256=LAWrnFrqamN5PwJo57AUtQOPrMFGnCGw4gBjEKZ6pYo,2127
|
|
3
|
+
vlmparse/cli.py,sha256=gY45YZe5LanN-ozG2vVtOaB2qyNWpjO2DvPmJeBi_wA,13045
|
|
4
|
+
vlmparse/constants.py,sha256=7-47S01n4MI2ebR09bpdOo3_P16d-z-NVGsm6KJP8ls,110
|
|
5
|
+
vlmparse/converter.py,sha256=F0JSY9sFYUggCvaUCb27kKGJJpnZKW2FStMDVJoIOeQ,7383
|
|
6
|
+
vlmparse/converter_with_server.py,sha256=62kcEp0NjzDR2vVmEfCeeLlwbb8E3sWcseb2jjK7DpM,4861
|
|
7
|
+
vlmparse/registries.py,sha256=yBVrrhy61rSoLwdNV-z0C4lqIpTbLoWab3V6u7aSyNM,5797
|
|
8
|
+
vlmparse/utils.py,sha256=rcVrtPiQVj_8HAmFQOu___72uYIapp_X89yxrMNCBow,1236
|
|
9
|
+
vlmparse/clients/chandra.py,sha256=EulsCZdwOtm0pQ6CDm320U96k8aWFN4wKqCm1Xo7VCE,9775
|
|
10
|
+
vlmparse/clients/deepseekocr.py,sha256=Uw6tPvP2KVsPDlz1ZUgYdbgQSjmFPuYeFDrGMMOTBAo,6501
|
|
11
|
+
vlmparse/clients/docling.py,sha256=SAkLsqseuWfkuiel8FWR1G0Z5s-SZU3dE2JbsOvF4SA,5328
|
|
12
|
+
vlmparse/clients/dotsocr.py,sha256=uGJoYEiDkP3-rmfdkAnMeAX-T4RZyEPoh6jmow5_-J8,10336
|
|
13
|
+
vlmparse/clients/granite_docling.py,sha256=EQpsv5qSJG0HtMSacmJStER2sq4TGf1EMU5_NmJsl4g,4634
|
|
14
|
+
vlmparse/clients/hunyuanocr.py,sha256=UFqaS4b8UM9EtizyrZIxlqcYlESmxm8xrQZP7lL6tkE,1857
|
|
15
|
+
vlmparse/clients/lightonocr.py,sha256=wx1Im8Z3wlRWwYbPqnSd3LqTtdAU8CnX5mzu1BuCUY8,1314
|
|
16
|
+
vlmparse/clients/mineru.py,sha256=6jZ1sKn2kGwUvD8gVs4PqEDH7uUXYK8pAB5Fr1JeqnY,3617
|
|
17
|
+
vlmparse/clients/nanonetocr.py,sha256=BT5vaeerCsK5agvOaHK3NvLUqWd1FfDmrMmDYbp646I,1543
|
|
18
|
+
vlmparse/clients/olmocr.py,sha256=A4Vl0meYpU5QPTML_OxyyRM07xCxtfrMZedgGMYEcuU,1851
|
|
19
|
+
vlmparse/clients/openai_converter.py,sha256=nMKJeWH43UxHMMLns3wjX0pYjU5Xnai6IYxFmS9I63s,6193
|
|
20
|
+
vlmparse/clients/paddleocrvl.py,sha256=qFBDj_UQocyq3WCh24tUOx9Ud7S9DfSm-1n3ztikY2s,1402
|
|
21
|
+
vlmparse/clients/prompts.py,sha256=-J60lqxgRzlkQ9VsQLxmWsIMaDt-gNqWqWoqHIw9CLc,4228
|
|
22
|
+
vlmparse/clients/pipe_utils/cleaner.py,sha256=oxBkBTOkluN1lmeNbzajRIe0_D__ZGwUOBaI_Ph0uxE,2396
|
|
23
|
+
vlmparse/clients/pipe_utils/html_to_md_conversion.py,sha256=cFFqzD2jCNw_968_eu3Wt--Ox7iJj2Rn5UoP_DZWosU,4112
|
|
24
|
+
vlmparse/clients/pipe_utils/utils.py,sha256=935ecIO446I0pstszE_1nrIPHn1Ffrxunq7fVd0dsd8,315
|
|
25
|
+
vlmparse/data_model/box.py,sha256=lJsh4qhjgYXZF5vTSJ1qMXD5GVlBi2_SBedBMlfJikU,16868
|
|
26
|
+
vlmparse/data_model/document.py,sha256=xheaMeStOj2c9GZKmdtxcEl_Dj44V5JyVp6JnTrSpH0,4615
|
|
27
|
+
vlmparse/servers/docker_server.py,sha256=FBW2TvtUHUQNwj0rBP92shvoiJCGlc_oAKQBXN8260E,7114
|
|
28
|
+
vlmparse/servers/utils.py,sha256=qy2-rnQTCQKt6CeTV5H74tvRTXyzBV2KswQiYW8Tf-k,8908
|
|
29
|
+
vlmparse/st_viewer/fs_nav.py,sha256=7GNH68h2Loh5pQ64Pe72-D2cs2BLhqRXevEmKdFmPX0,1616
|
|
30
|
+
vlmparse/st_viewer/st_viewer.py,sha256=m2rQTtk5rlwErNmivNAg-4rkHkvNkvLhoJZxFQi7Dwk,2105
|
|
31
|
+
vlmparse-0.1.6.dist-info/licenses/LICENSE,sha256=3TKJHk8hPBR5dbLWZ3IpfCftl-_m-iyBwpYQGZYxj14,1080
|
|
32
|
+
vlmparse-0.1.6.dist-info/METADATA,sha256=Xad3SjAYvCzUvPo6A6GKvc3daxtf5XNs1AQjDlF7RmI,5597
|
|
33
|
+
vlmparse-0.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
34
|
+
vlmparse-0.1.6.dist-info/entry_points.txt,sha256=gD5berP6HwE2wNIkls-Lw5goiceA8uMgPEd7ifnFJXs,47
|
|
35
|
+
vlmparse-0.1.6.dist-info/top_level.txt,sha256=k4ni-GNH_iAX7liQEsk_KY_c3xgZgt8k9fsSs9IXLXs,9
|
|
36
|
+
vlmparse-0.1.6.dist-info/RECORD,,
|