HowdenParser 0.1.12__tar.gz → 0.1.13__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.
@@ -0,0 +1,5 @@
1
+ from typing import Literal
2
+ from pydantic import BaseModel
3
+
4
+ class Parameter(BaseModel):
5
+ provider_and_model: Literal["mistralocr:mistral-ocr-latest"] = "mistralocr:mistral-ocr-latest"
@@ -3,6 +3,7 @@ from dotenv import load_dotenv
3
3
  import os
4
4
  from pathlib import Path
5
5
  import logging
6
+ from PyPDF2 import PdfReader
6
7
 
7
8
  load_dotenv()
8
9
 
@@ -13,14 +14,17 @@ class BaseParser(ABC):
13
14
 
14
15
 
15
16
  class MistralOCRParser(BaseParser):
16
- def __init__(self, result_type: str, **kwargs) -> None:
17
+ def __init__(self, model: str) -> None:
17
18
  from mistralai import Mistral
19
+ self.model = model
20
+ self.current_cost: float = 0.0
21
+ self.total_cost_euro: float = 0.0
22
+
18
23
  name = "MISTRAL-OCR-API-TOKEN"
19
24
  api_key = os.getenv(name)
20
25
  if not api_key:
21
26
  raise EnvironmentError(f"Missing {name} in .env file.")
22
27
 
23
- self.result_type = "md" if result_type.lower() in ("md", "markdown") else "text"
24
28
  self.client = Mistral(api_key=api_key)
25
29
 
26
30
  def parse(self, file_path: Path) -> str:
@@ -36,7 +40,7 @@ class MistralOCRParser(BaseParser):
36
40
  return signed_url.url
37
41
 
38
42
  ocr_response = self.client.ocr.process(
39
- model="mistral-ocr-latest",
43
+ model=self.model,
40
44
  document={
41
45
  "type": "document_url",
42
46
  "document_url": upload_pdf(file_path),
@@ -44,14 +48,23 @@ class MistralOCRParser(BaseParser):
44
48
  include_image_base64=True,
45
49
  )
46
50
 
51
+ self.current_cost = 1/1000 * self._count_pages(file_path)
52
+ self.total_cost_euro += self.current_cost
53
+
47
54
  return "\n".join(doc.markdown for doc in ocr_response.pages)
48
55
 
56
+ @staticmethod
57
+ def _count_pages(file_path: Path) -> int:
58
+ reader = PdfReader(str(file_path))
59
+ return len(reader.pages)
60
+
61
+
49
62
 
50
63
  class LangChainParser(BaseParser):
51
- def __init__(self, model_name: str):
64
+ def __init__(self, model: str):
52
65
  from langchain.llms import OpenAI
53
- self.model_name = model_name
54
- self.model = OpenAI(model_name=model_name)
66
+ self.model_name = model
67
+ self.model = OpenAI(model_name=model)
55
68
 
56
69
  def parse(self, text: str) -> dict:
57
70
  response = self.model(text)
@@ -89,7 +102,7 @@ class LlamaParser(BaseParser):
89
102
  return text
90
103
 
91
104
  class HuggingFaceParser(BaseParser):
92
- def __init__(self, result_type: str, mode: bool, **kwargs) -> None:
105
+ def __init__(self, model: str, result_type: str) -> None:
93
106
  from transformers import pipeline
94
107
 
95
108
  if result_type.lower() in ("md", "markdown"):
@@ -102,16 +115,15 @@ class HuggingFaceParser(BaseParser):
102
115
  if not self.api_key:
103
116
  raise EnvironmentError(f"Missing {name} in .env file.")
104
117
 
105
- # OCR + text extraction pipeline
106
118
  # Example model: microsoft/layoutlmv3-base-finetuned-docvqa
107
119
  self.parser = pipeline(
108
120
  task="document-question-answering",
109
- model="impira/layoutlm-document-qa",
121
+ model=model,
110
122
  use_auth_token=self.api_key
111
123
  )
112
124
 
113
125
  def parse(self, file_path: Path) -> str:
114
- import fitz # PyMuPDF for PDF → images
126
+ import fitz
115
127
 
116
128
  pdf_doc = fitz.open(file_path)
117
129
  output_parts = []
@@ -124,7 +136,6 @@ class HuggingFaceParser(BaseParser):
124
136
  output_parts.append(response[0]["answer"])
125
137
 
126
138
  if self.result_type == "markdown":
127
- # Here you could add rules to format into markdown
128
139
  return "\n\n".join(output_parts)
129
140
  else:
130
141
  return " ".join(output_parts)
@@ -132,17 +143,17 @@ class HuggingFaceParser(BaseParser):
132
143
  # === Step 3: Dynamic factory using string input ===
133
144
  class ParserFactory:
134
145
  @staticmethod
135
- def get_parser(parser_type: str, **kwargs) -> BaseParser:
136
- provider = parser_type.partition(":")[0].lower()
137
- model = parser_type.partition(":")[2]
146
+ def get_parser(provider_model: str, **kwargs) -> BaseParser:
147
+ provider = provider_model.partition(":")[0].lower()
148
+ model = provider_model.partition(":")[2]
138
149
  if provider == "langchain":
139
- return LangChainParser(model_name=model)
150
+ return LangChainParser(model=model)
140
151
  elif provider == "llamaparser":
141
152
  return LlamaParser(kwargs["result_type"], kwargs["mode"])
142
153
  elif provider == "huggingface":
143
- return HuggingFaceParser(model_name=model, **kwargs)
154
+ return HuggingFaceParser(model=model, **kwargs)
144
155
  elif provider == "mistralocr":
145
- return MistralOCRParser(**kwargs)
156
+ return MistralOCRParser(model)
146
157
  else:
147
- raise ValueError(f"Unknown parser type: {parser_type}")
158
+ raise ValueError(f"Unknown parser type: {provider_model}")
148
159
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: HowdenParser
3
- Version: 0.1.12
3
+ Version: 0.1.13
4
4
  Summary: A simple configuration manager with Pydantic and JSON export.
5
5
  License: MIT
6
6
  Keywords: config,configuration,pydantic,json
@@ -16,6 +16,7 @@ Requires-Dist: howdenconfig (>=0.1.13,<0.2.0)
16
16
  Requires-Dist: langchain (>=0.3.27,<0.4.0)
17
17
  Requires-Dist: llama-parse (>=0.6.58,<0.7.0)
18
18
  Requires-Dist: mistralai (>=1.9.3,<2.0.0)
19
+ Requires-Dist: pypdf2 (>=3.0.1,<4.0.0)
19
20
  Requires-Dist: transformers (>=4.55.2,<5.0.0)
20
21
  Project-URL: Documentation, https://github.com/yourusername/config
21
22
  Project-URL: Homepage, https://github.com/yourusername/config
@@ -3,7 +3,7 @@ name = "HowdenParser"
3
3
  description = ""
4
4
  readme = "README.md"
5
5
  requires-python = ">=3.12,<4.0"
6
- dependencies = [ "mistralai (>=1.9.3,<2.0.0)", "llama-parse (>=0.6.58,<0.7.0)", "langchain (>=0.3.27,<0.4.0)", "transformers (>=4.55.2,<5.0.0)", "fitz (>=0.0.1.dev2,<0.0.2)", "howdenconfig (>=0.1.13,<0.2.0)",]
6
+ dependencies = [ "mistralai (>=1.9.3,<2.0.0)", "llama-parse (>=0.6.58,<0.7.0)", "langchain (>=0.3.27,<0.4.0)", "transformers (>=4.55.2,<5.0.0)", "fitz (>=0.0.1.dev2,<0.0.2)", "howdenconfig (>=0.1.13,<0.2.0)", "pypdf2 (>=3.0.1,<4.0.0)",]
7
7
  [[project.authors]]
8
8
  name = "JesperThoftIllemannJ"
9
9
  email = "jesper.jaeger@howdendanmark.dk"
@@ -14,7 +14,7 @@ build-backend = "poetry.core.masonry.api"
14
14
 
15
15
  [tool.poetry]
16
16
  name = "HowdenParser"
17
- version = "0.1.12"
17
+ version = "0.1.13"
18
18
  description = "A simple configuration manager with Pydantic and JSON export."
19
19
  authors = [ "JesperThoftIllemannJ <jesper.jaeger@howdendanmark.dk>",]
20
20
  readme = "README.md"
@@ -1,7 +0,0 @@
1
- from typing import Literal
2
- from pydantic import BaseModel
3
-
4
- class Parameter(BaseModel):
5
- model: str = "mistralocr:"
6
- result_type: Literal["md"] = "md"
7
- mode: bool = False
File without changes