logos-sdk 0.0.25.dev10__tar.gz → 0.0.25.dev11__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 (26) hide show
  1. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/PKG-INFO +10 -2
  2. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/CampaignManager.py +58 -33
  3. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/DV360.py +46 -23
  4. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/Facebook.py +22 -0
  5. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/GoogleAds.py +42 -19
  6. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/MerchantCenter.py +25 -0
  7. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/MicrosoftAdvertising.py +23 -0
  8. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/Sklik.py +15 -0
  9. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk.egg-info/PKG-INFO +10 -2
  10. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/LICENSE +0 -0
  11. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/README.md +0 -0
  12. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/__init__.py +0 -0
  13. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/big_query/BigQuery.py +0 -0
  14. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/big_query/__init__.py +0 -0
  15. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/logging/LogosLogger.py +0 -0
  16. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/logging/__init__.py +0 -0
  17. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/Collabim.py +0 -0
  18. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/GoogleSheets.py +0 -0
  19. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/MarketMiner.py +0 -0
  20. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk/services/__init__.py +0 -0
  21. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk.egg-info/SOURCES.txt +0 -0
  22. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk.egg-info/dependency_links.txt +0 -0
  23. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk.egg-info/requires.txt +0 -0
  24. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/logos_sdk.egg-info/top_level.txt +0 -0
  25. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/setup.cfg +0 -0
  26. {logos_sdk-0.0.25.dev10 → logos_sdk-0.0.25.dev11}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: logos-sdk
3
- Version: 0.0.25.dev10
3
+ Version: 0.0.25.dev11
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
@@ -19,6 +19,14 @@ Requires-Dist: httplib2
19
19
  Requires-Dist: pandas
20
20
  Requires-Dist: db-dtypes
21
21
  Requires-Dist: numpy
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: requires-dist
29
+ Dynamic: summary
22
30
 
23
31
  # Logos Software Development Kit
24
32
 
@@ -32,17 +32,18 @@ class CampaignManagerService:
32
32
  self._QUERY_DIMENSION_VALUES = self._URL + "/query-dimension-values"
33
33
  self._GET_ACCESSIBLE_PARENT_ACCOUNTS = self._URL + "/get-parent-accounts"
34
34
  self._GET_ACCESSIBLE_ADVERTISERS = self._URL + "/get-advertisers"
35
+ self._GET_ACCOUNT_ACCESSIBILITY = self._URL + "/get-account-accessibility"
35
36
 
36
37
  def create_report(
37
- self,
38
- account_id: str,
39
- name: str,
40
- start_date: str,
41
- end_date: str,
42
- dimensions: list,
43
- metrics_names: list,
44
- dimension_filters: list,
45
- secret_id: str,
38
+ self,
39
+ account_id: str,
40
+ name: str,
41
+ start_date: str,
42
+ end_date: str,
43
+ dimensions: list,
44
+ metrics_names: list,
45
+ dimension_filters: list,
46
+ secret_id: str,
46
47
  ) -> Dict:
47
48
  """
48
49
  Method for creating a report in API and returning a dict containing its ID for further use
@@ -181,7 +182,7 @@ class CampaignManagerService:
181
182
  raise CampaignManagerServiceException(response.content)
182
183
 
183
184
  def check_report_ready_with_exponential_backoff(
184
- self, report_id: str, file_id: str, secret_id: str, backoff_attempts: int = 10
185
+ self, report_id: str, file_id: str, secret_id: str, backoff_attempts: int = 10
185
186
  ) -> bool:
186
187
  """
187
188
  Implements exponential backoff for pooling the API for readiness of the report, suggested in
@@ -196,7 +197,7 @@ class CampaignManagerService:
196
197
  if self.check_report_ready(report_id, file_id, secret_id):
197
198
  return True
198
199
  else:
199
- time.sleep((2**attempt) + randint(1, 20))
200
+ time.sleep((2 ** attempt) + randint(1, 20))
200
201
 
201
202
  return False
202
203
 
@@ -290,14 +291,14 @@ class CampaignManagerService:
290
291
  raise CampaignManagerServiceException(response.content)
291
292
 
292
293
  def query_dimension_values(
293
- self,
294
- account_id: str,
295
- secret_id: str,
296
- dimension_name: str,
297
- filters: List,
298
- start_date: str,
299
- end_date: int,
300
- max_results: int = 100,
294
+ self,
295
+ account_id: str,
296
+ secret_id: str,
297
+ dimension_name: str,
298
+ filters: List,
299
+ start_date: str,
300
+ end_date: int,
301
+ max_results: int = 100,
301
302
  ) -> List[Dict]:
302
303
  """
303
304
  Retrieves values of selected dimensions for data filtered according to rules set in list of filters
@@ -348,16 +349,16 @@ class CampaignManagerService:
348
349
  yield service_response["data"]["items"]
349
350
 
350
351
  def create_and_get_report_results(
351
- self,
352
- account_id: str,
353
- name: str,
354
- start_date: str,
355
- end_date: str,
356
- dimensions: list,
357
- metrics_names: list,
358
- dimension_filters: list,
359
- secret_id: str,
360
- backoff_attempts: int,
352
+ self,
353
+ account_id: str,
354
+ name: str,
355
+ start_date: str,
356
+ end_date: str,
357
+ dimensions: list,
358
+ metrics_names: list,
359
+ dimension_filters: list,
360
+ secret_id: str,
361
+ backoff_attempts: int,
361
362
  ) -> Dict:
362
363
  """
363
364
  Method to create report, run it and fetch results in one go
@@ -380,10 +381,10 @@ class CampaignManagerService:
380
381
  secret_id=secret_id,
381
382
  )
382
383
  if self.check_report_ready_with_exponential_backoff(
383
- report_id=report["id"],
384
- file_id=run_report["id"],
385
- secret_id=secret_id,
386
- backoff_attempts=backoff_attempts,
384
+ report_id=report["id"],
385
+ file_id=run_report["id"],
386
+ secret_id=secret_id,
387
+ backoff_attempts=backoff_attempts,
387
388
  ):
388
389
  return self.get_report_results(
389
390
  report_id=report["id"],
@@ -444,3 +445,27 @@ class CampaignManagerService:
444
445
  return service_response["data"]
445
446
  else:
446
447
  raise CampaignManagerServiceException(response.content)
448
+
449
+ def get_account_accessibility(self, secret_id: str,account_id, advertiser_id: str) -> bool:
450
+ """
451
+ Gets account accessibility
452
+ :param secret_id: The ID of the secret in secret manager
453
+ :param account_id: Account ID
454
+ :param advertiser_id: The ID of the advertiser.
455
+ :return: True if account has access
456
+ """
457
+ body = {
458
+ "secret_id": secret_id,
459
+ "account_id": account_id,
460
+ "advertiser_id": advertiser_id
461
+ }
462
+ header = get_headers(self._GET_ACCOUNT_ACCESSIBILITY)
463
+ response = request(
464
+ "post", url=self._GET_ACCOUNT_ACCESSIBILITY, json=body, headers=header
465
+ )
466
+
467
+ if response.status_code == HTTPStatus.OK:
468
+ service_response = response.json()
469
+ return service_response["data"]
470
+ else:
471
+ raise CampaignManagerServiceException(response.content)
@@ -20,10 +20,10 @@ class DV360Service:
20
20
  self._URL = url or os.environ.get("DV360_SERVICE_PATH")
21
21
  self._LIST_LINE_ITEMS = self._URL + "/line-items"
22
22
  self._BULK_LIST_LINE_ITEM_ASSIGNED_TARGETING_OPTIONS = (
23
- self._URL + "/bulk-list-line-item-assigned-targeting-options"
23
+ self._URL + "/bulk-list-line-item-assigned-targeting-options"
24
24
  )
25
25
  self._BULK_EDIT_LINE_ITEM_ASSIGNED_TARGETING_OPTIONS = (
26
- self._URL + "/bulk-edit-line-item-assigned-targeting-options"
26
+ self._URL + "/bulk-edit-line-item-assigned-targeting-options"
27
27
  )
28
28
  self._CREATE_CHANNEL = self._URL + "/create-channel"
29
29
  self._LIST_CHANNELS = self._URL + "/list-channels"
@@ -36,6 +36,7 @@ class DV360Service:
36
36
  self._DELETE_QUERY = self._URL + "/delete-query"
37
37
  self._GET_ACCESSIBLE_PARTNERS = self._URL + "/get-accessible-partners"
38
38
  self._GET_ACCESSIBLE_ADVERTISERS = self._URL + "/get-accessible-advertisers"
39
+ self._GET_ACCOUNT_ACCESSIBILITY = self._URL + "/get-account-accessibility"
39
40
 
40
41
  def list_line_items(self, advertiser_id, secret_id, filter_string=None):
41
42
  """
@@ -60,11 +61,11 @@ class DV360Service:
60
61
  raise DV360ServiceException(response.content)
61
62
 
62
63
  def bulk_list_line_item_assigned_targeting_options(
63
- self,
64
- advertiser_id,
65
- secret_id,
66
- line_item_ids,
67
- filter_string,
64
+ self,
65
+ advertiser_id,
66
+ secret_id,
67
+ line_item_ids,
68
+ filter_string,
68
69
  ):
69
70
  """
70
71
  Bulk lists targeting options under multiple line items
@@ -96,12 +97,12 @@ class DV360Service:
96
97
  raise DV360ServiceException(response.content)
97
98
 
98
99
  def bulk_edit_line_item_assigned_targeting_options(
99
- self,
100
- advertiser_id,
101
- secret_id,
102
- line_item_ids,
103
- delete_requests=None,
104
- create_requests=None,
100
+ self,
101
+ advertiser_id,
102
+ secret_id,
103
+ line_item_ids,
104
+ delete_requests=None,
105
+ create_requests=None,
105
106
  ):
106
107
  """
107
108
  Bulk edits targeting options under multiple line items
@@ -182,7 +183,7 @@ class DV360Service:
182
183
  raise DV360ServiceException(response.content)
183
184
 
184
185
  def list_channel_sites(
185
- self, advertiser_id, secret_id, channel_id, filter_string=None
186
+ self, advertiser_id, secret_id, channel_id, filter_string=None
186
187
  ):
187
188
  """
188
189
  Lists channels for advertiser
@@ -213,12 +214,12 @@ class DV360Service:
213
214
  raise DV360ServiceException(response.content)
214
215
 
215
216
  def bulk_edit_channels_sites(
216
- self,
217
- advertiser_id,
218
- secret_id,
219
- channel_id,
220
- deleted_sites=None,
221
- created_sites=None,
217
+ self,
218
+ advertiser_id,
219
+ secret_id,
220
+ channel_id,
221
+ deleted_sites=None,
222
+ created_sites=None,
222
223
  ):
223
224
  """
224
225
  Bulk edits sites under a single channel
@@ -353,8 +354,30 @@ class DV360Service:
353
354
  else:
354
355
  raise DV360ServiceException(response.content)
355
356
 
357
+ def get_account_accessibility(self, secret_id: str, advertiser_id: str) -> bool:
358
+ """
359
+ Gets account accessibility
360
+ :param secret_id: The ID of the secret in secret manager
361
+ :param advertiser_id: The ID of the advertiser.
362
+ :return: True if account has access
363
+ """
364
+ body = {
365
+ "secret_id": secret_id,
366
+ "advertiser_id": advertiser_id
367
+ }
368
+ header = get_headers(self._GET_ACCOUNT_ACCESSIBILITY)
369
+ response = request(
370
+ "post", url=self._GET_ACCOUNT_ACCESSIBILITY, json=body, headers=header
371
+ )
372
+
373
+ if response.status_code == HTTPStatus.OK:
374
+ service_response = response.json()
375
+ return service_response["data"]
376
+ else:
377
+ raise DV360ServiceException(response.content)
378
+
356
379
  def _check_report_ready_with_exponential_backoff(
357
- self, secret_id: str, query_id: str, report_id: str, backoff_attempts: int = 10
380
+ self, secret_id: str, query_id: str, report_id: str, backoff_attempts: int = 10
358
381
  ) -> bool:
359
382
  """
360
383
  Implements exponential backoff for pooling the API for readiness of the report, suggested in
@@ -370,7 +393,7 @@ class DV360Service:
370
393
  elif state == "FAILED":
371
394
  raise DV360ServiceException("Report failed to generate")
372
395
  else:
373
- sleep((2**attempt) + randint(1, 20))
396
+ sleep((2 ** attempt) + randint(1, 20))
374
397
 
375
398
  return False
376
399
 
@@ -404,7 +427,7 @@ class DV360Service:
404
427
  :return: The results
405
428
  """
406
429
  if not self._check_report_ready_with_exponential_backoff(
407
- secret_id, query_id, report_id
430
+ secret_id, query_id, report_id
408
431
  ):
409
432
  raise DV360ServiceException("Report did not generate in time")
410
433
 
@@ -27,6 +27,7 @@ class FacebookService:
27
27
  self._FEED_ERRORS = self._URL + "/feed-errors"
28
28
  self._FEED_ERRORS_REPORT_STATUS = self._URL + "/feed-errors-report-status"
29
29
  self._FEED_ERRORS_REPORT = self._URL + "/feed-errors-report"
30
+ self._GET_ACCOUNT_ACCESSIBILITY = self._URL + "/get-account-accessibility"
30
31
 
31
32
  def get_accessible_accounts(
32
33
  self, secret_id: str, timeout: int = None
@@ -61,6 +62,27 @@ class FacebookService:
61
62
  else:
62
63
  raise FacebookServiceException(response.content)
63
64
 
65
+ def get_account_accessibility(self, secret_id: str, account_id: str) -> bool:
66
+ """
67
+ Gets account accessibility
68
+ :param secret_id: The ID of the secret in secret manager
69
+ :param account_id: The ID of the account.
70
+ :return: True if account has access
71
+ """
72
+ body = {
73
+ "secret_id": secret_id,
74
+ "account_id": account_id
75
+ }
76
+ header = get_headers(self._GET_ACCOUNT_ACCESSIBILITY)
77
+ response = request(
78
+ "post", url=self._GET_ACCOUNT_ACCESSIBILITY, json=body, headers=header
79
+ )
80
+
81
+ if response.status_code == HTTPStatus.OK:
82
+ service_response = response.json()
83
+ return service_response["data"]
84
+ else:
85
+ raise FacebookServiceException(response.content)
64
86
  def get_insights(
65
87
  self,
66
88
  account_id: str,
@@ -22,6 +22,7 @@ class GoogleAdsService:
22
22
  self._EXCLUDE_FOR_ACCOUNT = self._URL + "/exclude-for-account"
23
23
  self._EXCLUDE_FOR_AD_GROUP = self._URL + "/exclude-for-ad-group"
24
24
  self._GET_ACCESSIBLE_ACCOUNTS = self._URL + "/list-accessible-accounts"
25
+ self._GET_ACCOUNT_ACCESSIBILITY = self._URL + "/get-account-accessibility"
25
26
 
26
27
  @staticmethod
27
28
  def fetch_with_retry_on_timeout(url, json, headers):
@@ -29,7 +30,7 @@ class GoogleAdsService:
29
30
  try:
30
31
  return request("post", url, json=json, headers=headers, timeout=25)
31
32
  except Timeout:
32
- delay = 2 * (2**attempt) + random.randint(0, 9)
33
+ delay = 2 * (2 ** attempt) + random.randint(0, 9)
33
34
  print(
34
35
  f"there was a timeout when contacting the service, going to sleep for {delay} seconds"
35
36
  )
@@ -38,10 +39,10 @@ class GoogleAdsService:
38
39
  raise Exception("The service is not able to reply within 30 seconds.")
39
40
 
40
41
  def search_stream(
41
- self,
42
- query: str,
43
- queried_account_id: str,
44
- secret_id: str,
42
+ self,
43
+ query: str,
44
+ queried_account_id: str,
45
+ secret_id: str,
45
46
  ) -> List[Union[List, Dict]]:
46
47
  """
47
48
  :param query Sql query for google ads. Best way to build it is https://developers.google.com/google-ads/api/fields/v14/accessible_bidding_strategy_query_builder
@@ -67,11 +68,11 @@ class GoogleAdsService:
67
68
  raise GoogleAdsServiceException(response.content)
68
69
 
69
70
  def search(
70
- self,
71
- query: str,
72
- queried_account_id: str,
73
- secret_id: str,
74
- page_size: int,
71
+ self,
72
+ query: str,
73
+ queried_account_id: str,
74
+ secret_id: str,
75
+ page_size: int,
75
76
  ) -> List[Dict]:
76
77
  """
77
78
  :param query Sql query for google ads. Best way to build it is https://developers.google.com/google-ads/api/fields/v14/accessible_bidding_strategy_query_builder
@@ -111,7 +112,7 @@ class GoogleAdsService:
111
112
  yield service_response["data"]["results"]
112
113
 
113
114
  def exclude_criterion_for_account(
114
- self, client_id: str, exclusion_raw: List[str], mode: str, secret_id: str = None
115
+ self, client_id: str, exclusion_raw: List[str], mode: str, secret_id: str = None
115
116
  ) -> None:
116
117
  """
117
118
  Excludes list of unwanted urls/YouTube channels for account with client_id
@@ -140,11 +141,11 @@ class GoogleAdsService:
140
141
  raise GoogleAdsServiceException(response.content)
141
142
 
142
143
  def exclude_criterion_for_ad_group(
143
- self,
144
- client_id: str,
145
- ad_group_id: str,
146
- exclusion_raw: List[str],
147
- secret_id: str = None,
144
+ self,
145
+ client_id: str,
146
+ ad_group_id: str,
147
+ exclusion_raw: List[str],
148
+ secret_id: str = None,
148
149
  ) -> None:
149
150
  """
150
151
  Excludes list of unwanted urls/YouTube channels for given ad_group with client_id
@@ -172,9 +173,9 @@ class GoogleAdsService:
172
173
  raise GoogleAdsServiceException(response.content)
173
174
 
174
175
  def get_accessible_accounts(
175
- self,
176
- secret_id: str,
177
- page_size: int = 1000,
176
+ self,
177
+ secret_id: str,
178
+ page_size: int = 1000,
178
179
  ) -> List[Dict]:
179
180
  body = {
180
181
  "secret_id": secret_id,
@@ -209,3 +210,25 @@ class GoogleAdsService:
209
210
  all_results.extend(service_response["data"]["results"])
210
211
 
211
212
  return all_results
213
+
214
+ def get_account_accessibility(self, secret_id: str, account_id: str) -> bool:
215
+ """
216
+ Gets account accessibility
217
+ :param secret_id: The ID of the secret in secret manager
218
+ :param account_id: The ID of the account.
219
+ :return: True if account has access
220
+ """
221
+ body = {
222
+ "secret_id": secret_id,
223
+ "account_id": account_id
224
+ }
225
+ header = get_headers(self._GET_ACCOUNT_ACCESSIBILITY)
226
+ response = request(
227
+ "post", url=self._GET_ACCOUNT_ACCESSIBILITY, json=body, headers=header
228
+ )
229
+
230
+ if response.status_code == HTTPStatus.OK:
231
+ service_response = response.json()
232
+ return service_response["data"]
233
+ else:
234
+ raise GoogleAdsServiceException(response.content)
@@ -15,6 +15,7 @@ class MerchantCenterService:
15
15
  self._URL = url or os.environ.get("MERCHANT_CENTER_SERVICE_PATH")
16
16
  self._LIST_ACCOUNTS = self._URL + "/account-service/accounts"
17
17
  self._LIST_ACCESSIBLE_ACCOUNTS = self._URL + "/account-service/list-accessible-accounts"
18
+ self._GET_ACCOUNT_ACCESSIBILITY = self._URL + "/account-service/get-account-accessibility"
18
19
  self._LIST_ACCOUNT_STATUSES = self._URL + "/account-service/account-statuses"
19
20
  self._LIST_PRODUCTS = self._URL + "/product-service/products"
20
21
  self._LIST_PRODUCT_STATUSES = self._URL + "/product-service/product-statuses"
@@ -199,3 +200,27 @@ class MerchantCenterService:
199
200
 
200
201
  service_response = response.json()
201
202
  yield service_response["data"]["results"]
203
+
204
+ def get_account_accessibility(self, secret_id: str,merchant_account_id:str, account_id: str) -> bool:
205
+ """
206
+ Gets account accessibility
207
+ :param secret_id: The ID of the secret in secret manager
208
+ :param merchant_account_id: The ID of the managing account. This must be a multi-client account.
209
+ :param account_id: The ID of the account.
210
+ :return: True if account has access
211
+ """
212
+ body = {
213
+ "secret_id": secret_id,
214
+ "merchant_account_id": merchant_account_id,
215
+ "account_id": account_id
216
+ }
217
+ header = get_headers(self._GET_ACCOUNT_ACCESSIBILITY)
218
+ response = request(
219
+ "post", url=self._GET_ACCOUNT_ACCESSIBILITY, json=body, headers=header
220
+ )
221
+
222
+ if response.status_code == HTTPStatus.OK:
223
+ service_response = response.json()
224
+ return service_response["data"]
225
+ else:
226
+ raise MerchantServiceException(response.content)
@@ -23,6 +23,7 @@ class MicrosoftAdvertising:
23
23
  load_dotenv()
24
24
  self._URL = url or os.environ.get("MICROSOFT_ADVERTISING_PATH")
25
25
  self._GET_ACCESSIBLE_ACCOUNTS = self._URL + "/accessible-accounts"
26
+ self._GET_ACCOUNT_ACCESSIBILITY = self._URL + "/get-account-accessibility"
26
27
  self._GET_DESTINATION_URL_REPORT = self._URL + "/destination-url-report"
27
28
  self._GET_CAMPAIGN_PERFORMANCE_REPORT = self._URL + "/campaign-performance-report"
28
29
  self._GET_GEOGRAPHIC_PERFORMANCE_REPORT = self._URL + "/geographic-performance-report"
@@ -226,3 +227,25 @@ class MicrosoftAdvertising:
226
227
  return service_response["data"]
227
228
  else:
228
229
  raise MicrosoftAdvertisingException(response.content)
230
+
231
+ def get_account_accessibility(self, secret_id: str, account_id: str) -> bool:
232
+ """
233
+ Gets account accessibility
234
+ :param secret_id: The ID of the secret in secret manager
235
+ :param account_id: The ID of the account in Microsoft Advertising
236
+ :return: True if account has access
237
+ """
238
+ body = {
239
+ "secret_id": secret_id,
240
+ "account_id": account_id
241
+ }
242
+ header = get_headers(self._GET_ACCOUNT_ACCESSIBILITY)
243
+ response = request(
244
+ "post", url=self._GET_ACCOUNT_ACCESSIBILITY, json=body, headers=header
245
+ )
246
+
247
+ if response.status_code == HTTPStatus.OK:
248
+ service_response = response.json()
249
+ return service_response["data"]
250
+ else:
251
+ raise MicrosoftAdvertisingException(response.content)
@@ -434,3 +434,18 @@ class SklikService:
434
434
  return service_response["data"]
435
435
  else:
436
436
  raise SklikServiceException(response.content)
437
+
438
+ def get_account_accessibility(self, secret_id: str, account_email: str) -> bool:
439
+ """
440
+ Gets account accessibility
441
+ :param secret_id: The ID of the secret in secret manager
442
+ :param account_email: Account email to refers to Sklik accountId
443
+ :return: True if account has access
444
+ """
445
+ body = {"account_email": account_email, "secret_id": secret_id}
446
+ response = execute_request("post", url=self._GET_SESSION, json=body)
447
+ if response.status_code == 200:
448
+ return True
449
+ if response.status_code == 401 or response.status_code == 403 or response.status_code == 404:
450
+ return False
451
+ raise SklikServiceException(response.content)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: logos-sdk
3
- Version: 0.0.25.dev10
3
+ Version: 0.0.25.dev11
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
@@ -19,6 +19,14 @@ Requires-Dist: httplib2
19
19
  Requires-Dist: pandas
20
20
  Requires-Dist: db-dtypes
21
21
  Requires-Dist: numpy
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: requires-dist
29
+ Dynamic: summary
22
30
 
23
31
  # Logos Software Development Kit
24
32