Coverage for mindsdb / integrations / handlers / zipcodebase_handler / zipcodebase_tables.py: 0%
181 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1import pandas as pd
2from typing import List
3from mindsdb.integrations.libs.api_handler import APITable
4from mindsdb.integrations.utilities.handlers.query_utilities import SELECTQueryParser, SELECTQueryExecutor
5from mindsdb.utilities import log
6from mindsdb_sql_parser import ast
8logger = log.getLogger(__name__)
11class ZipCodeBaseCodeLocationTable(APITable):
12 """The ZipCodeBase Location Table implementation"""
14 def select(self, query: ast.Select) -> pd.DataFrame:
15 """Pulls data from the https://app.zipcodebase.com/documentation#search API
17 Parameters
18 ----------
19 query : ast.Select
20 Given SQL SELECT query
22 Returns
23 -------
24 pd.DataFrame
25 Location of the codes matching the query
27 Raises
28 ------
29 ValueError
30 If the query contains an unsupported condition
31 """
33 select_statement_parser = SELECTQueryParser(
34 query,
35 'code_to_location',
36 self.get_columns()
37 )
39 selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query()
41 search_params = {}
42 subset_where_conditions = []
44 for op, arg1, arg2 in where_conditions:
45 if arg1 == "codes":
46 if op == '=':
47 search_params["codes"] = arg2
48 else:
49 raise NotImplementedError("Only '=' operator is supported for codes column.")
51 elif arg1 in self.get_columns():
52 subset_where_conditions.append([op, arg1, arg2])
54 filter_flag = "codes" in search_params
56 if not filter_flag:
57 raise NotImplementedError("`codes` column has to be present in where clause.")
59 code_to_location_df = pd.DataFrame(columns=self.get_columns())
61 response = self.handler.client.code_to_location(search_params.get("codes"))
63 self.check_res(res=response)
65 content = response["content"]
67 code_to_location_df = pd.json_normalize(self.clean_resp(content["results"]))
69 select_statement_executor = SELECTQueryExecutor(
70 code_to_location_df,
71 selected_columns,
72 subset_where_conditions,
73 order_by_conditions,
74 result_limit
75 )
77 code_to_location_df = select_statement_executor.execute_query()
79 return code_to_location_df
81 def clean_resp(self, data):
82 clean_data = []
83 for k, v in data.items():
84 clean_data.extend(v)
85 return clean_data
87 def check_res(self, res):
88 if res["code"] != 200:
89 raise Exception("Error fetching results - " + res["error"])
91 def get_columns(self) -> List[str]:
92 """Gets all columns to be returned in pandas DataFrame responses
93 Returns
94 -------
95 List[str]
96 List of columns
97 """
99 return [
100 "postal_code",
101 "country_code",
102 "latitude",
103 "longitude",
104 "city",
105 "state",
106 "city_en",
107 "state_en",
108 "state_code",
109 "province",
110 "province_code"
111 ]
114class ZipCodeBaseCodeInRadiusTable(APITable):
115 """The ZipCodeBase Codes within Radius Table implementation"""
117 def select(self, query: ast.Select) -> pd.DataFrame:
118 """Pulls data from the https://app.zipcodebase.com/documentation#radius API
120 Parameters
121 ----------
122 query : ast.Select
123 Given SQL SELECT query
125 Returns
126 -------
127 pd.DataFrame
128 codes within the radius
130 Raises
131 ------
132 ValueError
133 If the query contains an unsupported condition
134 """
136 select_statement_parser = SELECTQueryParser(
137 query,
138 'codes_within_radius',
139 self.get_columns()
140 )
142 selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query()
144 search_params = {}
145 subset_where_conditions = []
147 for op, arg1, arg2 in where_conditions:
148 if arg1 == "code":
149 if op == '=':
150 search_params["code"] = arg2
151 else:
152 raise NotImplementedError("Only '=' operator is supported for code column.")
154 if arg1 == "radius":
155 if op == '=':
156 search_params["radius"] = arg2
157 else:
158 raise NotImplementedError("Only '=' operator is supported for radius column.")
160 if arg1 == "country":
161 if op == '=':
162 search_params["country"] = arg2
163 else:
164 raise NotImplementedError("Only '=' operator is supported for country column.")
166 if arg1 == "unit":
167 if op == '=':
168 search_params["unit"] = arg2
169 else:
170 raise NotImplementedError("Only '=' operator is supported for unit column.")
172 elif arg1 in self.get_columns():
173 subset_where_conditions.append([op, arg1, arg2])
175 filter_flag = ("code" in search_params) and ("radius" in search_params) and ("country" in search_params)
177 if not filter_flag:
178 raise NotImplementedError("`codes`, `radius` and `country` columns have to be present in where clause.")
180 code_to_location_df = pd.DataFrame(columns=self.get_columns())
182 response = self.handler.client.codes_within_radius(search_params.get("code"), search_params.get("radius"), search_params.get("country"), search_params.get("unit", "km"))
184 self.check_res(res=response)
186 content = response["content"]
188 logger.info(f"response size - {len(content['results'])}")
189 code_to_location_df = pd.json_normalize(content["results"])
191 select_statement_executor = SELECTQueryExecutor(
192 code_to_location_df,
193 selected_columns,
194 subset_where_conditions,
195 order_by_conditions,
196 result_limit
197 )
199 code_to_location_df = select_statement_executor.execute_query()
201 return code_to_location_df
203 def check_res(self, res):
204 if res["code"] != 200:
205 raise Exception("Error fetching results - " + res["error"])
207 def get_columns(self) -> List[str]:
208 """Gets all columns to be returned in pandas DataFrame responses
209 Returns
210 -------
211 List[str]
212 List of columns
213 """
215 return [
216 "code",
217 "city",
218 "state",
219 "city_en",
220 "state_en",
221 "distance"
222 ]
225class ZipCodeBaseCodeByCityTable(APITable):
226 """The ZipCodeBase Codes within a City Table implementation"""
228 def select(self, query: ast.Select) -> pd.DataFrame:
229 """Pulls data from the https://app.zipcodebase.com/documentation#city API
231 Parameters
232 ----------
233 query : ast.Select
234 Given SQL SELECT query
236 Returns
237 -------
238 pd.DataFrame
239 codes within the city
241 Raises
242 ------
243 ValueError
244 If the query contains an unsupported condition
245 """
247 select_statement_parser = SELECTQueryParser(
248 query,
249 'codes_by_city',
250 self.get_columns()
251 )
253 selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query()
255 search_params = {}
256 subset_where_conditions = []
258 for op, arg1, arg2 in where_conditions:
259 if arg1 == "city":
260 if op == '=':
261 search_params["city"] = arg2
262 else:
263 raise NotImplementedError("Only '=' operator is supported for city column.")
265 if arg1 == "country":
266 if op == '=':
267 search_params["country"] = arg2
268 else:
269 raise NotImplementedError("Only '=' operator is supported for country column.")
271 elif arg1 in self.get_columns():
272 subset_where_conditions.append([op, arg1, arg2])
274 filter_flag = ("city" in search_params) and ("country" in search_params)
276 if not filter_flag:
277 raise NotImplementedError("`city` and `country` columns have to be present in where clause.")
279 codes_by_city_df = pd.DataFrame(columns=self.get_columns())
281 response = self.handler.client.codes_by_city(search_params.get("city"), search_params.get("country"))
283 self.check_res(res=response)
285 content = response["content"]
287 logger.info(f"response size - {len(content['results'])}")
288 codes_by_city_df = pd.json_normalize({"codes": content["results"]})
290 select_statement_executor = SELECTQueryExecutor(
291 codes_by_city_df,
292 selected_columns,
293 subset_where_conditions,
294 order_by_conditions,
295 result_limit
296 )
298 codes_by_city_df = select_statement_executor.execute_query()
300 return codes_by_city_df
302 def check_res(self, res):
303 if res["code"] != 200:
304 raise Exception("Error fetching results - " + res["error"])
306 def get_columns(self) -> List[str]:
307 """Gets all columns to be returned in pandas DataFrame responses
308 Returns
309 -------
310 List[str]
311 List of columns
312 """
314 return [
315 "codes"
316 ]
319class ZipCodeBaseCodeByStateTable(APITable):
320 """The ZipCodeBase Codes within a State Table implementation"""
322 def select(self, query: ast.Select) -> pd.DataFrame:
323 """Pulls data from the https://app.zipcodebase.com/documentation#state API
325 Parameters
326 ----------
327 query : ast.Select
328 Given SQL SELECT query
330 Returns
331 -------
332 pd.DataFrame
333 codes within the state
335 Raises
336 ------
337 ValueError
338 If the query contains an unsupported condition
339 """
341 select_statement_parser = SELECTQueryParser(
342 query,
343 'codes_by_state',
344 self.get_columns()
345 )
347 selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query()
349 search_params = {}
350 subset_where_conditions = []
352 for op, arg1, arg2 in where_conditions:
353 if arg1 == "state":
354 if op == '=':
355 search_params["state"] = arg2
356 else:
357 raise NotImplementedError("Only '=' operator is supported for state column.")
359 if arg1 == "country":
360 if op == '=':
361 search_params["country"] = arg2
362 else:
363 raise NotImplementedError("Only '=' operator is supported for country column.")
365 elif arg1 in self.get_columns():
366 subset_where_conditions.append([op, arg1, arg2])
368 filter_flag = ("state" in search_params) and ("country" in search_params)
370 if not filter_flag:
371 raise NotImplementedError("`state` and `country` columns have to be present in where clause.")
373 codes_by_state_df = pd.DataFrame(columns=self.get_columns())
375 response = self.handler.client.codes_by_state(search_params.get("state"), search_params.get("country"))
377 self.check_res(res=response)
379 content = response["content"]
381 logger.info(f"response size - {len(content['results'])}")
382 codes_by_state_df = pd.json_normalize({"codes": content["results"]})
384 select_statement_executor = SELECTQueryExecutor(
385 codes_by_state_df,
386 selected_columns,
387 subset_where_conditions,
388 order_by_conditions,
389 result_limit
390 )
392 codes_by_state_df = select_statement_executor.execute_query()
394 return codes_by_state_df
396 def check_res(self, res):
397 if res["code"] != 200:
398 raise Exception("Error fetching results - " + res["error"])
400 def get_columns(self) -> List[str]:
401 """Gets all columns to be returned in pandas DataFrame responses
402 Returns
403 -------
404 List[str]
405 List of columns
406 """
408 return [
409 "codes"
410 ]
413class ZipCodeBaseStatesByCountryTable(APITable):
414 """The ZipCodeBase Provinces/states within a country Table implementation"""
416 def select(self, query: ast.Select) -> pd.DataFrame:
417 """Pulls data from the https://app.zipcodebase.com/documentation#provinces API
419 Parameters
420 ----------
421 query : ast.Select
422 Given SQL SELECT query
424 Returns
425 -------
426 pd.DataFrame
427 states within a country
429 Raises
430 ------
431 ValueError
432 If the query contains an unsupported condition
433 """
435 select_statement_parser = SELECTQueryParser(
436 query,
437 'states_by_country',
438 self.get_columns()
439 )
441 selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query()
443 search_params = {}
444 subset_where_conditions = []
446 for op, arg1, arg2 in where_conditions:
448 if arg1 == "country":
449 if op == '=':
450 search_params["country"] = arg2
451 else:
452 raise NotImplementedError("Only '=' operator is supported for country column.")
454 elif arg1 in self.get_columns():
455 subset_where_conditions.append([op, arg1, arg2])
457 filter_flag = ("country" in search_params)
459 if not filter_flag:
460 raise NotImplementedError("`country` column has to be present in where clause.")
462 states_by_country_df = pd.DataFrame(columns=self.get_columns())
464 response = self.handler.client.states_by_country(search_params.get("country"))
466 self.check_res(res=response)
468 content = response["content"]
470 logger.info(f"response size - {len(content['results'])}")
471 states_by_country_df = pd.json_normalize({"states": content["results"]})
473 select_statement_executor = SELECTQueryExecutor(
474 states_by_country_df,
475 selected_columns,
476 subset_where_conditions,
477 order_by_conditions,
478 result_limit
479 )
481 states_by_country_df = select_statement_executor.execute_query()
483 return states_by_country_df
485 def check_res(self, res):
486 if res["code"] != 200:
487 raise Exception("Error fetching results - " + res["error"])
489 def get_columns(self) -> List[str]:
490 """Gets all columns to be returned in pandas DataFrame responses
491 Returns
492 -------
493 List[str]
494 List of columns
495 """
497 return [
498 "states"
499 ]