Coverage for mindsdb / integrations / handlers / google_content_shopping_handler / google_content_shopping_tables.py: 0%
197 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 mindsdb_sql_parser import ast
3from pandas import DataFrame
5from mindsdb.integrations.libs.api_handler import APITable
6from mindsdb.integrations.utilities.date_utils import parse_utc_date
7from mindsdb.integrations.utilities.sql_utils import extract_comparison_conditions
10class AccountsTable(APITable):
11 """
12 Table class for the Google Content API for Shopping Accounts table.
13 """
15 def select(self, query: ast.Select) -> DataFrame:
16 """
17 Lists the sub-accounts in your Merchant Center account.
19 Args:
20 query (ast.Select): SQL query to parse.
22 Returns:
23 Response: Response object containing the results.
24 """
26 # Parse the query to get the conditions.
27 conditions = extract_comparison_conditions(query.where)
28 # Get the start and end times from the conditions.
29 params = {}
30 accepted_params = ['view', 'label', 'name']
31 for op, arg1, arg2 in conditions:
32 if arg1 == 'accountId':
33 if op == '=':
34 params[arg1] = arg2
35 elif op == '>':
36 params['startId'] = arg2
37 elif op == '<':
38 params['endId'] = arg2
39 else:
40 raise NotImplementedError
41 if arg1 in accepted_params:
42 if op != '=':
43 raise NotImplementedError
44 params[arg1] = arg2
45 else:
46 raise NotImplementedError
48 if query.limit is not None:
49 params['maxResults'] = query.limit.value
51 # Get the accounts from the API.
52 accounts = self.handler. \
53 call_application_api(method_name='get_accounts', params=params)
55 selected_columns = []
56 for target in query.targets:
57 if isinstance(target, ast.Star):
58 selected_columns = self.get_columns()
59 break
60 elif isinstance(target, ast.Identifier):
61 selected_columns.append(target.parts[-1])
62 else:
63 raise ValueError(f"Unknown query target {type(target)}")
65 if len(accounts) == 0:
66 accounts = pd.DataFrame([], columns=selected_columns)
67 else:
68 accounts.columns = self.get_columns()
69 for col in set(accounts.columns).difference(set(selected_columns)):
70 accounts = accounts.drop(col, axis=1)
71 return accounts
73 def delete(self, query: ast.Delete):
74 """
75 Deletes accounts from your Merchant Center account.
77 Args:
78 query (ast.Delete): SQL query to parse.
80 Returns:
81 Response: Response object containing the results.
82 """
84 # Parse the query to get the conditions.
85 conditions = extract_comparison_conditions(query.where)
86 # Get the start and end times from the conditions.
87 params = {}
88 for op, arg1, arg2 in conditions:
89 if arg1 == 'accountId':
90 if op == '=':
91 params[arg1] = arg2
92 elif op == '>':
93 params['startId'] = arg2
94 elif op == '<':
95 params['endId'] = arg2
96 elif arg1 == 'force':
97 if op != '=':
98 raise NotImplementedError
99 params[arg1] = arg2
100 else:
101 raise NotImplementedError
103 # Delete the events in the Google Calendar API.
104 self.handler.call_application_api(method_name='delete_accounts', params=params)
106 def get_columns(self) -> list:
107 """Gets all columns to be returned in pandas DataFrame responses"""
108 return [
109 'name',
110 'kind',
111 'websiteUrl',
112 'adultContent',
113 'sellerId',
114 'users',
115 'id',
116 'youtubeChannelLinks',
117 'googleMyBusinessLink',
118 'businessInformation',
119 'automaticImprovements',
120 'adsLinks',
121 'cssId',
122 'labelIds',
123 'accountManagement',
124 'automaticLabelIds',
125 'conversionSettings'
126 ]
129class OrdersTable(APITable):
130 """
131 Table class for the Google Content API for Shopping Orders table.
132 """
134 def select(self, query: ast.Select) -> DataFrame:
135 """
136 Lists the orders in your Merchant Center account.
138 Args:
139 query (ast.Select): SQL query to parse.
141 Returns:
142 Response: Response object containing the results.
143 """
145 # Parse the query to get the conditions.
146 conditions = extract_comparison_conditions(query.where)
147 # Get the start and end times from the conditions.
148 params = {}
149 accepted_params = ['statuses', 'acknowledged']
150 for op, arg1, arg2 in conditions:
151 if arg1 == 'orderId':
152 if op == '=':
153 params[arg1] = arg2
154 elif op == '>':
155 params['startId'] = arg2
156 elif op == '<':
157 params['endId'] = arg2
158 else:
159 raise NotImplementedError
160 if arg1 == 'placedDateStart' or arg1 == 'placedDateEnd':
161 if op != '=':
162 raise NotImplementedError
163 params[arg1] = parse_utc_date(arg2)
164 if arg1 in accepted_params:
165 params[arg1] = parse_utc_date(arg2)
166 if op != '=':
167 raise NotImplementedError
168 params[arg1] = arg2
169 else:
170 raise NotImplementedError
172 if query.order_by is not None:
173 if query.order_by[0].value == 'placedDate':
174 if query.order_by[1].value == 'ASC':
175 params['orderBy'] = 'placedDateAsc'
176 else:
177 params['orderBy'] = 'placedDateDesc'
178 raise NotImplementedError
179 else:
180 raise NotImplementedError
182 if query.limit is not None:
183 params['maxResults'] = query.limit.value
185 # Get the orders from the API.
186 orders = self.handler. \
187 call_application_api(method_name='get_orders', params=params)
189 selected_columns = []
190 for target in query.targets:
191 if isinstance(target, ast.Star):
192 selected_columns = self.get_columns()
193 break
194 elif isinstance(target, ast.Identifier):
195 selected_columns.append(target.parts[-1])
196 else:
197 raise ValueError(f"Unknown query target {type(target)}")
199 if len(orders) == 0:
200 orders = pd.DataFrame([], columns=selected_columns)
201 else:
202 orders.columns = self.get_columns()
203 for col in set(orders.columns).difference(set(selected_columns)):
204 orders = orders.drop(col, axis=1)
205 return orders
207 def delete(self, query: ast.Delete):
208 """
209 Deletes orders in your Merchant Center account.
211 Args:
212 query (ast.Delete): SQL query to parse.
214 Returns:
215 Response: Response object containing the results.
216 """
218 # Parse the query to get the conditions.
219 conditions = extract_comparison_conditions(query.where)
220 # Get the start and end times from the conditions.
221 params = {}
222 for op, arg1, arg2 in conditions:
223 if arg1 == 'orderId':
224 if op == '=':
225 params[arg1] = arg2
226 elif op == '>':
227 params['startId'] = arg2
228 elif op == '<':
229 params['endId'] = arg2
230 else:
231 raise NotImplementedError
232 else:
233 raise NotImplementedError
235 # Delete the events in the Google Calendar API.
236 self.handler.call_application_api(method_name='delete_orders', params=params)
238 def get_columns(self) -> list:
239 """Gets all columns to be returned in pandas DataFrame responses"""
240 return [
241 'id',
242 'merchantId',
243 'merchantOrderId',
244 'kind',
245 'lineItems',
246 'status',
247 'paymentStatus',
248 'acknowledged',
249 'placedDate',
250 'deliveryDetails',
251 'customer',
252 'shippingCost',
253 'shippingCostTax',
254 'refunds',
255 'shipments',
256 'billingAddress',
257 'promotions',
258 'taxCollector',
259 'netPriceAmount',
260 'netTaxAmount',
261 'pickupDetails',
262 'annotations'
263 ]
266class ProductsTable(APITable):
267 """
268 Table class for the Google Content API for Shopping Products table.
269 """
271 def select(self, query: ast.Select) -> DataFrame:
272 """
273 Lists the products in your Merchant Center account.
275 Args:
276 query (ast.Select): SQL query to parse.
278 Returns:
279 Response: Response object containing the results.
280 """
282 # Parse the query to get the conditions.
283 conditions = extract_comparison_conditions(query.where)
284 params = {}
285 for op, arg1, arg2 in conditions:
286 if arg1 == 'productId':
287 if op == '=':
288 params[arg1] = arg2
289 elif op == '>':
290 params['startId'] = arg2
291 elif op == '<':
292 params['endId'] = arg2
293 else:
294 raise NotImplementedError
295 else:
296 raise NotImplementedError
298 if query.limit is not None:
299 params['maxResults'] = query.limit.value
301 # Get the products from the API.
302 products = self.handler. \
303 call_application_api(method_name='get_products', params=params)
305 selected_columns = []
306 for target in query.targets:
307 if isinstance(target, ast.Star):
308 selected_columns = self.get_columns()
309 break
310 elif isinstance(target, ast.Identifier):
311 selected_columns.append(target.parts[-1])
312 else:
313 raise ValueError(f"Unknown query target {type(target)}")
315 if len(products) == 0:
316 products = pd.DataFrame([], columns=selected_columns)
317 else:
318 products.columns = self.get_columns()
319 for col in set(products.columns).difference(set(selected_columns)):
320 products = products.drop(col, axis=1)
321 return products
323 def update(self, query: ast.Update):
324 """
325 Updates products in your Merchant Center account.
327 Args:
328 query (ast.Update): SQL query to parse.
330 Returns:
331 Response: Response object containing the results.
332 """
334 params = {}
335 values = query.values[0]
336 # Get the event data from the values.
337 accepted_params = self.get_columns()
338 for col, val in zip(query.update_columns, values):
339 if col in accepted_params:
340 params[col] = val
341 else:
342 raise NotImplementedError
344 params['updateMask'] = ','.join(params.keys())
345 # Parse the query to get the conditions.
346 conditions = extract_comparison_conditions(query.where)
347 # Get the start and end times from the conditions.
349 for op, arg1, arg2 in conditions:
350 if arg1 == 'productId':
351 if op == '=':
352 params[arg1] = arg2
353 elif op == '>':
354 params['startId'] = arg2
355 elif op == '<':
356 params['endId'] = arg2
357 else:
358 raise NotImplementedError
359 else:
360 raise NotImplementedError
362 # Update the products in the Google Merchant Center API.
363 self.handler.call_application_api(method_name='update_products', params=params)
365 def delete(self, query: ast.Delete):
366 """
367 Deletes products in your Merchant Center account.
369 Args:
370 query (ast.Delete): SQL query to parse.
372 Returns:
373 Response: Response object containing the results.
374 """
376 # Parse the query to get the conditions.
377 conditions = extract_comparison_conditions(query.where)
378 # Get the start and end times from the conditions.
379 params = {}
380 for op, arg1, arg2 in conditions:
381 if arg1 == 'productId':
382 if op == '=':
383 params[arg1] = arg2
384 elif op == '>':
385 params['startId'] = arg2
386 elif op == '<':
387 params['endId'] = arg2
388 else:
389 raise NotImplementedError
390 elif arg1 == 'feedId':
391 if op != '=':
392 raise NotImplementedError
393 params[arg1] = arg2
394 else:
395 raise NotImplementedError
397 # Delete the products in the Google Merchant Center API.
398 self.handler.call_application_api(method_name='delete_products', params=params)
400 def get_columns(self) -> list:
401 """Gets all columns to be returned in pandas DataFrame responses"""
402 return [
403 'id',
404 'offerId',
405 'title',
406 'description',
407 'link',
408 'imageLink',
409 'contentLanguage',
410 'targetCountry',
411 'channel',
412 'channelExclusivity',
413 'price',
414 'salePrice',
415 'salePriceEffectiveDate',
416 'gtin',
417 'mpn',
418 'brand',
419 'condition',
420 'adult',
421 'multipack',
422 'isBundle',
423 'energyEfficiencyClass',
424 'minEnergyEfficiencyClass',
425 'maxEnergyEfficiencyClass',
426 'ageGroup',
427 'color',
428 'expirationDate',
429 'disclosureDate',
430 'availability',
431 'source'
432 ]