logos-sdk 0.0.25.dev26__tar.gz → 0.0.25.dev28__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.
Files changed (27) hide show
  1. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/PKG-INFO +1 -1
  2. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/big_query/BigQuery.py +51 -1
  3. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/MerchantCenter.py +8 -8
  4. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk.egg-info/PKG-INFO +1 -1
  5. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/LICENSE +0 -0
  6. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/README.md +0 -0
  7. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/__init__.py +0 -0
  8. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/big_query/__init__.py +0 -0
  9. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/logging/LogosLogger.py +0 -0
  10. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/logging/__init__.py +0 -0
  11. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/CampaignManager.py +0 -0
  12. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/Collabim.py +0 -0
  13. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/DV360.py +0 -0
  14. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/Facebook.py +0 -0
  15. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/GoogleAds.py +0 -0
  16. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/GoogleSheets.py +0 -0
  17. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/MarketMiner.py +0 -0
  18. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/MicrosoftAdvertising.py +0 -0
  19. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/MicrosoftAdvertisingMerchantCenter.py +0 -0
  20. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/Sklik.py +0 -0
  21. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk/services/__init__.py +0 -0
  22. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk.egg-info/SOURCES.txt +0 -0
  23. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk.egg-info/dependency_links.txt +0 -0
  24. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk.egg-info/requires.txt +0 -0
  25. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/logos_sdk.egg-info/top_level.txt +0 -0
  26. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/setup.cfg +0 -0
  27. {logos_sdk-0.0.25.dev26 → logos_sdk-0.0.25.dev28}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logos-sdk
3
- Version: 0.0.25.dev26
3
+ Version: 0.0.25.dev28
4
4
  Summary: SDK for Logos platform
5
5
  Home-page: https://bitbucket.org/databy/logos-sdk-pip/src/master/
6
6
  Author: Databy.io
@@ -2,7 +2,7 @@ import os
2
2
  from datetime import datetime
3
3
 
4
4
  import google.auth.exceptions
5
- from typing import List, Dict, Union, Optional
5
+ from typing import List, Dict, Union, Optional, Sequence
6
6
 
7
7
  from google.api_core.exceptions import NotFound
8
8
  from google.cloud.logging import Client as LoggerClient
@@ -218,3 +218,53 @@ class BigQuery:
218
218
  errors = self._service.insert_rows(bq_table, records)
219
219
  if errors:
220
220
  raise BigQueryException(errors)
221
+
222
+ def upsert_into_table(
223
+ self,
224
+ dataset_id: str,
225
+ target_table: str,
226
+ records: List[Dict],
227
+ schema_columns: List[Dict],
228
+ key_columns: Sequence[str],
229
+ ) -> None:
230
+ if not records:
231
+ return
232
+ if not key_columns:
233
+ return
234
+
235
+ bq_table = self.check_table_exists(dataset_id, target_table)
236
+ if bq_table is None:
237
+ self.create_table(dataset_id, target_table, schema_columns)
238
+ table_id = f"{self.project_id}.{dataset_id}.{target_table}"
239
+ cols = [f["name"] for f in schema_columns]
240
+
241
+ staging_table_name = f"_staging_{target_table}"
242
+ staging_table_id = f"{self.project_id}.{dataset_id}.{staging_table_name}"
243
+ self.create_table(dataset_id, staging_table_name, schema_columns)
244
+
245
+ self.insert_into_table(dataset_id, staging_table_name, records)
246
+
247
+ q = lambda c: f"{c}"
248
+
249
+ on_clause = " AND ".join(f"T.{q(k)} = S.{q(k)}" for k in key_columns)
250
+ update_cols = [c for c in cols if c not in set(key_columns)]
251
+ update_set = ",\n ".join(f"{q(c)} = S.{q(c)}" for c in update_cols)
252
+
253
+ insert_cols = ", ".join(q(c) for c in cols)
254
+ insert_vals = ", ".join(f"S.{q(c)}" for c in cols)
255
+
256
+ merge_sql = f"""
257
+ MERGE `{table_id}` T
258
+ USING `{staging_table_id}` S
259
+ ON {on_clause}
260
+ WHEN MATCHED THEN
261
+ UPDATE SET
262
+ {update_set}
263
+ WHEN NOT MATCHED THEN
264
+ INSERT ({insert_cols})
265
+ VALUES ({insert_vals})
266
+ """
267
+ job = self._service.query(merge_sql)
268
+ job.result()
269
+
270
+ self.delete_table(dataset_id, staging_table_name)
@@ -21,7 +21,7 @@ class MerchantCenterService:
21
21
  self._LIST_PRODUCT_STATUSES = self._URL + "/product-service/product-statuses"
22
22
  self._REPORTS_SEARCH = self._URL + "/reports-search"
23
23
  self._GET_SUPPLEMENTAL_FEEDS = self._URL + "/feed-service/supplemental-feeds"
24
- self._PRIMARY_FEED = self._URL + "/feed-service/feeds"
24
+ self._PRIMARY_FEEDS = self._URL + "/feed-service/feeds"
25
25
 
26
26
 
27
27
  def list_accounts(self, merchant_account_id: str, secret_id: str):
@@ -228,11 +228,11 @@ class MerchantCenterService:
228
228
  else:
229
229
  raise MerchantServiceException(response.content)
230
230
 
231
- def get_primary_feed(self, secret_id: str, merchant_account_id: str):
231
+ def get_primary_feeds(self, secret_id: str, merchant_account_id: str):
232
232
  body = {"secret_id": secret_id, "merchant_account_id": merchant_account_id}
233
- header = get_headers(self._PRIMARY_FEED)
233
+ header = get_headers(self._PRIMARY_FEEDS)
234
234
  response = self.session.request(
235
- "post", url=self._PRIMARY_FEED, json=body, headers=header
235
+ "post", url=self._PRIMARY_FEEDS, json=body, headers=header
236
236
  )
237
237
 
238
238
  if response.status_code == HTTPStatus.OK:
@@ -255,9 +255,9 @@ class MerchantCenterService:
255
255
  "supplemental_feed_id": supplemental_feed_id,
256
256
  "action": "attach"
257
257
  }
258
- header = get_headers(self._PRIMARY_FEED)
258
+ header = get_headers(self._PRIMARY_FEEDS)
259
259
  response = self.session.request(
260
- "patch", url=self._PRIMARY_FEED, json=body, headers=header
260
+ "patch", url=self._PRIMARY_FEEDS, json=body, headers=header
261
261
  )
262
262
 
263
263
  if response.status_code == HTTPStatus.OK:
@@ -280,9 +280,9 @@ class MerchantCenterService:
280
280
  "supplemental_feed_id": supplemental_feed_id,
281
281
  "action": "detach"
282
282
  }
283
- header = get_headers(self._PRIMARY_FEED)
283
+ header = get_headers(self._PRIMARY_FEEDS)
284
284
  response = self.session.request(
285
- "patch", url=self._PRIMARY_FEED, json=body, headers=header
285
+ "patch", url=self._PRIMARY_FEEDS, json=body, headers=header
286
286
  )
287
287
 
288
288
  if response.status_code == HTTPStatus.OK:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logos-sdk
3
- Version: 0.0.25.dev26
3
+ Version: 0.0.25.dev28
4
4
  Summary: SDK for Logos platform
5
5
  Home-page: https://bitbucket.org/databy/logos-sdk-pip/src/master/
6
6
  Author: Databy.io