mb-rag 1.0.117__py3-none-any.whl → 1.0.124__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.

Potentially problematic release.


This version of mb-rag might be problematic. Click here for more details.

@@ -1,96 +1,223 @@
1
- import os
2
- import importlib.util
3
- from mb_rag.chatbot.basic import get_chatbot_google_generative_ai
1
+ """
2
+ Bounding box utilities
3
+ """
4
4
 
5
- __all__ = [ "generate_bounding_box", "add_bounding_box"]
5
+ import os
6
+ from typing import List, Dict, Any, Optional, Tuple, Union
7
+ from dataclasses import dataclass
8
+ from mb_rag.utils.extra import check_package
6
9
 
10
+ __all__ = ['BoundingBoxConfig', 'BoundingBoxProcessor']
7
11
 
8
- def check_package(package_name):
12
+ def check_image_dependencies() -> None:
9
13
  """
10
- Check if a package is installed
11
- Args:
12
- package_name (str): Name of the package
13
- Returns:
14
- bool: True if package is installed, False otherwise
14
+ Check if required image processing packages are installed
15
+ Raises:
16
+ ImportError: If any required package is missing
15
17
  """
16
- return importlib.util.find_spec(package_name) is not None
18
+ if not check_package("PIL"):
19
+ raise ImportError("Pillow package not found. Please install it using: pip install Pillow")
20
+ if not check_package("cv2"):
21
+ raise ImportError("OpenCV package not found. Please install it using: pip install opencv-python")
22
+ if not check_package("google.generativeai"):
23
+ raise ImportError("Google Generative AI package not found. Please install it using: pip install google-generativeai")
17
24
 
25
+ @dataclass
26
+ class BoundingBoxConfig:
27
+ """Configuration for bounding box operations"""
28
+ model_name: str = "gemini-1.5-pro-latest"
29
+ api_key: Optional[str] = None
30
+ default_prompt: str = 'Return bounding boxes of container, for each only one return [ymin, xmin, ymax, xmax]'
18
31
 
19
- def generate_bounding_box(image_path: str,model_name: str = "gemini-1.5-flash", prompt: str = 'Return bounding boxes of container, for each only one return [ymin, xmin, ymax, xmax]'):
32
+ class BoundingBoxProcessor:
20
33
  """
21
- Function to generate bounding boxes
22
- Args:
23
- image_path (str): Image path
24
- model_name (GenerativeModel): GenerativeModel object - google model (Default: )
25
- prompt (str): Prompt
26
- Returns:
27
- res (str): Result
28
- Raises:
29
- FileNotFoundError: If image file doesn't exist
30
- ValueError: If model is None or invalid
31
- """
32
- try:
33
- model = get_chatbot_google_generative_ai(model_name)
34
- except Exception as e:
35
- raise ValueError(f"Error initializing model: {str(e)}")
36
-
37
- if not os.path.exists(image_path):
38
- raise FileNotFoundError(f"Image file not found: {image_path}")
34
+ Class for processing images and generating bounding boxes
39
35
 
40
- try:
41
- if not check_package('PIL'):
42
- raise ImportError("PIL package not found. Please install it using: pip install pillow")
43
- from PIL import Image
36
+ Attributes:
37
+ model: The Google Generative AI model instance
38
+ config: Configuration for bounding box operations
39
+ """
44
40
 
45
- image = Image.open(image_path)
46
- res = model.generate_content([image, prompt])
47
- return res
48
- except Exception as e:
49
- raise ValueError(f"Error generating bounding boxes: {str(e)}")
41
+ def __init__(self, config: Optional[BoundingBoxConfig] = None, **kwargs):
42
+ """
43
+ Initialize bounding box processor
44
+ Args:
45
+ config: Configuration for the processor
46
+ **kwargs: Additional arguments
47
+ """
48
+ check_image_dependencies()
49
+ self.config = config or BoundingBoxConfig(**kwargs)
50
+ self._initialize_model()
51
+ self._initialize_image_libs()
50
52
 
51
- def add_bounding_box(image_path: str, bounding_box: list, show: bool = False):
52
- """
53
- Function to add bounding box to image
54
- Args:
55
- image_path (str): Image path
56
- bounding_box (list): Bounding boxes
57
- show (bool): Whether to display the image
58
- Returns:
59
- image (Image): Image with bounding box
60
- Raises:
61
- FileNotFoundError: If image file doesn't exist
62
- ValueError: If bounding box format is invalid
63
- """
64
- if not os.path.exists(image_path):
65
- raise FileNotFoundError(f"Image file not found: {image_path}")
66
-
67
- if not isinstance(bounding_box, list):
68
- raise ValueError("bounding_box must be a list of bounding box coordinates with keys as labels and values as [ymin, xmin, ymax, xmax]")
69
-
70
- try:
71
- if not check_package('cv2'):
72
- raise ImportError("cv2 package not found. Please install it using: pip install opencv-python")
53
+ @classmethod
54
+ def from_model(cls, model_name: str, api_key: Optional[str] = None, **kwargs) -> 'BoundingBoxProcessor':
55
+ """
56
+ Create processor with specific model configuration
57
+ Args:
58
+ model_name: Name of the model
59
+ api_key: Optional API key
60
+ **kwargs: Additional configuration
61
+ Returns:
62
+ BoundingBoxProcessor: Configured processor
63
+ """
64
+ config = BoundingBoxConfig(
65
+ model_name=model_name,
66
+ api_key=api_key
67
+ )
68
+ return cls(config, **kwargs)
69
+
70
+ def _initialize_model(self) -> None:
71
+ """Initialize the AI model"""
72
+ import google.generativeai as genai
73
+
74
+ api_key = self.config.api_key or os.environ.get("GOOGLE_API_KEY")
75
+ if not api_key:
76
+ raise ValueError("Google API key not found. Please provide api_key parameter or set GOOGLE_API_KEY environment variable.")
77
+
78
+ try:
79
+ genai.configure(api_key=api_key)
80
+ self.model = genai.GenerativeModel(model_name=self.config.model_name)
81
+ except Exception as e:
82
+ raise ValueError(f"Error initializing Google Generative AI model: {str(e)}")
83
+
84
+ def _initialize_image_libs(self) -> None:
85
+ """Initialize image processing libraries"""
86
+ from PIL import Image
73
87
  import cv2
74
- img = cv2.imread(image_path)
75
- if img is None:
76
- raise ValueError(f"Failed to load image: {image_path}")
88
+ self._Image = Image
89
+ self._cv2 = cv2
90
+
91
+ @staticmethod
92
+ def _validate_image_path(image_path: str) -> None:
93
+ """
94
+ Validate image path
95
+ Args:
96
+ image_path: Path to image
97
+ Raises:
98
+ FileNotFoundError: If image doesn't exist
99
+ """
100
+ if not os.path.exists(image_path):
101
+ raise FileNotFoundError(f"Image file not found: {image_path}")
102
+
103
+ def generate_bounding_boxes(self,
104
+ image_path: str,
105
+ prompt: Optional[str] = None) -> Any:
106
+ """
107
+ Generate bounding boxes for an image
108
+ Args:
109
+ image_path: Path to image
110
+ prompt: Custom prompt for the model
111
+ Returns:
112
+ Any: Model response with bounding boxes
113
+ """
114
+ self._validate_image_path(image_path)
77
115
 
116
+ try:
117
+ image = self._Image.open(image_path)
118
+ prompt = prompt or self.config.default_prompt
119
+ return self.model.generate_content([image, prompt])
120
+ except Exception as e:
121
+ raise ValueError(f"Error generating bounding boxes: {str(e)}")
78
122
 
79
- for box in bounding_box:
80
- if not isinstance(box, dict):
81
- raise ValueError("bounding_box must be a list of bounding box coordinates with keys as labels and values as [ymin, xmin, ymax, xmax]")
82
- for key, value in box.items():
123
+ def add_bounding_boxes(self,
124
+ image_path: str,
125
+ bounding_boxes: Dict[str, List[int]],
126
+ color: Tuple[int, int, int] = (0, 0, 255),
127
+ thickness: int = 4,
128
+ font_scale: float = 1.0,
129
+ show: bool = False) -> Any:
130
+ """
131
+ Add bounding boxes to an image
132
+ Args:
133
+ image_path: Path to image
134
+ bounding_boxes: Dictionary of bounding boxes
135
+ color: BGR color tuple
136
+ thickness: Line thickness
137
+ font_scale: Font scale for labels
138
+ show: Whether to display the image
139
+ Returns:
140
+ Any: Image with bounding boxes
141
+ """
142
+ self._validate_image_path(image_path)
143
+
144
+ if not isinstance(bounding_boxes, dict):
145
+ raise ValueError("bounding_boxes must be a dictionary")
146
+
147
+ try:
148
+ img = self._cv2.imread(image_path)
149
+ if img is None:
150
+ raise ValueError(f"Failed to load image: {image_path}")
151
+
152
+ for key, value in bounding_boxes.items():
83
153
  if not isinstance(value, list) or len(value) != 4:
84
154
  raise ValueError(f"Invalid bounding box format for key {key}. Expected [ymin, xmin, ymax, xmax]")
155
+
156
+ self._cv2.rectangle(
157
+ img=img,
158
+ pt1=(value[1], value[0]), # xmin, ymin
159
+ pt2=(value[3], value[2]), # xmax, ymax
160
+ color=color,
161
+ thickness=thickness
162
+ )
163
+ self._cv2.putText(
164
+ img=img,
165
+ text=key,
166
+ org=(value[1], value[0]),
167
+ fontFace=self._cv2.FONT_HERSHEY_SIMPLEX,
168
+ fontScale=font_scale,
169
+ color=color,
170
+ thickness=thickness//2
171
+ )
172
+
173
+ if show:
174
+ self._display_image(img)
85
175
 
86
- cv2.rectangle(img, (value[1], value[0]), (value[3], value[2]), (0, 0, 255), 4)
87
- cv2.putText(img, key, (value[1], value[0]), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
176
+ return img
177
+ except Exception as e:
178
+ raise ValueError(f"Error adding bounding boxes to image: {str(e)}")
179
+
180
+ def _display_image(self, img: Any) -> None:
181
+ """
182
+ Display an image
183
+ Args:
184
+ img: Image to display
185
+ """
186
+ self._cv2.imshow("Image", img)
187
+ self._cv2.waitKey(0)
188
+ self._cv2.destroyAllWindows()
189
+
190
+ def save_image(self, img: Any, output_path: str) -> None:
191
+ """
192
+ Save an image
193
+ Args:
194
+ img: Image to save
195
+ output_path: Path to save the image
196
+ """
197
+ try:
198
+ self._cv2.imwrite(output_path, img)
199
+ except Exception as e:
200
+ raise ValueError(f"Error saving image: {str(e)}")
201
+
202
+ def process_image(self,
203
+ image_path: str,
204
+ output_path: Optional[str] = None,
205
+ show: bool = False,
206
+ **kwargs) -> Any:
207
+ """
208
+ Complete image processing pipeline
209
+ Args:
210
+ image_path: Path to input image
211
+ output_path: Optional path to save output
212
+ show: Whether to display the result
213
+ **kwargs: Additional arguments for bounding box generation
214
+ Returns:
215
+ Any: Processed image
216
+ """
217
+ boxes = self.generate_bounding_boxes(image_path, **kwargs)
218
+ img = self.add_bounding_boxes(image_path, boxes, show=show)
88
219
 
89
- if show:
90
- cv2.imshow("Image", img)
91
- cv2.waitKey(0)
92
- cv2.destroyAllWindows()
220
+ if output_path:
221
+ self.save_image(img, output_path)
93
222
 
94
223
  return img
95
- except Exception as e:
96
- raise ValueError(f"Error adding bounding box to image: {str(e)}")
mb_rag/utils/extra.py CHANGED
@@ -4,7 +4,7 @@ import os
4
4
  from dotenv import load_dotenv
5
5
  import importlib.util
6
6
 
7
- __all__ = ["load_env_file"]
7
+ __all__ = ["load_env_file", "check_package", "pdf_to_text", "convert_pdfs_in_folder"]
8
8
 
9
9
  def load_env_file(file_path='.env'):
10
10
  """
mb_rag/version.py CHANGED
@@ -1,5 +1,5 @@
1
1
  MAJOR_VERSION = 1
2
2
  MINOR_VERSION = 0
3
- PATCH_VERSION = 117
3
+ PATCH_VERSION = 124
4
4
  version = '{}.{}.{}'.format(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION)
5
5
  __all__ = ['MAJOR_VERSION', 'MINOR_VERSION', 'PATCH_VERSION', 'version']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mb_rag
3
- Version: 1.0.117
3
+ Version: 1.0.124
4
4
  Summary: RAG function file
5
5
  Author: ['Malav Bateriwala']
6
6
  Requires-Python: >=3.8
@@ -0,0 +1,15 @@
1
+ mb_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ mb_rag/version.py,sha256=g3pkzzTRM6lWK4_vY_dwd2hYFDmXrp2VRW8Uj2krk4k,208
3
+ mb_rag/chatbot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ mb_rag/chatbot/basic.py,sha256=OR2IvDg-Sy968C2Mna6lxmFfh7Czj8yCEkCfyvtxBwI,14223
5
+ mb_rag/chatbot/chains.py,sha256=vDbLX5R29sWN1pcFqJ5fyxJEgMCM81JAikunAEvMC9A,7223
6
+ mb_rag/chatbot/prompts.py,sha256=n1PyiLbU-5fkslRv6aVOzt0dDlwya_cEdQ7kRnRhMuY,1749
7
+ mb_rag/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ mb_rag/rag/embeddings.py,sha256=kOnHjrbi0GRVErfcjML8fZz-KttipObUfa5fW9tGOoY,21196
9
+ mb_rag/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ mb_rag/utils/bounding_box.py,sha256=XnuhnLrsGvsI8P8VtOwlBrDlFE2It1HEZOcLlK6kusE,7931
11
+ mb_rag/utils/extra.py,sha256=spbFrGgdruNyYQ5PzgvpSIa6Nm0rn9bb4qc8W9g582o,2492
12
+ mb_rag-1.0.124.dist-info/METADATA,sha256=XyQ055JYBEiv5OU8m9FBhcOnHCoipo69LbnMgSa4bmM,154
13
+ mb_rag-1.0.124.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
14
+ mb_rag-1.0.124.dist-info/top_level.txt,sha256=FIK1eAa5uYnurgXZquBG-s3PIy-HDTC5yJBW4lTH_pM,7
15
+ mb_rag-1.0.124.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- mb_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- mb_rag/version.py,sha256=gwipOtP0TZlqdg5Rg1j43hyxg2GzlRZ0U9N3VPUDxNE,208
3
- mb_rag/chatbot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- mb_rag/chatbot/basic.py,sha256=AEcgMrXcH-QsCdoykqqgRJsS2-ZOEmxJuj2nd5KgcgI,13804
5
- mb_rag/chatbot/chains.py,sha256=KwdvAgI3DosSLgXGsm6fxeOKPYSbwy1mHH4ZIlOfTZY,8355
6
- mb_rag/chatbot/prompts.py,sha256=n1PyiLbU-5fkslRv6aVOzt0dDlwya_cEdQ7kRnRhMuY,1749
7
- mb_rag/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- mb_rag/rag/embeddings.py,sha256=kOnHjrbi0GRVErfcjML8fZz-KttipObUfa5fW9tGOoY,21196
9
- mb_rag/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- mb_rag/utils/bounding_box.py,sha256=PLfP_wSFkfNRu1uOu-1YIAQh93cuUHIkpFj77M4GaNk,3676
11
- mb_rag/utils/extra.py,sha256=qgaFsybeonT6XAFNfAU5h24FimDb-beGZ1qTztTFhSk,2434
12
- mb_rag-1.0.117.dist-info/METADATA,sha256=YH6LUu87Vn06x6NLD8FNS1YnaOuqx8Tq1vpTb8_81W0,154
13
- mb_rag-1.0.117.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
14
- mb_rag-1.0.117.dist-info/top_level.txt,sha256=FIK1eAa5uYnurgXZquBG-s3PIy-HDTC5yJBW4lTH_pM,7
15
- mb_rag-1.0.117.dist-info/RECORD,,