vlmparse 0.1.6__py3-none-any.whl → 0.1.8__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.
@@ -2,15 +2,23 @@ import os
2
2
  from typing import Callable
3
3
 
4
4
  from loguru import logger
5
- from pydantic import BaseModel, Field
5
+ from pydantic import Field
6
6
 
7
+ from .model_identity import ModelIdentityMixin
7
8
  from .utils import docker_server
8
9
 
9
10
 
10
- class DockerServerConfig(BaseModel):
11
- """Base configuration for deploying a Docker server."""
11
+ class DockerServerConfig(ModelIdentityMixin):
12
+ """Base configuration for deploying a Docker server.
13
+
14
+ Inherits from ModelIdentityMixin which provides:
15
+ - model_name: str
16
+ - default_model_name: str | None
17
+ - aliases: list[str]
18
+ - _create_client_kwargs(base_url): Helper for creating client configs
19
+ - get_all_names(): All names this model can be referenced by
20
+ """
12
21
 
13
- model_name: str
14
22
  docker_image: str
15
23
  dockerfile_dir: str | None = None
16
24
  command_args: list[str] = Field(default_factory=list)
@@ -27,7 +35,6 @@ class DockerServerConfig(BaseModel):
27
35
  environment: dict[str, str] = Field(default_factory=dict)
28
36
  volumes: dict[str, dict] | None = None
29
37
  entrypoint: str | None = None
30
- aliases: list[str] = Field(default_factory=list)
31
38
 
32
39
  class Config:
33
40
  extra = "allow"
@@ -49,15 +56,14 @@ class DockerServerConfig(BaseModel):
49
56
 
50
57
  def update_command_args(
51
58
  self,
52
- vllm_kwargs: dict | None = None,
53
- forget_predefined_vllm_kwargs: bool = False,
59
+ vllm_args: dict | None = None,
60
+ forget_predefined_vllm_args: bool = False,
54
61
  ) -> 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
62
+ if vllm_args is not None:
63
+ if forget_predefined_vllm_args:
64
+ self.command_args = vllm_args
59
65
  else:
60
- self.command_args.extend(new_kwargs)
66
+ self.command_args.extend(vllm_args)
61
67
 
62
68
  return self.command_args
63
69
 
@@ -85,22 +91,16 @@ class VLLMDockerServerConfig(DockerServerConfig):
85
91
  hf_home_folder: str | None = os.getenv("HF_HOME", None)
86
92
  add_model_key_to_server: bool = False
87
93
  container_port: int = 8000
88
- aliases: list[str] = Field(default_factory=list)
89
-
90
- @property
91
- def llm_params(self):
92
- from vlmparse.clients.openai_converter import LLMParams
93
-
94
- return LLMParams(
95
- base_url=f"http://localhost:{self.docker_port}{self.get_base_url_suffix()}",
96
- model_name=self.default_model_name,
97
- )
98
94
 
99
95
  @property
100
96
  def client_config(self):
101
97
  from vlmparse.clients.openai_converter import OpenAIConverterConfig
102
98
 
103
- return OpenAIConverterConfig(llm_params=self.llm_params)
99
+ return OpenAIConverterConfig(
100
+ **self._create_client_kwargs(
101
+ f"http://localhost:{self.docker_port}{self.get_base_url_suffix()}"
102
+ )
103
+ )
104
104
 
105
105
  def get_command(self) -> list[str]:
106
106
  """Build VLLM-specific command."""
@@ -172,41 +172,64 @@ class ConverterServer:
172
172
  def stop(self):
173
173
  """Stop the Docker server."""
174
174
  if self._server_context is not None:
175
- self._server_context.__exit__(None, None, None)
176
- self._server_context = None
177
- self._container = None
178
- self.base_url = None
175
+ try:
176
+ self._server_context.__exit__(None, None, None)
177
+ except Exception as e:
178
+ logger.warning(f"Error during server cleanup: {e}")
179
+ finally:
180
+ self._server_context = None
181
+ self._container = None
182
+ self.base_url = None
179
183
  logger.info("Server stopped")
180
184
 
181
185
  def __del__(self):
182
- """Automatically stop server when object is destroyed if auto_stop is True."""
183
- if self.auto_stop and self._server_context is not None:
184
- self.stop()
186
+ """Automatically stop server when object is destroyed if auto_stop is True.
187
+
188
+ Note: This is a fallback mechanism. Prefer using the context manager
189
+ or explicitly calling stop() for reliable cleanup.
190
+ """
191
+ try:
192
+ if self.auto_stop and self._server_context is not None:
193
+ self.stop()
194
+ except Exception:
195
+ pass # Suppress errors during garbage collection
185
196
 
186
197
 
187
198
  class DockerConfigRegistry:
188
- """Registry for mapping model names to their Docker configurations."""
199
+ """Registry for mapping model names to their Docker configurations.
200
+
201
+ Thread-safe registry that maps model names to their Docker configuration factories.
202
+ """
189
203
 
190
204
  def __init__(self):
191
- self._registry = dict()
205
+ import threading
206
+
207
+ self._registry: dict[str, Callable[[], DockerServerConfig | None]] = {}
208
+ self._lock = threading.RLock()
192
209
 
193
210
  def register(
194
211
  self, model_name: str, config_factory: Callable[[], DockerServerConfig | None]
195
212
  ):
196
- """Register a config factory for a model name."""
197
- self._registry[model_name] = config_factory
213
+ """Register a config factory for a model name (thread-safe)."""
214
+ with self._lock:
215
+ self._registry[model_name] = config_factory
198
216
 
199
217
  def get(self, model_name: str, default=False) -> DockerServerConfig | None:
200
- """Get config for a model name. Returns default if not registered."""
201
- if model_name not in self._registry:
202
- if default:
203
- return VLLMDockerServerConfig(model_name=model_name)
204
- return None
205
- return self._registry[model_name]()
218
+ """Get config for a model name (thread-safe). Returns default if not registered."""
219
+ with self._lock:
220
+ if model_name not in self._registry:
221
+ if default:
222
+ return VLLMDockerServerConfig(
223
+ model_name=model_name, default_model_name=DEFAULT_MODEL_NAME
224
+ )
225
+ return None
226
+ factory = self._registry[model_name]
227
+ return factory()
206
228
 
207
229
  def list_models(self) -> list[str]:
208
- """List all registered model names."""
209
- return list(self._registry.keys())
230
+ """List all registered model names (thread-safe)."""
231
+ with self._lock:
232
+ return list(self._registry.keys())
210
233
 
211
234
 
212
235
  # Global registry instance
@@ -0,0 +1,48 @@
1
+ """Model identity mixin for consistent model name handling between server and client configs."""
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class ModelIdentityMixin(BaseModel):
7
+ """Mixin providing model identity fields with validation.
8
+
9
+ This mixin ensures that model_name and default_model_name are consistently
10
+ passed from server configs to client configs.
11
+ """
12
+
13
+ model_name: str
14
+ default_model_name: str | None = None
15
+ aliases: list[str] = Field(default_factory=list)
16
+
17
+ def get_effective_model_name(self) -> str:
18
+ """Returns the model name to use for API calls."""
19
+ return self.default_model_name if self.default_model_name else self.model_name
20
+
21
+ def _create_client_kwargs(self, base_url: str) -> dict:
22
+ """Generate kwargs for client config with model identity.
23
+
24
+ Use this method in server configs to ensure consistent passing
25
+ of model_name and default_model_name to client configs.
26
+
27
+ Args:
28
+ base_url: The base URL for the client to connect to.
29
+
30
+ Returns:
31
+ Dictionary with base_url, model_name, and default_model_name.
32
+ """
33
+ return {
34
+ "base_url": base_url,
35
+ "model_name": self.model_name,
36
+ "default_model_name": self.get_effective_model_name(),
37
+ }
38
+
39
+ def get_all_names(self) -> list[str]:
40
+ """Get all names this model can be referenced by.
41
+
42
+ Returns:
43
+ List containing model_name, aliases, and short name (after last /).
44
+ """
45
+ names = [self.model_name] + self.aliases
46
+ if "/" in self.model_name:
47
+ names.append(self.model_name.split("/")[-1])
48
+ return [n for n in names if isinstance(n, str)]
vlmparse/servers/utils.py CHANGED
@@ -2,6 +2,7 @@ import getpass
2
2
  import time
3
3
  from contextlib import contextmanager
4
4
  from pathlib import Path
5
+ from urllib.parse import parse_qsl, urlparse
5
6
 
6
7
  import docker
7
8
  from loguru import logger
@@ -222,25 +223,52 @@ def docker_server(
222
223
  logger.info("Container stopped")
223
224
 
224
225
 
226
+ def normalize_uri(uri: str) -> tuple:
227
+ u = urlparse(uri)
228
+
229
+ # --- Normalize scheme ---
230
+ scheme = (u.scheme or "http").lower()
231
+
232
+ # --- Normalize host ---
233
+ host = (u.hostname or "").lower()
234
+ if host in ("localhost", "0.0.0.0"):
235
+ host = "localhost"
236
+
237
+ # --- Normalize port (apply defaults) ---
238
+ if u.port:
239
+ port = u.port
240
+ else:
241
+ port = 443 if scheme == "https" else 80
242
+
243
+ # --- Normalize path ---
244
+ # Treat empty path as "/" and remove trailing slash (except root)
245
+ path = u.path or "/"
246
+ if path != "/" and path.endswith("/"):
247
+ path = path.rstrip("/")
248
+
249
+ # Collapse duplicate slashes
250
+ while "//" in path:
251
+ path = path.replace("//", "/")
252
+
253
+ # --- Normalize query parameters (sorted) ---
254
+ query_pairs = parse_qsl(u.query, keep_blank_values=True)
255
+ query = "&".join(f"{k}={v}" for k, v in sorted(query_pairs))
256
+
257
+ return (scheme, host, port, path, query)
258
+
259
+
225
260
  def get_model_from_uri(uri: str) -> str:
226
261
  model = None
227
262
  client = docker.from_env()
228
263
  containers = client.containers.list()
264
+
265
+ uri = normalize_uri(uri)
266
+
229
267
  for container in containers:
230
268
  c_uri = container.labels.get("vlmparse_uri")
231
269
  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")
234
-
235
- # Check if user URI matches container URI (ignoring /v1 suffix if missing)
236
- if c_uri and (
237
- c_uri == uri or c_uri.startswith(uri.rstrip("/")) or uri.startswith(c_uri)
238
- ):
239
- # Update URI to the correct one from container (likely has /v1)
240
- if len(c_uri) > len(uri.rstrip("/")):
241
- logger.info(f"Updating URI from {uri} to {c_uri}")
242
- uri = c_uri
243
270
 
271
+ if c_uri and uri == normalize_uri(c_uri):
244
272
  # Infer model if not provided
245
273
  if model is None and c_model:
246
274
  logger.info(f"Inferred model {c_model} from container")
vlmparse/utils.py CHANGED
@@ -19,8 +19,19 @@ def from_base64(base64_str: str):
19
19
  return Image.open(BytesIO(image_data))
20
20
 
21
21
 
22
- def get_file_paths(inputs: str | list[str]):
23
- # Expand file paths from glob patterns
22
+ def get_file_paths(inputs: str | list[str], raise_on_empty: bool = False) -> list[str]:
23
+ """Expand file paths from glob patterns.
24
+
25
+ Args:
26
+ inputs: A string or list of strings containing file paths, glob patterns, or directories.
27
+ raise_on_empty: If True, raise FileNotFoundError when no files are found.
28
+
29
+ Returns:
30
+ List of valid file paths.
31
+
32
+ Raises:
33
+ FileNotFoundError: If raise_on_empty is True and no files are found.
34
+ """
24
35
  file_paths = []
25
36
  if isinstance(inputs, str):
26
37
  inputs = [inputs]
@@ -36,6 +47,8 @@ def get_file_paths(inputs: str | list[str]):
36
47
  file_paths = [f for f in file_paths if os.path.exists(f) and os.path.isfile(f)]
37
48
 
38
49
  if not file_paths:
50
+ if raise_on_empty:
51
+ raise FileNotFoundError("No files found matching the input patterns")
39
52
  logger.error("No PDF files found matching the inputs patterns")
40
53
 
41
54
  return file_paths
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vlmparse
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Requires-Python: >=3.11.0
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -54,6 +54,12 @@ Dynamic: license-file
54
54
 
55
55
  # vlmparse
56
56
 
57
+ <div align="center">
58
+
59
+ [\[📜 arXiv coming soon\]] | [[Dataset (🤗Hugging Face)]](https://huggingface.co/datasets/pulsia/fr-bench-pdf2md) | [[pypi]](https://pypi.org/project/vlmparse/) | [[vlmparse]](https://github.com/ld-lab-pulsia/vlmparse) | [[Benchmark]](https://github.com/ld-lab-pulsia/benchpdf2md)
60
+
61
+ </div>
62
+
57
63
  A unified wrapper for Vision Language Models (VLM) and OCR solutions to parse PDF documents into Markdown.
58
64
 
59
65
  Features:
@@ -209,3 +215,7 @@ with ConverterWithServer(model="mineru2.5") as converter_with_server:
209
215
  ```
210
216
 
211
217
  Note that if you pass an uri of a vllm server to `ConverterWithServer`, the model name is inferred automatically and no server is started.
218
+
219
+ ## Credits
220
+
221
+ This work was financed by La Poste and led by members of Probayes and OpenValue, two subsidiaries (filiales) of La Poste.
@@ -0,0 +1,38 @@
1
+ vlmparse/base_model.py,sha256=4U4UPe8SNArliKnUf8pp8zQugWYsnhg9okylt7mrW1U,381
2
+ vlmparse/build_doc.py,sha256=fb7awoqVN-6NBlKVkMFb1v1iTWcxne5QAyNaKYTyvM4,2275
3
+ vlmparse/cli.py,sha256=asew0JdpbgFZrZqnG-Bqh5A_DrXcP0XomLB3y3AgG6Y,12855
4
+ vlmparse/constants.py,sha256=DYaK7KtTW8p9MPb3iPvoP5H1r7ICRuIFo89P01q4uCI,184
5
+ vlmparse/converter.py,sha256=KKcXqrp3nJo3d7DXjHn3O2SklbsJ489rDY4NJ9O42Fs,8795
6
+ vlmparse/converter_with_server.py,sha256=A84l3YNal-hs2mMlER1sB29rddsO8MNOP2j9ts0ujtE,7280
7
+ vlmparse/registries.py,sha256=B4kxibP7XYbhL9bZ5gn21LQCPhHCYftAM4i0-xD9fRs,6469
8
+ vlmparse/utils.py,sha256=6Ff9OfAIVR-4_37QD5sifoNt_GmB3YUqgFwmIjuemtc,1727
9
+ vlmparse/clients/chandra.py,sha256=zAHjgI_MJ5FVGANHCG8KJQByaw6-zTS6CHXsCBA8TJI,13025
10
+ vlmparse/clients/deepseekocr.py,sha256=pKdNJD9v86BRn7YrXE6PGk_jQxnbZ_6UjgSUxgd3Su4,6859
11
+ vlmparse/clients/docling.py,sha256=BLtNAxVJR6qvPip4ZBP-se8IMNFSbJ-fWEGlTSwimK8,5310
12
+ vlmparse/clients/dotsocr.py,sha256=oAUzDMTObeW0sTy5sFl08O6GQPSTic5ITbJYh_45Z54,10414
13
+ vlmparse/clients/granite_docling.py,sha256=KYaEdgk3oD0TuYDKqTQ4o6IkXC-E3AIYJ2KYxnEsjWM,3595
14
+ vlmparse/clients/hunyuanocr.py,sha256=etpIiA28OoGW-o5pOGeBxOlUDjUQ4zcKXWnJ8ba44DU,1979
15
+ vlmparse/clients/lightonocr.py,sha256=ZWC12U6myDr_2EuOPYGyJYxpBachjOUtLrxS62A8mzg,2048
16
+ vlmparse/clients/mineru.py,sha256=9r6_JwCGB6-C-YKpoadUs7lSuDEJyBFkfjWV5WN-VrE,3599
17
+ vlmparse/clients/mistral_converter.py,sha256=_hEyK_2vM5LEwbt30bFodMrWJtavLsBDxCkVclNUF4M,2837
18
+ vlmparse/clients/nanonetocr.py,sha256=gTbD4OtuHiWd6Ack6Bx-anZM9P_aErfSHXwtymETvqM,1665
19
+ vlmparse/clients/olmocr.py,sha256=V4638WftLCTr5Q6ZRgWKKSPAhFYdpBw3izeuda6EKDQ,1966
20
+ vlmparse/clients/openai_converter.py,sha256=bckm33Pkvqul--DjfEEEI3evn4_va0CoQcigdpCCMGc,7746
21
+ vlmparse/clients/paddleocrvl.py,sha256=q3AgEWj0UyXGpSEVZISdfqv2PV_qY-uF498bL8U1tpg,1596
22
+ vlmparse/clients/prompts.py,sha256=-J60lqxgRzlkQ9VsQLxmWsIMaDt-gNqWqWoqHIw9CLc,4228
23
+ vlmparse/clients/pipe_utils/cleaner.py,sha256=oxBkBTOkluN1lmeNbzajRIe0_D__ZGwUOBaI_Ph0uxE,2396
24
+ vlmparse/clients/pipe_utils/html_to_md_conversion.py,sha256=cFFqzD2jCNw_968_eu3Wt--Ox7iJj2Rn5UoP_DZWosU,4112
25
+ vlmparse/clients/pipe_utils/utils.py,sha256=935ecIO446I0pstszE_1nrIPHn1Ffrxunq7fVd0dsd8,315
26
+ vlmparse/data_model/box.py,sha256=lJsh4qhjgYXZF5vTSJ1qMXD5GVlBi2_SBedBMlfJikU,16868
27
+ vlmparse/data_model/document.py,sha256=xheaMeStOj2c9GZKmdtxcEl_Dj44V5JyVp6JnTrSpH0,4615
28
+ vlmparse/servers/docker_server.py,sha256=FOIHU0_CDfyZ9UA285BrnUFuEMJRxbu-OzlByBa-P9s,7951
29
+ vlmparse/servers/model_identity.py,sha256=DkH7KQAAZA9Sn7eJEnaKfH54XSEI17aqD1ScqqkTBEk,1711
30
+ vlmparse/servers/utils.py,sha256=tIXhgbF9EVOJy2nYEguVq69gn9ATxtya_1F4wZSt68o,9454
31
+ vlmparse/st_viewer/fs_nav.py,sha256=7GNH68h2Loh5pQ64Pe72-D2cs2BLhqRXevEmKdFmPX0,1616
32
+ vlmparse/st_viewer/st_viewer.py,sha256=m2rQTtk5rlwErNmivNAg-4rkHkvNkvLhoJZxFQi7Dwk,2105
33
+ vlmparse-0.1.8.dist-info/licenses/LICENSE,sha256=3TKJHk8hPBR5dbLWZ3IpfCftl-_m-iyBwpYQGZYxj14,1080
34
+ vlmparse-0.1.8.dist-info/METADATA,sha256=dwu5tiTLuhVMYL-ZQCMNYW_MNlJu84V2us0aeRfrSpU,6048
35
+ vlmparse-0.1.8.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
36
+ vlmparse-0.1.8.dist-info/entry_points.txt,sha256=gD5berP6HwE2wNIkls-Lw5goiceA8uMgPEd7ifnFJXs,47
37
+ vlmparse-0.1.8.dist-info/top_level.txt,sha256=k4ni-GNH_iAX7liQEsk_KY_c3xgZgt8k9fsSs9IXLXs,9
38
+ vlmparse-0.1.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,36 +0,0 @@
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,,