python-amazon-ad-api 0.4.3__tar.gz → 0.4.5__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.
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/PKG-INFO +18 -18
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/README.md +17 -17
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/dsp/client.py +0 -7
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/reports.py +2 -2
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/keywords_v3.py +4 -4
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/product_ads_v3.py +1 -1
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/auth/access_token_client.py +5 -3
- python-amazon-ad-api-0.4.5/ad_api/auth/credentials.py +6 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/base_client.py +1 -5
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/client.py +39 -62
- python-amazon-ad-api-0.4.5/ad_api/base/credential_provider.py +160 -0
- python-amazon-ad-api-0.4.5/ad_api/base/exceptions.py +140 -0
- python-amazon-ad-api-0.4.5/ad_api/version.py +1 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/python_amazon_ad_api.egg-info/PKG-INFO +18 -18
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/python_amazon_ad_api.egg-info/requires.txt +1 -1
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/setup.cfg +1 -1
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/setup.py +2 -2
- python-amazon-ad-api-0.4.3/ad_api/auth/credentials.py +0 -11
- python-amazon-ad-api-0.4.3/ad_api/base/credential_provider.py +0 -72
- python-amazon-ad-api-0.4.3/ad_api/base/exceptions.py +0 -54
- python-amazon-ad-api-0.4.3/ad_api/version.py +0 -1
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/LICENSE +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/advertising_test_account.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/attribution.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/audiences.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/billing.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/brand_metrics.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/creative_assets.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/dsp/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/dsp/access_token_client.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/dsp/credential_provider.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/dsp/reports.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/eligibility.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/history.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/insights.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/invoices.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/localization.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/manager_accounts.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/metadata.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/portfolios.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/profiles.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/ad_groups.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/ad_groups_v4.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/ads_v4.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/bid_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/brands.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/campaigns.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/campaigns_v4.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/forecast.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/keywords.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/keywords_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/landing_page_asins.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/media.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/moderation.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/negative_keywords.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/negative_product_targeting.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/product_targeting.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/reports.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/snapshots.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/stores.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sb/targeting_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/ad_groups.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/bid_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/brand_safety.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/budget_rules.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/campaigns.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/campaigns_budget_usage.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/creatives.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/forecast.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/negative_product_targeting.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/product_ads.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/product_targeting.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/reports.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/snapshots.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sd/targeting_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/ad_groups.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/ad_groups_v3.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/bid_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/bid_recommendations_v3.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/budget_initial_recommendation.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/budget_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/budget_rules.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/budget_rules_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaign_consolidated_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaign_negative_keywords.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaign_negative_keywords_v3.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaign_negative_targets.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaigns.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaigns_budget_usage.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaigns_v3.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/campaings_optimization.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/keywords.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/negative_keywords.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/negative_keywords_v3.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/negative_product_targeting.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/negative_product_targeting_v3.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/product_ads.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/product_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/product_targeting.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/product_targeting_v3.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/ranked_keywords_recommendations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/reports.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/snapshots.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/sp/suggested_keywords.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/api/validation_configurations.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/auth/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/auth/access_token_response.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/auth/exceptions.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/__init__.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/api_response.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/config.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/helpers.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/marketplaces.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/base/utils.py +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/python_amazon_ad_api.egg-info/SOURCES.txt +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/python_amazon_ad_api.egg-info/dependency_links.txt +0 -0
- {python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/python_amazon_ad_api.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-amazon-ad-api
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.5
|
|
4
4
|
Summary: Python wrapper for the Amazon Advertising API
|
|
5
5
|
Home-page: https://github.com/denisneuf/python-amazon-ad-api
|
|
6
6
|
Author: Daniel Alvaro
|
|
@@ -299,21 +299,21 @@ There is a new version 3 of Sponsored Product API, please check the [migration g
|
|
|
299
299
|
|
|
300
300
|
### [Modules Available Sponsored Brands 3.0](https://python-amazon-ad-api.readthedocs.io/en/latest/sb_v3.html)
|
|
301
301
|
|
|
302
|
-
* Campaigns(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/campaigns.html)
|
|
303
|
-
* Ad Groups(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/ad_groups.html)
|
|
304
|
-
* Keywords(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/keywords.html)
|
|
305
|
-
* Negative Keywords(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_keywords.html)
|
|
306
|
-
* Product Targeting(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/product_targeting.html)
|
|
307
|
-
* Negative Product Targeting(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_product_targeting.html)
|
|
308
|
-
* Targeting Recommendations(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/targeting_recommendations.html)
|
|
309
|
-
* Bid Recommendations(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/bid_recommendations.html)
|
|
310
|
-
* Stores(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/stores.html)
|
|
311
|
-
* Landing Page Asins(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/landing_page_asins.html)
|
|
312
|
-
* Media(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/media.html)
|
|
313
|
-
* Brands(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/brands.html)
|
|
314
|
-
* Moderation(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/moderation.html)
|
|
315
|
-
* Reports(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/reports.html)
|
|
316
|
-
* Snapshots
|
|
302
|
+
* [Campaigns](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/campaigns.html)
|
|
303
|
+
* [Ad Groups](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/ad_groups.html)
|
|
304
|
+
* [Keywords](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/keywords.html)
|
|
305
|
+
* [Negative Keywords](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_keywords.html)
|
|
306
|
+
* [Product Targeting](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/product_targeting.html)
|
|
307
|
+
* [Negative Product Targeting](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_product_targeting.html)
|
|
308
|
+
* [Targeting Recommendations](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/targeting_recommendations.html)
|
|
309
|
+
* [Bid Recommendations](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/bid_recommendations.html)
|
|
310
|
+
* [Stores](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/stores.html)
|
|
311
|
+
* [Landing Page Asins](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/landing_page_asins.html)
|
|
312
|
+
* [Media](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/media.html)
|
|
313
|
+
* [Brands](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/brands.html)
|
|
314
|
+
* [Moderation](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/moderation.html)
|
|
315
|
+
* [Reports](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/reports.html)
|
|
316
|
+
* [Snapshots](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/snapshots.html)
|
|
317
317
|
|
|
318
318
|
### [Modules Available Sponsored Brands 4.0](https://python-amazon-ad-api.readthedocs.io/en/latest/sb_v4.html)
|
|
319
319
|
|
|
@@ -338,9 +338,9 @@ There is a new version 3 of Sponsored Product API, please check the [migration g
|
|
|
338
338
|
* [Forecasts](https://python-amazon-ad-api.readthedocs.io/en/latest/sd/forecast.html)
|
|
339
339
|
* [Recommendations](https://python-amazon-ad-api.readthedocs.io/en/latest/sd/recommendations.html)
|
|
340
340
|
|
|
341
|
-
### Modules Available DSP
|
|
341
|
+
### [Modules Available DSP](https://python-amazon-ad-api.readthedocs.io/en/latest/dsp.html)
|
|
342
342
|
|
|
343
|
-
* Reports
|
|
343
|
+
* [Reports](https://python-amazon-ad-api.readthedocs.io/en/latest/dsp/reports.html)
|
|
344
344
|
|
|
345
345
|
### Simple Example Usage Campaigns with Credentials
|
|
346
346
|
|
|
@@ -284,21 +284,21 @@ There is a new version 3 of Sponsored Product API, please check the [migration g
|
|
|
284
284
|
|
|
285
285
|
### [Modules Available Sponsored Brands 3.0](https://python-amazon-ad-api.readthedocs.io/en/latest/sb_v3.html)
|
|
286
286
|
|
|
287
|
-
* Campaigns(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/campaigns.html)
|
|
288
|
-
* Ad Groups(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/ad_groups.html)
|
|
289
|
-
* Keywords(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/keywords.html)
|
|
290
|
-
* Negative Keywords(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_keywords.html)
|
|
291
|
-
* Product Targeting(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/product_targeting.html)
|
|
292
|
-
* Negative Product Targeting(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_product_targeting.html)
|
|
293
|
-
* Targeting Recommendations(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/targeting_recommendations.html)
|
|
294
|
-
* Bid Recommendations(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/bid_recommendations.html)
|
|
295
|
-
* Stores(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/stores.html)
|
|
296
|
-
* Landing Page Asins(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/landing_page_asins.html)
|
|
297
|
-
* Media(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/media.html)
|
|
298
|
-
* Brands(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/brands.html)
|
|
299
|
-
* Moderation(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/moderation.html)
|
|
300
|
-
* Reports(https://python-amazon-ad-api.readthedocs.io/en/latest/sb/reports.html)
|
|
301
|
-
* Snapshots
|
|
287
|
+
* [Campaigns](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/campaigns.html)
|
|
288
|
+
* [Ad Groups](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/ad_groups.html)
|
|
289
|
+
* [Keywords](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/keywords.html)
|
|
290
|
+
* [Negative Keywords](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_keywords.html)
|
|
291
|
+
* [Product Targeting](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/product_targeting.html)
|
|
292
|
+
* [Negative Product Targeting](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/negative_product_targeting.html)
|
|
293
|
+
* [Targeting Recommendations](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/targeting_recommendations.html)
|
|
294
|
+
* [Bid Recommendations](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/bid_recommendations.html)
|
|
295
|
+
* [Stores](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/stores.html)
|
|
296
|
+
* [Landing Page Asins](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/landing_page_asins.html)
|
|
297
|
+
* [Media](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/media.html)
|
|
298
|
+
* [Brands](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/brands.html)
|
|
299
|
+
* [Moderation](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/moderation.html)
|
|
300
|
+
* [Reports](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/reports.html)
|
|
301
|
+
* [Snapshots](https://python-amazon-ad-api.readthedocs.io/en/latest/sb/snapshots.html)
|
|
302
302
|
|
|
303
303
|
### [Modules Available Sponsored Brands 4.0](https://python-amazon-ad-api.readthedocs.io/en/latest/sb_v4.html)
|
|
304
304
|
|
|
@@ -323,9 +323,9 @@ There is a new version 3 of Sponsored Product API, please check the [migration g
|
|
|
323
323
|
* [Forecasts](https://python-amazon-ad-api.readthedocs.io/en/latest/sd/forecast.html)
|
|
324
324
|
* [Recommendations](https://python-amazon-ad-api.readthedocs.io/en/latest/sd/recommendations.html)
|
|
325
325
|
|
|
326
|
-
### Modules Available DSP
|
|
326
|
+
### [Modules Available DSP](https://python-amazon-ad-api.readthedocs.io/en/latest/dsp.html)
|
|
327
327
|
|
|
328
|
-
* Reports
|
|
328
|
+
* [Reports](https://python-amazon-ad-api.readthedocs.io/en/latest/dsp/reports.html)
|
|
329
329
|
|
|
330
330
|
### Simple Example Usage Campaigns with Credentials
|
|
331
331
|
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
from ad_api.base import Client
|
|
2
|
-
from ad_api.auth.credentials import BaseCredentials
|
|
3
|
-
from ad_api.api.dsp.credential_provider import DspCredentialProvider
|
|
4
|
-
from ad_api.api.dsp.access_token_client import DspAccessTokenClient
|
|
5
2
|
|
|
6
3
|
|
|
7
4
|
class DspClient(Client):
|
|
8
|
-
access_token_client_class = DspAccessTokenClient
|
|
9
|
-
credentials_class = BaseCredentials
|
|
10
|
-
credential_provider_class = DspCredentialProvider
|
|
11
|
-
|
|
12
5
|
@property
|
|
13
6
|
def headers(self):
|
|
14
7
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from ad_api.base import Client, sp_endpoint, fill_query_params, ApiResponse
|
|
1
|
+
from ad_api.base import Client, sp_endpoint, fill_query_params, ApiResponse, Utils
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class Reports(Client):
|
|
@@ -35,7 +35,7 @@ class Reports(Client):
|
|
|
35
35
|
ApiResponse
|
|
36
36
|
|
|
37
37
|
"""
|
|
38
|
-
return self._request(kwargs.pop('path'), data=kwargs.pop('body'), params=kwargs)
|
|
38
|
+
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs)
|
|
39
39
|
|
|
40
40
|
@sp_endpoint('/reporting/reports/{}', method='GET')
|
|
41
41
|
def get_report(self, reportId, **kwargs) -> ApiResponse:
|
|
@@ -13,7 +13,7 @@ class KeywordsV3(Client):
|
|
|
13
13
|
Returns
|
|
14
14
|
ApiResponse
|
|
15
15
|
"""
|
|
16
|
-
json_version = 'application/vnd.spKeyword.
|
|
16
|
+
json_version = 'application/vnd.spKeyword.v' + str(version) + "+json"
|
|
17
17
|
headers = {
|
|
18
18
|
"Accept": json_version,
|
|
19
19
|
"Content-Type": json_version
|
|
@@ -39,7 +39,7 @@ class KeywordsV3(Client):
|
|
|
39
39
|
Returns
|
|
40
40
|
ApiResponse
|
|
41
41
|
"""
|
|
42
|
-
json_version = 'application/vnd.spKeyword.
|
|
42
|
+
json_version = 'application/vnd.spKeyword.v' + str(version) + "+json"
|
|
43
43
|
|
|
44
44
|
headers = {
|
|
45
45
|
"Accept": json_version,
|
|
@@ -67,7 +67,7 @@ class KeywordsV3(Client):
|
|
|
67
67
|
ApiResponse
|
|
68
68
|
"""
|
|
69
69
|
|
|
70
|
-
json_version = 'application/vnd.spKeyword.
|
|
70
|
+
json_version = 'application/vnd.spKeyword.v' + str(version) + "+json"
|
|
71
71
|
headers = {
|
|
72
72
|
"Accept": json_version,
|
|
73
73
|
"Content-Type": json_version
|
|
@@ -93,7 +93,7 @@ class KeywordsV3(Client):
|
|
|
93
93
|
ApiResponse
|
|
94
94
|
"""
|
|
95
95
|
|
|
96
|
-
json_version = 'application/vnd.spKeyword.
|
|
96
|
+
json_version = 'application/vnd.spKeyword.v' + str(version) + "+json"
|
|
97
97
|
headers = {
|
|
98
98
|
"Accept": json_version,
|
|
99
99
|
"Content-Type": json_version
|
{python-amazon-ad-api-0.4.3 → python-amazon-ad-api-0.4.5}/ad_api/auth/access_token_client.py
RENAMED
|
@@ -7,6 +7,8 @@ from ad_api.base import BaseClient
|
|
|
7
7
|
from .credentials import Credentials
|
|
8
8
|
from .access_token_response import AccessTokenResponse
|
|
9
9
|
from .exceptions import AuthorizationError
|
|
10
|
+
# from .credential_provider import CredentialProvider
|
|
11
|
+
|
|
10
12
|
import os
|
|
11
13
|
|
|
12
14
|
cache = TTLCache(maxsize=int(os.environ.get('AD_API_AUTH_CACHE_SIZE', 10)), ttl=3200)
|
|
@@ -20,9 +22,9 @@ class AccessTokenClient(BaseClient):
|
|
|
20
22
|
grant_type = 'refresh_token'
|
|
21
23
|
path = '/auth/o2/token'
|
|
22
24
|
|
|
23
|
-
def __init__(self,
|
|
24
|
-
|
|
25
|
-
self.cred =
|
|
25
|
+
def __init__(self, credentials=None, proxies=None, verify=True, timeout=None):
|
|
26
|
+
|
|
27
|
+
self.cred = Credentials(credentials)
|
|
26
28
|
self.timeout = timeout
|
|
27
29
|
self.proxies = proxies
|
|
28
30
|
self.verify = verify
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import ad_api.version as vd
|
|
2
|
-
from ad_api.base.credential_provider import CredentialProvider
|
|
3
|
-
|
|
4
2
|
|
|
5
3
|
class BaseClient:
|
|
6
4
|
scheme = 'https://'
|
|
7
5
|
method = 'GET'
|
|
8
6
|
content_type = 'application/x-www-form-urlencoded;charset=UTF-8'
|
|
9
7
|
user_agent = 'python-ad-api'
|
|
10
|
-
credential_provider_class = CredentialProvider
|
|
11
8
|
|
|
12
|
-
def __init__(self
|
|
9
|
+
def __init__(self):
|
|
13
10
|
try:
|
|
14
11
|
version = vd.__version__
|
|
15
12
|
self.user_agent += f'-{version}'
|
|
16
13
|
except:
|
|
17
14
|
pass
|
|
18
|
-
self.credentials = self.credential_provider_class(account, credentials).credentials
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
+
from json import JSONDecodeError
|
|
2
3
|
import logging
|
|
3
4
|
from cachetools import TTLCache
|
|
4
5
|
from requests import request
|
|
@@ -6,7 +7,7 @@ from ad_api.auth.credentials import Credentials
|
|
|
6
7
|
from ad_api.auth import AccessTokenClient, AccessTokenResponse
|
|
7
8
|
from .api_response import ApiResponse
|
|
8
9
|
from .base_client import BaseClient
|
|
9
|
-
from .exceptions import get_exception_for_content
|
|
10
|
+
from .exceptions import get_exception_for_code, get_exception_for_content
|
|
10
11
|
from .marketplaces import Marketplaces
|
|
11
12
|
import os
|
|
12
13
|
import requests
|
|
@@ -15,15 +16,13 @@ import gzip
|
|
|
15
16
|
from zipfile import ZipFile
|
|
16
17
|
import zipfile
|
|
17
18
|
from urllib.parse import urlparse, quote
|
|
19
|
+
from ad_api.base.credential_provider import CredentialProvider
|
|
18
20
|
|
|
19
21
|
log = logging.getLogger(__name__)
|
|
20
22
|
role_cache = TTLCache(maxsize=int(os.environ.get('AD_API_AUTH_CACHE_SIZE', 10)), ttl=3200)
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
class Client(BaseClient):
|
|
24
|
-
access_token_client_class = AccessTokenClient
|
|
25
|
-
credentials_class = Credentials
|
|
26
|
-
grantless_scope = ''
|
|
27
26
|
|
|
28
27
|
def __init__(
|
|
29
28
|
self,
|
|
@@ -37,17 +36,15 @@ class Client(BaseClient):
|
|
|
37
36
|
debug=False
|
|
38
37
|
):
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
self.
|
|
42
|
-
|
|
43
|
-
self._auth = self.access_token_client_class(
|
|
44
|
-
account=account,
|
|
45
|
-
credentials=credentials,
|
|
46
|
-
credentials_class=self.credentials_class,
|
|
39
|
+
self.credentials = CredentialProvider(account, credentials).credentials
|
|
40
|
+
self._auth = AccessTokenClient(
|
|
41
|
+
credentials=self.credentials,
|
|
47
42
|
proxies=proxies,
|
|
48
43
|
verify=verify,
|
|
49
44
|
timeout=timeout,
|
|
50
45
|
)
|
|
46
|
+
self.endpoint = marketplace.endpoint
|
|
47
|
+
self.debug = debug
|
|
51
48
|
self.timeout = timeout
|
|
52
49
|
self.proxies = proxies
|
|
53
50
|
self.verify = verify
|
|
@@ -56,9 +53,9 @@ class Client(BaseClient):
|
|
|
56
53
|
def headers(self):
|
|
57
54
|
return {
|
|
58
55
|
'User-Agent': self.user_agent,
|
|
59
|
-
'Amazon-Advertising-API-ClientId': self.credentials
|
|
56
|
+
'Amazon-Advertising-API-ClientId': self.credentials['client_id'],
|
|
60
57
|
'Authorization': 'Bearer %s' % self.auth.access_token,
|
|
61
|
-
'Amazon-Advertising-API-Scope': self.credentials
|
|
58
|
+
'Amazon-Advertising-API-Scope': self.credentials['profile_id'],
|
|
62
59
|
'Content-Type': 'application/json'
|
|
63
60
|
}
|
|
64
61
|
|
|
@@ -263,6 +260,7 @@ class Client(BaseClient):
|
|
|
263
260
|
if self.debug:
|
|
264
261
|
logging.info(headers or self.headers)
|
|
265
262
|
|
|
263
|
+
|
|
266
264
|
if params:
|
|
267
265
|
str_query = ""
|
|
268
266
|
for key, value in params.items():
|
|
@@ -275,69 +273,48 @@ class Client(BaseClient):
|
|
|
275
273
|
if data is not None:
|
|
276
274
|
logging.info(data)
|
|
277
275
|
|
|
278
|
-
|
|
276
|
+
logging.info(vars(res))
|
|
279
277
|
|
|
280
|
-
|
|
281
|
-
def _check_response(self, res) -> ApiResponse:
|
|
278
|
+
return self._check_response(res)
|
|
282
279
|
|
|
283
|
-
|
|
284
|
-
|
|
280
|
+
@staticmethod
|
|
281
|
+
def _check_response(res) -> ApiResponse:
|
|
285
282
|
|
|
286
283
|
content = vars(res).get('_content')
|
|
287
|
-
|
|
284
|
+
headers = vars(res).get('headers')
|
|
285
|
+
status_code = vars(res).get('status_code')
|
|
288
286
|
|
|
289
|
-
if
|
|
287
|
+
if 200 <= res.status_code < 300:
|
|
290
288
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
289
|
+
try:
|
|
290
|
+
js = res.json() or {}
|
|
291
|
+
except JSONDecodeError:
|
|
292
|
+
js = {}
|
|
294
293
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
294
|
+
try:
|
|
295
|
+
error = js.get('error', None) # Dict.get(key, default=None)
|
|
296
|
+
except AttributeError:
|
|
297
|
+
error = None
|
|
299
298
|
|
|
300
|
-
|
|
299
|
+
if error:
|
|
300
|
+
exception = get_exception_for_content(error[0].get('code'))
|
|
301
|
+
raise exception(error[0].get('code'), error[0], headers)
|
|
301
302
|
|
|
302
|
-
|
|
303
|
-
exception = get_exception_for_content(data)
|
|
304
|
-
raise exception(data)
|
|
303
|
+
next_token = vars(res).get('_next')
|
|
305
304
|
|
|
306
|
-
|
|
307
|
-
exception = get_exception_for_content(data)
|
|
308
|
-
raise exception(data)
|
|
305
|
+
return ApiResponse(js, next_token, headers=headers)
|
|
309
306
|
|
|
310
|
-
|
|
311
|
-
dictionary = {"status_code": vars(res).get('status_code'), "code": data.get('code'), "details": data.get('details'), "requestId": data.get('requestId')}
|
|
312
|
-
exception = get_exception_for_content(data)
|
|
313
|
-
raise exception(dictionary)
|
|
307
|
+
else:
|
|
314
308
|
|
|
315
|
-
|
|
316
|
-
dictionary = {"status_code": vars(res).get('status_code'), "code": data.get('code'), "details": data.get('details'), "requestId": data.get('requestId')}
|
|
317
|
-
exception = get_exception_for_content(data)
|
|
318
|
-
raise exception(dictionary)
|
|
309
|
+
exception = get_exception_for_code(res.status_code)
|
|
319
310
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
311
|
+
try:
|
|
312
|
+
js = res.json()
|
|
313
|
+
except JSONDecodeError:
|
|
314
|
+
js = res.content
|
|
324
315
|
|
|
325
|
-
if type(data) is dict and data.get('details') == 'Invalid authorization inputs' and vars(res).get('_content_consumed') is True:
|
|
326
|
-
dictionary = {"status_code": vars(res).get('status_code'), "message": "Invalid authorization inputs"}
|
|
327
|
-
exception = get_exception_for_content(dictionary)
|
|
328
|
-
raise exception(dictionary)
|
|
329
316
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
exception = get_exception_for_content(dictionary)
|
|
333
|
-
raise exception(dictionary)
|
|
317
|
+
raise exception(status_code, js, headers)
|
|
318
|
+
exit(res.status_code)
|
|
334
319
|
|
|
335
|
-
if type(data) is dict and data.get('details') == 'Cannot consume content type' and vars(res).get('_content_consumed') is True:
|
|
336
|
-
dictionary = {"status_code": vars(res).get('status_code'), "message": data.get('details')}
|
|
337
|
-
exception = get_exception_for_content(dictionary)
|
|
338
|
-
raise exception(dictionary)
|
|
339
320
|
|
|
340
|
-
headers = vars(res).get('headers')
|
|
341
|
-
status_code = vars(res).get('status_code')
|
|
342
|
-
next_token = vars(res).get('_next')
|
|
343
|
-
return ApiResponse(data, next_token, headers=headers)
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import functools
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import pprint
|
|
6
|
+
|
|
7
|
+
from typing import Dict, Iterable, Optional, Type
|
|
8
|
+
|
|
9
|
+
import confuse
|
|
10
|
+
import logging
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
required_credentials = [
|
|
14
|
+
'refresh_token',
|
|
15
|
+
'client_id',
|
|
16
|
+
'client_secret',
|
|
17
|
+
'profile_id'
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MissingCredentials(Exception):
|
|
22
|
+
"""
|
|
23
|
+
Credentials are missing, see the error output to find possible causes
|
|
24
|
+
"""
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BaseCredentialProvider(abc.ABC):
|
|
29
|
+
|
|
30
|
+
def __init__(self, credentials: dict or str, *args, **kwargs):
|
|
31
|
+
self.credentials = credentials
|
|
32
|
+
|
|
33
|
+
@abc.abstractmethod
|
|
34
|
+
def load_credentials(self):
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _get_env(self, key):
|
|
39
|
+
return os.environ.get(f'{key}',
|
|
40
|
+
os.environ.get(key))
|
|
41
|
+
|
|
42
|
+
def check_credentials(self):
|
|
43
|
+
try:
|
|
44
|
+
self.errors = [c for c in required_credentials if
|
|
45
|
+
c not in self.credentials.keys() or not self.credentials[c]]
|
|
46
|
+
except (AttributeError, TypeError):
|
|
47
|
+
raise MissingCredentials(f'Credentials are missing: {", ".join(required_credentials)}')
|
|
48
|
+
if not len(self.errors):
|
|
49
|
+
return self.credentials
|
|
50
|
+
raise MissingCredentials(f'Credentials are missing: {", ".join(self.errors)}')
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class FromEnvCredentialProvider(BaseCredentialProvider):
|
|
55
|
+
|
|
56
|
+
def __init__(self, *args, **kwargs):
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
def load_credentials(self):
|
|
60
|
+
account_data = dict(
|
|
61
|
+
refresh_token=self._get_env('AD_API_REFRESH_TOKEN'),
|
|
62
|
+
client_id=self._get_env('AD_API_CLIENT_ID'),
|
|
63
|
+
client_secret=self._get_env('AD_API_CLIENT_SECRET'),
|
|
64
|
+
profile_id=self._get_env('AD_API_PROFILE_ID'),
|
|
65
|
+
)
|
|
66
|
+
self.credentials = account_data
|
|
67
|
+
self.check_credentials()
|
|
68
|
+
return self.credentials
|
|
69
|
+
|
|
70
|
+
def _get_env(self, key):
|
|
71
|
+
return os.environ.get(f'{key}',
|
|
72
|
+
os.environ.get(key))
|
|
73
|
+
|
|
74
|
+
class FromCodeCredentialProvider(BaseCredentialProvider):
|
|
75
|
+
|
|
76
|
+
def __init__(self, credentials: dict, *args, **kwargs):
|
|
77
|
+
super().__init__(credentials)
|
|
78
|
+
|
|
79
|
+
def load_credentials(self):
|
|
80
|
+
self.check_credentials()
|
|
81
|
+
return self.credentials
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class FromConfigFileCredentialProvider(BaseCredentialProvider):
|
|
85
|
+
|
|
86
|
+
file = 'credentials.yml' # Will moved to default confuse config.yaml
|
|
87
|
+
|
|
88
|
+
def __init__(self, account: str, *args, **kwargs):
|
|
89
|
+
self.account = account
|
|
90
|
+
|
|
91
|
+
def load_credentials(self):
|
|
92
|
+
try:
|
|
93
|
+
config = confuse.Configuration('python-ad-api')
|
|
94
|
+
config_filename = os.path.join(config.config_dir(), self.file)
|
|
95
|
+
config.set_file(config_filename)
|
|
96
|
+
account_data = config[self.account].get()
|
|
97
|
+
super().__init__(account_data)
|
|
98
|
+
self.check_credentials()
|
|
99
|
+
return (account_data)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
except confuse.exceptions.NotFoundError:
|
|
103
|
+
raise MissingCredentials(f'The account {self.account} was not setup in your configuration file.')
|
|
104
|
+
except confuse.exceptions.ConfigReadError:
|
|
105
|
+
raise MissingCredentials(
|
|
106
|
+
f'Neither environment variables nor a config file were found. '
|
|
107
|
+
f'Please set the correct variables, or use a config file (credentials.yml). '
|
|
108
|
+
f'See https://confuse.readthedocs.io/en/latest/usage.html#search-paths for search paths.'
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class CredentialProvider():
|
|
113
|
+
|
|
114
|
+
def load_credentials(self):
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
def _get_env(self, key):
|
|
118
|
+
return os.environ.get(f'{key}',
|
|
119
|
+
os.environ.get(key))
|
|
120
|
+
|
|
121
|
+
def __init__(
|
|
122
|
+
self,
|
|
123
|
+
account: str = 'default',
|
|
124
|
+
credentials: Optional[Dict[str, str]] = None,
|
|
125
|
+
):
|
|
126
|
+
|
|
127
|
+
client_id_env = self._get_env('AD_API_CLIENT_ID'),
|
|
128
|
+
client_secret_env = self._get_env('AD_API_CLIENT_SECRET')
|
|
129
|
+
|
|
130
|
+
if client_id_env is not None and client_secret_env is not None:
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
self.credentials = FromEnvCredentialProvider().load_credentials()
|
|
134
|
+
except MissingCredentials:
|
|
135
|
+
logging.error("MissingCredentials")
|
|
136
|
+
logging.error(MissingCredentials)
|
|
137
|
+
|
|
138
|
+
elif isinstance(credentials, dict):
|
|
139
|
+
try:
|
|
140
|
+
self.credentials = FromCodeCredentialProvider(credentials).load_credentials()
|
|
141
|
+
|
|
142
|
+
except MissingCredentials:
|
|
143
|
+
logging.error("MissingCredentials")
|
|
144
|
+
logging.error(MissingCredentials)
|
|
145
|
+
|
|
146
|
+
else:
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
self.credentials = FromConfigFileCredentialProvider(account).load_credentials()
|
|
150
|
+
|
|
151
|
+
except MissingCredentials:
|
|
152
|
+
logging.error("MissingCredentials")
|
|
153
|
+
logging.error(MissingCredentials)
|
|
154
|
+
|
|
155
|
+
class Config:
|
|
156
|
+
def __init__(self, **kwargs):
|
|
157
|
+
self.refresh_token = kwargs.get('refresh_token')
|
|
158
|
+
self.client_id = kwargs.get('client_id')
|
|
159
|
+
self.client_secret = kwargs.get('client_secret')
|
|
160
|
+
self.profile_id = kwargs.get('profile_id')
|