HowdenParser 4.2.0__tar.gz → 5.1.0__tar.gz

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.
@@ -57,7 +57,8 @@ class Parser(BaseParser):
57
57
  *,
58
58
  provider_and_model: Literal["llamaparser:"],
59
59
  result_type: str,
60
- mode: bool,
60
+ model: str,
61
+ parse_mode: str,
61
62
  preserve_layout_alignment_across_pages: bool,
62
63
  merge_tables_across_pages_in_markdown: bool,
63
64
  hide_footers: bool,
@@ -148,7 +149,7 @@ class Parser(BaseParser):
148
149
  if missing:
149
150
  example = ""
150
151
  if provider == "llamaparser":
151
- example = "Example: Parser('llamaparser:', result_type='md', mode=True, extract_tables=True)"
152
+ example = "Example: Parser('llamaparser:', result_type='md', mode=True, extract_tables=True, parse_mode='parse_page_with_agent', model='anthropic-sonnet-4.5)"
152
153
  elif provider == "mistralocr":
153
154
  example = "Example: Parser('mistralocr:ocr-large')"
154
155
  elif provider == "langchain":
@@ -0,0 +1,81 @@
1
+ import os
2
+ import logging
3
+ from pathlib import Path
4
+ from ..parser import BaseParser
5
+
6
+ class LlamaParser(BaseParser, name="llamaparser"):
7
+ def __init__(self, result_type: str, model: str, parse_mode: str, provider_and_model: str,
8
+ merge_tables_across_pages_in_markdown: bool, preserve_layout_alignment_across_pages: bool,
9
+ hide_footers: bool, hide_headers: bool) -> None:
10
+
11
+ super().__init__()
12
+ logging.info("Configuring LlamaParser (lazy init enabled)...")
13
+
14
+ # Store configuration only
15
+ self.result_type = result_type
16
+ self.model = model
17
+ self.parse_mode = parse_mode
18
+ self.provider_and_model = provider_and_model
19
+ self.merge_tables_across_pages_in_markdown = merge_tables_across_pages_in_markdown
20
+ self.preserve_layout_alignment_across_pages = preserve_layout_alignment_across_pages
21
+ self.hide_footers = hide_footers
22
+ self.hide_headers = hide_headers
23
+
24
+ # DO NOT CREATE LlamaParse HERE
25
+ # It creates asyncio objects bound to the wrong loop
26
+ self._parser = None
27
+
28
+ def _lazy_init(self):
29
+ """Initialize LlamaParse inside the worker thread event loop."""
30
+ if self._parser is not None:
31
+ return
32
+
33
+ from llama_parse import LlamaParse, ResultType
34
+
35
+ api_key = os.getenv("LLAMA-PARSER-API-TOKEN")
36
+ if not api_key:
37
+ raise EnvironmentError("Missing LLAMA-PARSER-API-TOKEN in .env file.")
38
+
39
+ rt = self.result_type
40
+ if rt.lower() in ("md", "markdown"):
41
+ rt = ResultType.MD
42
+
43
+ # Construct the parser INSIDE the worker thread
44
+ self._parser = LlamaParse(
45
+ api_key=api_key,
46
+ result_type=rt,
47
+ model=self.model,
48
+ parse_mode=self.parse_mode,
49
+ merge_tables_across_pages_in_markdown=self.merge_tables_across_pages_in_markdown,
50
+ preserve_layout_alignment_across_pages=self.preserve_layout_alignment_across_pages,
51
+ hide_footers=self.hide_footers,
52
+ hide_headers=self.hide_headers,
53
+ )
54
+
55
+ logging.info("LlamaParser initialized inside worker thread")
56
+
57
+ def parse(self, file_path: Path, include_pagenumbers: bool = False) -> str:
58
+ # Ensure parser is created inside the thread event loop
59
+ self._lazy_init()
60
+
61
+ # Standard calls
62
+ if not include_pagenumbers:
63
+ documents = self._parser.load_data(str(file_path))
64
+ return "\n".join(doc.text for doc in documents)
65
+
66
+ # With page numbers
67
+ documents = self._parser.parse(file_path)
68
+
69
+ if self.result_type.lower() in ("md", "markdown"):
70
+ return "\n".join(
71
+ f"<PAGE_NUMBER {idx}>{page.md}</PAGE_NUMBER {idx}>"
72
+ for idx, page in enumerate(documents.pages, start=1)
73
+ )
74
+
75
+ return "\n".join(
76
+ f"<PAGE_NUMBER {idx}>{page.text}</PAGE_NUMBER {idx}>"
77
+ for idx, page in enumerate(documents.pages, start=1)
78
+ )
79
+
80
+ def __call__(self, file_path: Path) -> str:
81
+ return self.parse(file_path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: HowdenParser
3
- Version: 4.2.0
3
+ Version: 5.1.0
4
4
  Summary: A simple configuration manager with Pydantic and JSON export.
5
5
  License: MIT
6
6
  Keywords: config,configuration,pydantic,json
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "HowdenParser"
3
- version = "4.2.0"
3
+ version = "5.1.0"
4
4
  description = "A simple configuration manager with Pydantic and JSON export."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12,<3.14"
@@ -1,61 +0,0 @@
1
- import os
2
- import logging
3
- from pathlib import Path
4
- from ..parser import BaseParser
5
-
6
- class LlamaParser(BaseParser, name="llamaparser"):
7
- def __init__(self, result_type: str,
8
- mode: bool,
9
- provider_and_model: str,
10
- merge_tables_across_pages_in_markdown: bool,
11
- preserve_layout_alignment_across_pages: bool,
12
- hide_footers: bool,
13
- hide_headers: bool
14
- ) -> None:
15
- logging.info("Initializing LlamaParser...")
16
- self.result_type = result_type
17
- self.mode = mode
18
- self.provider_and_model = provider_and_model
19
- self.merge_tables_across_pages_in_markdown = merge_tables_across_pages_in_markdown
20
- self.preserve_layout_alignment_across_pages = preserve_layout_alignment_across_pages
21
- self.hide_footers=hide_footers
22
- self.hide_headers=hide_headers
23
-
24
- from llama_parse import LlamaParse, ResultType
25
- if result_type.lower() in ("md", "markdown"):
26
- result_type = ResultType.MD
27
- api_key = os.getenv("LLAMA-PARSER-API-TOKEN")
28
- if not api_key:
29
- raise EnvironmentError("Missing LLAMA-PARSER-API-TOKEN in .env file.")
30
- self._parser = LlamaParse(api_key=api_key,
31
- result_type=result_type,
32
- premium_mode=self.mode,
33
- merge_tables_across_pages_in_markdown=self.merge_tables_across_pages_in_markdown,
34
- preserve_layout_alignment_across_pages=self.preserve_layout_alignment_across_pages,
35
- hide_footers=self.hide_footers,
36
- hide_headers=self.hide_headers)
37
-
38
- def parse(self, file_path: Path, include_pagenumbers: bool=False) -> str:
39
- """
40
- Parse the document at file_path.
41
- Args:
42
- file_path (Path): Path to the document to be parsed.
43
- include_pagenumbers (bool): Whether to include page numbers in the output. If True, page numbers will be wrapped around each page's content, like so: <PAGE_NUMBER 1>...content...</PAGE_NUMBER 1>
44
- """
45
-
46
- if not include_pagenumbers:
47
- documents = self._parser.load_data(str(file_path))
48
-
49
- result = "\n".join(doc.text for doc in documents)
50
- else:
51
- documents = self._parser.parse(file_path)
52
-
53
- if self.result_type.lower() in ("md", "markdown"):
54
- result = "\n".join(f"<PAGE_NUMBER {idx}>{page.md}</PAGE_NUMBER {idx}>" for idx, page in enumerate(documents.pages, start=1))
55
- else:
56
- result = "\n".join(f"<PAGE_NUMBER {idx}>{page.text}</PAGE_NUMBER {idx}>" for idx, page in enumerate(documents.pages, start=1))
57
-
58
- return result
59
-
60
- def __call__(self, file_path: Path) -> str:
61
- return self.parse(file_path)
File without changes