python-amazon-sp-api 1.9.47__py3-none-any.whl → 1.9.48__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-amazon-sp-api
3
- Version: 1.9.47
3
+ Version: 1.9.48
4
4
  Summary: Python wrapper for the Amazon Selling-Partner API
5
5
  Home-page: https://github.com/saleweaver/python-amazon-sp-api
6
6
  Author: Michael
@@ -1,7 +1,7 @@
1
- python_amazon_sp_api-1.9.47.data/scripts/make_endpoint,sha256=QWcwG6z4RWFJlzj4-xyHJymjObyKtwkvWFRq8T18iG0,8568
2
- python_amazon_sp_api-1.9.47.dist-info/licenses/LICENSE,sha256=nbzomPIVo1PVl5bpGAntofsYAF7ZQ2UhzOtKgf7IiNw,1071
1
+ python_amazon_sp_api-1.9.48.data/scripts/make_endpoint,sha256=QWcwG6z4RWFJlzj4-xyHJymjObyKtwkvWFRq8T18iG0,8568
2
+ python_amazon_sp_api-1.9.48.dist-info/licenses/LICENSE,sha256=nbzomPIVo1PVl5bpGAntofsYAF7ZQ2UhzOtKgf7IiNw,1071
3
3
  sp_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- sp_api/__version__.py,sha256=eXmKlD4iSXqkxowZW-Oce1KSzEwGlZglsxemACIdvVc,23
4
+ sp_api/__version__.py,sha256=0xnicgHViArTE7XX9oDWtL51xlVbR4WryMZRKpTyisk,23
5
5
  sp_api/api/__init__.py,sha256=t29_Sr8XGPM2fD9tmD12Xb5hrOevyPRMK67cGbzc8vw,4560
6
6
  sp_api/api/amazon_warehousing_and_distribu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  sp_api/api/amazon_warehousing_and_distribu/amazon_warehousing_and_distribu.py,sha256=bMBIxIj0eu6Gi6WY3XLdHHYDzNCwz0-9X59Jo9DoqfE,5863
@@ -123,26 +123,7 @@ sp_api/util/key_maker.py,sha256=T4I2rdBZzvWtX32qgrv9DA5EzVK3LEAWtbRffup-_kE,2172
123
123
  sp_api/util/load_all_pages.py,sha256=K6Suml4_GWZ5L9-YcnhaM9q-dA7Xr6wNLE-kWP_8MPk,1839
124
124
  sp_api/util/load_date_bound.py,sha256=j9gu9WucENqU9xaQ-xG7c4yK4RB-FXK39_r1mLT76z0,1726
125
125
  sp_api/util/retry.py,sha256=V8SeSeX3Brdou138hNA5HeQkKlHppZcqbZobIDjmBYw,2407
126
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
- tests/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
- tests/api/finances/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- tests/api/finances/test_finances.py,sha256=pbbQKZzFWPrylw_JbCekCwingPBvMJ5ON8cp_X7iUyg,584
130
- tests/api/notifications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
- tests/api/notifications/test_notifications.py,sha256=ln4sM3Rfspax_QCARkmrqOKBWfYx_a-4KNje5YJ9Io8,1293
132
- tests/api/orders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
133
- tests/api/orders/test_orders.py,sha256=j568TSG55x8afPhlFmwTyjVBmMdo6pcAr1esGH3RlUo,3717
134
- tests/api/product_fees/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
135
- tests/api/product_fees/product_fees.py,sha256=3d4alLRlAQzfbmxWu2LWGVg4jsozc6A5BvmkJLtt9cM,2542
136
- tests/api/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
- tests/api/reports/test_reports.py,sha256=Ni0QpflVEJlZYk696cKTe5BasoeSWAyXxpxSJnFcGHI,3974
138
- tests/api/sellers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
- tests/api/sellers/test_sellers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
140
- tests/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
141
- tests/client/test_auth.py,sha256=fI4Lo5Z6O0GfqIldPlCe1OAoZRfAvMRjomo-mGfQxfs,1993
142
- tests/client/test_base.py,sha256=SaXsycFpNYWy8zEYGVzb0aYUZuhJ4qz1_8oAvy6XAvg,4905
143
- tests/client/test_credential_provider.py,sha256=qSBVgDEaR7_C2CmJOY7KAmxNMOfVeE4qG0hfXH3Gk2o,1476
144
- tests/client/test_helpers.py,sha256=RzpnytJGSEIFDRqcMm2QpdIqZubDfNNQRNVgvZPX3K0,3731
145
- python_amazon_sp_api-1.9.47.dist-info/METADATA,sha256=SEO6CnQuHIi0DtPMMS6wGO-uMW1JsDllcNUpGLdSI-M,5994
146
- python_amazon_sp_api-1.9.47.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
147
- python_amazon_sp_api-1.9.47.dist-info/top_level.txt,sha256=oZPLMXOmLpAhwQ2La20WfRtlOYlnjub0v419-qPfwkw,13
148
- python_amazon_sp_api-1.9.47.dist-info/RECORD,,
126
+ python_amazon_sp_api-1.9.48.dist-info/METADATA,sha256=dtVGjPH7e0BPDV1oAL5mi0or4zia3KCSCFsnx8y92NE,5994
127
+ python_amazon_sp_api-1.9.48.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
128
+ python_amazon_sp_api-1.9.48.dist-info/top_level.txt,sha256=mEzPMFyyy0LmJGY4KFXfh5usUka4eeouIr7-2IAzoE0,7
129
+ python_amazon_sp_api-1.9.48.dist-info/RECORD,,
sp_api/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.9.47'
1
+ __version__ = '1.9.48'
tests/__init__.py DELETED
File without changes
tests/api/__init__.py DELETED
File without changes
File without changes
@@ -1,19 +0,0 @@
1
- import json
2
- from datetime import datetime, timedelta
3
-
4
- from sp_api.api import Finances
5
- from sp_api.base import SellingApiBadRequestException
6
-
7
-
8
- def test_for_order():
9
- res = Finances().get_financial_events_for_order('485-734-5434857', MaxResultsPerPage=10)
10
- assert res.payload.get('NextToken') == 'Next token value'
11
-
12
-
13
- def test_for_order_expect_400():
14
- try:
15
- Finances().get_financial_events_for_order('BAD-ORDER', MaxResultsPerPage=10)
16
- except SellingApiBadRequestException as br:
17
- assert br.code == 400
18
- assert type(br) == SellingApiBadRequestException
19
-
File without changes
@@ -1,26 +0,0 @@
1
- from sp_api.api import Notifications, Reports, Finances
2
- from sp_api.base import SellingApiException, NotificationType, ReportType, Marketplaces
3
- from sp_api.util import throttle_retry, load_all_pages
4
-
5
-
6
- def test_create_destination():
7
- res = Notifications().create_destination(name='test', arn='arn:aws:sqs:us-east-2:444455556666:queue1')
8
- assert res.payload.get("destinationId") == "TEST_CASE_200_DESTINATION_ID"
9
- assert res.payload.get("resource").get('sqs').get('arn') == "arn:aws:sqs:us-east-2:444455556666:queue1"
10
-
11
-
12
- def test_create_subscription():
13
- res = Notifications().create_subscription(NotificationType.MFN_ORDER_STATUS_CHANGE, destination_id='dest_id')
14
- assert res.payload.get('destinationId') == 'TEST_CASE_200_DESTINATION_ID'
15
- assert res.payload.get('subscriptionId') == 'TEST_CASE_200_SUBSCRIPTION_ID'
16
-
17
-
18
- def test_delete_subscription():
19
- res = Notifications().delete_notification_subscription(NotificationType.MFN_ORDER_STATUS_CHANGE, 'subscription_id')
20
- assert res.errors is None
21
-
22
-
23
- def test_get_subscriptions():
24
- res = Notifications().get_subscription(NotificationType.REPORT_PROCESSING_FINISHED)
25
- assert res.payload.get('destinationId') == 'TEST_CASE_200_DESTINATION_ID'
26
- assert res.payload.get('subscriptionId') == 'TEST_CASE_200_SUBSCRIPTION_ID'
File without changes
@@ -1,122 +0,0 @@
1
- from sp_api.api import Orders
2
-
3
-
4
- def test_get_orders():
5
- res = Orders().get_orders(CreatedAfter='TEST_CASE_200', MarketplaceIds=["ATVPDKIKX0DER"])
6
- assert res.errors is None
7
- assert res.payload.get('Orders') is not None
8
-
9
-
10
- def test_get_order_items():
11
- res = Orders().get_order_items('TEST_CASE_200')
12
- assert res.errors is None
13
- assert res.payload.get('AmazonOrderId') is not None
14
-
15
-
16
- def test_get_order_address():
17
- res = Orders().get_order_address('TEST_CASE_200')
18
- assert res.errors is None
19
- assert res.payload.get('AmazonOrderId') is not None
20
-
21
-
22
- def test_get_order_buyer_info():
23
- res = Orders().get_order_buyer_info('TEST_CASE_200')
24
- assert res.errors is None
25
- assert res.payload.get('AmazonOrderId') is not None
26
-
27
-
28
- def test_get_order():
29
- res = Orders().get_order('TEST_CASE_200')
30
- assert res.errors is None
31
- assert res.payload.get('AmazonOrderId') is not None
32
-
33
-
34
- def test_get_order_items_buyer_info():
35
- res = Orders().get_order_items_buyer_info('TEST_CASE_200')
36
- assert res.errors is None
37
- assert res.payload.get('AmazonOrderId') is not None
38
-
39
-
40
- def test_get_orders_400_error():
41
- from sp_api.base import SellingApiBadRequestException
42
- try:
43
- Orders().get_orders(CreatedAfter='TEST_CASE_400')
44
- except SellingApiBadRequestException as sep:
45
- assert sep.code == 400
46
- assert sep.amzn_code == 'InvalidInput'
47
-
48
-
49
- def test_get_order_api_response_call():
50
- res = Orders().get_order('TEST_CASE_200')
51
- print(res('DefaultShipFromLocationAddress'))
52
- assert res('DefaultShipFromLocationAddress') is not None
53
- assert res.errors is None
54
- assert res.payload.get('AmazonOrderId') is not None
55
-
56
-
57
- def test_get_orders_attr():
58
- res = Orders().get_orders(CreatedAfter='TEST_CASE_200', MarketplaceIds=["ATVPDKIKX0DER"])
59
- assert res.Orders is not None
60
- assert res.errors is None
61
- assert res.payload.get('Orders') is not None
62
-
63
-
64
- def test_get_order_api_response_call2():
65
- res = Orders().get_order('TEST_CASE_200')
66
- assert res() is not None
67
- assert isinstance(res(), dict)
68
- assert res.errors is None
69
- assert res.payload.get('AmazonOrderId') is not None
70
-
71
-
72
- def test_update_shipment_status():
73
- res = Orders().update_shipment_status(
74
- order_id='123-1234567-1234567',
75
- marketplaceId='ATVPDKIKX0DER',
76
- shipmentStatus='ReadyForPickup'
77
- )
78
- assert res() is not None
79
- assert isinstance(res(), dict)
80
- assert res.errors is None
81
- assert res.payload.get("status_code") == 204
82
-
83
-
84
- def test_confirm_shipment():
85
- res = Orders().confirm_shipment(
86
- order_id='123-1234567-1234567',
87
- marketplaceId='ATVPDKIKX0DER',
88
- packageDetail={
89
- 'packageReferenceId': '0001',
90
- 'carrierCode': 'DHL',
91
- "shippingMethod": 'Paket',
92
- 'trackingNumber': '1234567890',
93
- 'shipDate': '2023-03-19T12:00:00Z',
94
- 'orderItems': [
95
- {
96
- 'orderItemId': '123456789',
97
- 'quantity': 1
98
- },
99
- {
100
- 'orderItemId': '2345678901',
101
- 'quantity': 2
102
- },
103
- ]
104
- }
105
- )
106
- assert res() is not None
107
- assert isinstance(res(), dict)
108
- assert res.errors is None
109
- assert res.payload.get("status_code") is None
110
-
111
-
112
- def test_update_shipment_status_400_error():
113
- from sp_api.base import SellingApiBadRequestException
114
- try:
115
- Orders().update_shipment_status(
116
- order_id='123-1234567-1234567',
117
- marketplaceId='1',
118
- shipmentStatus='ReadyForPickup'
119
- )
120
- except SellingApiBadRequestException as sep:
121
- assert sep.code == 400
122
- assert sep.amzn_code == 'InvalidInput'
File without changes
@@ -1,49 +0,0 @@
1
- from sp_api.api import ProductFees
2
- from sp_api.base import Marketplaces
3
-
4
-
5
- def test_get_fees_for_sku():
6
- res = ProductFees().get_product_fees_estimate_for_sku("UmaS1", 10, currency='USD', shipping_price=10, is_fba=False,
7
- points={
8
- "PointsNumber": 0,
9
- "PointsMonetaryValue": {
10
- "CurrencyCode": "USD",
11
- "Amount": 0
12
- }
13
- })
14
- assert res.payload.get('FeesEstimateResult').get('Status') == 'Success'
15
-
16
-
17
- def test_get_fees_for_asin():
18
- res = ProductFees().get_product_fees_estimate_for_asin("UmaS1", 10, currency='USD', shipping_price=10, is_fba=False,
19
- points={
20
- "PointsNumber": 0,
21
- "PointsMonetaryValue": {
22
- "CurrencyCode": "USD",
23
- "Amount": 0
24
- }
25
- })
26
- assert res.payload.get('FeesEstimateResult').get('Status') == 'Success'
27
-
28
-
29
- def test_get_product_fees_estimate():
30
- res = ProductFees().get_product_fees_estimate([
31
- dict(identifier='UmaS1',id_type='ASIN',id_value="asin123", price=10, currency='USD', shipping_price=10, is_fba=False,
32
- points={
33
- "PointsNumber": 0,
34
- "PointsMonetaryValue": {
35
- "CurrencyCode": "USD",
36
- "Amount": 0
37
- }}
38
- ),
39
- dict(identifier='UmaS2', marketplace_id=Marketplaces.MX.marketplace_id, id_type='SellerSKU', id_value="sku123", price=10, currency='MXN', shipping_price=10, is_fba=True,
40
- points={
41
- "PointsNumber": 0,
42
- "PointsMonetaryValue": {
43
- "CurrencyCode": "MXN",
44
- "Amount": 0
45
- }}
46
- ),
47
- ])
48
- for fer in res.payload:
49
- assert fer['Status'] == 'Success'
File without changes
@@ -1,127 +0,0 @@
1
- from sp_api.api import Reports
2
- from sp_api.base import Marketplaces, Schedules, SellingApiBadRequestException, SellingApiServerException, \
3
- ProcessingStatus
4
- from sp_api.base.reportTypes import ReportType
5
-
6
-
7
- def test_create_report():
8
- res = Reports().create_report(
9
- reportType=ReportType.GET_MERCHANT_LISTINGS_ALL_DATA,
10
- dataStartTime='2019-12-10T20:11:24.000Z',
11
- marketplaceIds=[
12
- "A1PA6795UKMFR9",
13
- "ATVPDKIKX0DER"
14
- ])
15
- assert res.payload.get('reportId') == 'ID323'
16
-
17
-
18
- def test_create_report_expect_400():
19
- try:
20
- Reports().create_report(
21
- reportType="BAD_FEE_DISCOUNTS_REPORT",
22
- dataStartTime="2019-12-10T20:11:24.000Z",
23
- marketplaceIds=[
24
- "A1PA6795UKMFR9",
25
- "ATVPDKIKX0DER"
26
- ])
27
- except SellingApiBadRequestException as br:
28
- assert br.code == 400
29
-
30
-
31
- def test_create_report_expect_500():
32
- try:
33
- Reports().create_report(
34
- reportType="BAD_FEE_DISCasdafsdsfsdfsdOUNTS_REPORT",
35
- dataStartTime="2019-12-10T20:11:24.000Z",
36
- marketplaceIds=[
37
- "A1PA6asfd795UKMFR9",
38
- "ATVPDKIKX0DER"
39
- ])
40
- except SellingApiServerException as br:
41
- assert br.code == 500
42
-
43
-
44
- def test_get_report():
45
- res = Reports().get_report('ID323')
46
- assert res.payload.get('reportId') == 'ReportId1'
47
- assert res.payload.get('reportType') == 'FEE_DISCOUNTS_REPORT'
48
-
49
-
50
- def test_get_report_document_n_decrypt():
51
- res = Reports().get_report_document('0356cf79-b8b0-4226-b4b9-0ee058ea5760', decrypt=False)
52
- assert res.errors is None
53
- assert 'document' not in res.payload
54
-
55
-
56
- def test_create_report_schedule():
57
- res = Reports().create_report_schedule(reportType='FEE_DISCOUNTS_REPORT',
58
- period=Schedules.MINUTES_5.value,
59
- nextReportCreationTime="2019-12-10T20:11:24.000Z",
60
- marketplaceIds=["A1PA6795UKMFR9", "ATVPDKIKX0DER"])
61
- assert res.errors is None
62
- assert 'reportScheduleId' in res.payload
63
-
64
-
65
- def test_delete_schedule_by_id():
66
- res = Reports().delete_report_schedule('ID')
67
- assert res.errors is None
68
-
69
-
70
- def test_get_schedule_by_id():
71
- res = Reports().get_report_schedule('ID323')
72
- assert res.errors is None
73
- assert 'period' in res.payload
74
- assert res.payload.get('reportType') == 'FEE_DISCOUNTS_REPORT'
75
-
76
-
77
- def test_get_reports_1():
78
- report_types = [
79
- "FEE_DISCOUNTS_REPORT",
80
- "GET_AFN_INVENTORY_DATA"
81
- ]
82
- processing_status = [
83
- "IN_QUEUE",
84
- "IN_PROGRESS"
85
- ]
86
- res = Reports().get_reports(reportTypes=report_types, processingStatuses=processing_status)
87
- assert res.errors is None
88
-
89
-
90
- def test_get_reports_2():
91
- report_types = [
92
- "FEE_DISCOUNTS_REPORT",
93
- "GET_AFN_INVENTORY_DATA"
94
- ]
95
- processing_status = [
96
- ProcessingStatus.IN_QUEUE,
97
- ProcessingStatus.IN_PROGRESS
98
- ]
99
- res = Reports().get_reports(reportTypes=report_types, processingStatuses=processing_status)
100
- assert res.errors is None
101
-
102
-
103
- def test_get_reports_3():
104
- report_types = [
105
- ReportType.FEE_DISCOUNTS_REPORT,
106
- ReportType.GET_AFN_INVENTORY_DATA
107
- ]
108
- processing_status = [
109
- ProcessingStatus.IN_QUEUE,
110
- ProcessingStatus.IN_PROGRESS
111
- ]
112
- res = Reports().get_reports(reportTypes=report_types, processingStatuses=processing_status)
113
- assert res.errors is None
114
-
115
-
116
- def test_get_reports_4():
117
- report_types = [
118
- ReportType.FEE_DISCOUNTS_REPORT,
119
- ReportType.GET_AFN_INVENTORY_DATA
120
- ]
121
- processing_status = [
122
- ProcessingStatus.IN_QUEUE,
123
- ProcessingStatus.IN_PROGRESS
124
- ]
125
- res = Reports().get_reports(reportTypes=report_types, processingStatuses=processing_status,
126
- marketplaceIds=[Marketplaces.US, Marketplaces.US.marketplace_id])
127
- assert res.errors is None
File without changes
File without changes
tests/client/__init__.py DELETED
File without changes
tests/client/test_auth.py DELETED
@@ -1,59 +0,0 @@
1
- from sp_api.base import AccessTokenClient
2
- from sp_api.base import Credentials, CredentialProvider
3
- from sp_api.base import AuthorizationError
4
- from sp_api.base.credential_provider import BaseCredentialProvider, FromCodeCredentialProvider
5
-
6
-
7
- refresh_token = '<refresh_token>'
8
- lwa_app_id = '<lwa_app_id>'
9
- lwa_client_secret = '<lwa_client_secret>'
10
-
11
-
12
- def test_auth_exception():
13
- e = AuthorizationError(200, 'Foo', 999)
14
- assert e.status_code == 999
15
- assert e.error_code == 200
16
- assert e.message == 'Foo'
17
-
18
-
19
- def test_credentials():
20
- x = CredentialProvider()
21
- assert x.credentials is not None
22
- assert x.credentials.lwa_app_id is not None
23
- assert x.credentials.lwa_client_secret is not None
24
-
25
-
26
- def test_credentials_with_custom_provider():
27
- class CustomCredentialProvider(BaseCredentialProvider):
28
- def load_credentials(self):
29
- self.credentials = {
30
- "refresh_token": refresh_token,
31
- "lwa_app_id": lwa_app_id,
32
- "lwa_client_secret": lwa_client_secret,
33
- }
34
-
35
- cp = CredentialProvider(credential_providers=(CustomCredentialProvider,))
36
- assert cp.credentials is not None
37
- assert cp.credentials.refresh_token == "<refresh_token>"
38
- assert cp.credentials.lwa_app_id == "<lwa_app_id>"
39
- assert cp.credentials.lwa_client_secret == "<lwa_client_secret>"
40
-
41
-
42
- def test_auth_client():
43
- client = AccessTokenClient(credentials=CredentialProvider(credentials=dict(
44
- refresh_token=refresh_token,
45
- lwa_app_id=lwa_app_id,
46
- lwa_client_secret=lwa_client_secret,
47
- )).credentials)
48
- x = client._auth_code_request_body('foo')
49
- assert x.get('grant_type') == 'authorization_code'
50
-
51
- try:
52
- client.authorize_auth_code('foo')
53
- except AuthorizationError as e:
54
- assert isinstance(e, AuthorizationError)
55
-
56
- try:
57
- client._request('https://jsonplaceholder.typicode.com/posts/1', {}, {})
58
- except AuthorizationError as e:
59
- assert isinstance(e, AuthorizationError)
tests/client/test_base.py DELETED
@@ -1,163 +0,0 @@
1
- import os
2
- import pytest
3
-
4
- from sp_api.api import FulfillmentInbound
5
- from sp_api.base import AccessTokenClient
6
- from sp_api.base import Marketplaces, MissingCredentials, Client, SellingApiForbiddenException
7
- from sp_api.base.credential_provider import FromCodeCredentialProvider, FromEnvironmentVariablesCredentialProvider, \
8
- FromSecretsCredentialProvider, FromConfigFileCredentialProvider, required_credentials
9
- from sp_api.base.exceptions import MissingScopeException
10
-
11
- refresh_token = '<refresh_token>'
12
- lwa_app_id = '<lwa_app_id>'
13
- lwa_client_secret = '<lwa_client_secret>'
14
-
15
-
16
- class Res:
17
- status_code = 200
18
- method = 'GET'
19
- headers = {}
20
- def json(self):
21
- return {'foo': 'bar'}
22
-
23
- def __getattr__(self, item):
24
- return item
25
-
26
-
27
- def test_client_request():
28
- try:
29
- Client()._request('', data=dict())
30
- except SellingApiForbiddenException as e:
31
- assert isinstance(e, SellingApiForbiddenException)
32
-
33
-
34
- def test_client_timeout():
35
- client = Client(timeout=1)
36
- assert client.timeout == 1
37
- client = Client()
38
- assert client.timeout is None
39
-
40
-
41
- def test_api_response_has_next_token():
42
- res = FulfillmentInbound().get_shipments(QueryType='SHIPMENT')
43
- assert res.next_token is not None
44
-
45
-
46
- def test_marketplaces():
47
- assert Marketplaces.DE.region == 'eu-west-1'
48
- assert Marketplaces.US.marketplace_id == 'ATVPDKIKX0DER'
49
-
50
-
51
- def test_from_code_credential_provider():
52
- p = FromCodeCredentialProvider(credentials=dict(
53
- refresh_token=refresh_token,
54
- lwa_app_id=lwa_app_id,
55
- lwa_client_secret=lwa_client_secret,
56
- ))
57
- assert p.credentials is not None
58
- assert isinstance(p.credentials, dict)
59
-
60
-
61
- def test_from_code_credential_provider_no_refresh_token():
62
- p = FromCodeCredentialProvider(credentials=dict(
63
- lwa_app_id=lwa_app_id,
64
- lwa_client_secret=lwa_client_secret,
65
- ))
66
- assert p.credentials is not None
67
- assert isinstance(p.credentials, dict)
68
- assert p.credentials.get('refresh_token') is None
69
-
70
-
71
- @pytest.mark.order(-2)
72
- def test_env_vars_provider():
73
- os.environ['SP_API_REFRESH_TOKEN'] = 'foo'
74
- os.environ['LWA_APP_ID'] = 'foo'
75
- os.environ['LWA_CLIENT_SECRET'] = 'foo'
76
-
77
- p = FromEnvironmentVariablesCredentialProvider()()
78
- assert 'refresh_token' in p
79
-
80
- os.environ.pop('SP_API_REFRESH_TOKEN')
81
- os.environ.pop('LWA_APP_ID')
82
- os.environ.pop('LWA_CLIENT_SECRET')
83
-
84
-
85
- @pytest.mark.order(-1)
86
- def test_from_secrets():
87
- os.environ['SP_API_AWS_SECRET_ID'] = 'testing/sp-api-foo'
88
- try:
89
- p = FromSecretsCredentialProvider()()
90
- assert 'refresh_token' in p
91
- assert p.get('refresh_token') == 'foo'
92
- os.environ.pop('SP_API_AWS_SECRET_ID')
93
- except MissingCredentials as e:
94
- assert isinstance(e, MissingCredentials)
95
-
96
-
97
- def test_from_config_file_provider():
98
- try:
99
- p = FromConfigFileCredentialProvider()()
100
- assert p.get('refresh_token') is not None
101
- except MissingCredentials as e:
102
- assert isinstance(e, MissingCredentials)
103
-
104
-
105
- def test_req():
106
- assert len(required_credentials) == 2
107
-
108
-
109
- def test_client():
110
- client = Client(marketplace=Marketplaces.UK)
111
- assert client.marketplace_id == Marketplaces.UK.marketplace_id
112
- assert client.credentials is not None
113
- assert client.endpoint == Marketplaces.UK.endpoint
114
- assert client.region == Marketplaces.UK.region
115
- assert client.restricted_data_token is None
116
- assert isinstance(client._auth, AccessTokenClient)
117
-
118
- assert isinstance(client._get_cache_key(), str)
119
- assert isinstance(client._get_cache_key('test'), str)
120
-
121
- assert client.headers['host'] == client.endpoint[8:]
122
- assert len(client.headers.keys()) == 5
123
-
124
- assert client.auth is not None
125
- try:
126
- x = client.grantless_auth
127
- except MissingScopeException as e:
128
- assert isinstance(e, MissingScopeException)
129
-
130
- try:
131
- client._request('', data={})
132
- except SellingApiForbiddenException as e:
133
- assert isinstance(e, SellingApiForbiddenException)
134
- try:
135
- client._request('', params={})
136
- except SellingApiForbiddenException as e:
137
- assert isinstance(e, SellingApiForbiddenException)
138
-
139
- check = client._check_response(Res())
140
- assert check.payload['foo'] == 'bar'
141
-
142
- r = Res()
143
- r.method = 'POST'
144
- check = client._check_response(r)
145
- assert check.payload['foo'] == 'bar'
146
- assert check('foo') == 'bar'
147
- assert check.foo == 'bar'
148
- assert check()['foo'] == 'bar'
149
-
150
- r.method = 'DELETE'
151
- check = client._check_response(r)
152
- assert check.payload['foo'] == 'bar'
153
- assert check('foo') == 'bar'
154
- assert check.foo == 'bar'
155
- assert check()['foo'] == 'bar'
156
-
157
- client.grantless_scope = 'sellingpartnerapi::notifications'
158
- assert client.grantless_auth is not None
159
-
160
- try:
161
- client._request_grantless_operation('')
162
- except SellingApiForbiddenException as e:
163
- assert isinstance(e, SellingApiForbiddenException)
@@ -1,45 +0,0 @@
1
- import os
2
- from unittest import mock
3
-
4
- from sp_api.base.credential_provider import FromCachedSecretsCredentialProvider
5
-
6
-
7
- REFRESH_TOKEN = '<refresh_token>'
8
- LWA_APP_ID = '<lwa_app_id>'
9
- LWA_CLIENT_SECRET = '<lwa_client_secret>'
10
-
11
-
12
- def test_from_cached_secrets_cp_without_secret_id_set():
13
- with mock.patch.dict(os.environ, {"SP_API_AWS_SECRET_ID": ""}):
14
- cp = FromCachedSecretsCredentialProvider()
15
- cp.load_credentials()
16
-
17
- assert cp.credentials is None
18
-
19
-
20
- def test_from_cached_secrets_cp_without_cache_available():
21
- with mock.patch.dict(os.environ, {"SP_API_AWS_SECRET_ID": "test"}), \
22
- mock.patch.object(FromCachedSecretsCredentialProvider, "_get_secret_cache", return_value=None):
23
- cp = FromCachedSecretsCredentialProvider()
24
- cp.load_credentials()
25
-
26
- assert cp.credentials is None
27
-
28
-
29
- def test_from_cached_secrets_cp_with_cache_available():
30
- secret_content = {
31
- "SP_API_REFRESH_TOKEN": REFRESH_TOKEN,
32
- "LWA_APP_ID": LWA_APP_ID,
33
- "LWA_CLIENT_SECRET": LWA_CLIENT_SECRET,
34
- }
35
-
36
- with mock.patch.dict(os.environ, {"SP_API_AWS_SECRET_ID": "test"}), \
37
- mock.patch.object(FromCachedSecretsCredentialProvider, "get_secret_content", return_value=secret_content):
38
- cp = FromCachedSecretsCredentialProvider()
39
- cp.load_credentials()
40
-
41
- assert cp.credentials == {
42
- "refresh_token": REFRESH_TOKEN,
43
- "lwa_app_id": LWA_APP_ID,
44
- "lwa_client_secret": LWA_CLIENT_SECRET,
45
- }
@@ -1,142 +0,0 @@
1
- import enum
2
- import os
3
- from datetime import datetime, timedelta
4
- from io import BytesIO
5
-
6
- from sp_api.api import FulfillmentInbound, Orders
7
- from sp_api.base import fill_query_params, sp_endpoint, create_md5, nest_dict, deprecated
8
- from sp_api.util import KeyMaker, load_all_pages, throttle_retry, load_date_bound
9
- from sp_api.util.load_all_pages import make_sleep_time
10
-
11
- key_mapping = {
12
- 'sku': ['seller_sku', 'sellerSku'],
13
- 'title': ['product_name']
14
- }
15
- test_obj = {
16
- 'goo': {'x': {}},
17
- 'seller_sku': 1,
18
- 'product_name': {
19
- 'sellerSku': [
20
- 'seller_sku',
21
- 3,
22
- {
23
- 'sellerSku': 22,
24
- 'product_name': {
25
- 'title': 'Foo',
26
- 'x': 'bar'
27
- }
28
- }
29
- ]
30
- }
31
- }
32
-
33
-
34
- def test_key_maker_from_dict():
35
- r = KeyMaker(key_mapping, deep=True).convert_keys(test_obj)
36
- assert isinstance(r, dict)
37
- assert r.get('sku') == 1
38
- assert r.get('seller_sku') is None
39
- assert isinstance(r.get('title'), dict)
40
- assert isinstance(r.get('title').get('sku'), list)
41
-
42
-
43
- def test_key_maker_from_list():
44
- r = KeyMaker(key_mapping, deep=True).convert_keys([test_obj])
45
- assert isinstance(r, list)
46
- assert len(r) == 1
47
-
48
- assert r[0].get('sku') == 1
49
- assert r[0].get('seller_sku') is None
50
- assert isinstance(r[0].get('title'), dict)
51
- assert isinstance(r[0].get('title').get('sku'), list)
52
-
53
-
54
- def test_key_maker_from_dict_not_deep():
55
- r = KeyMaker(key_mapping, deep=False).convert_keys(test_obj)
56
- assert r.get('sku') == 1
57
- assert r.get('seller_sku') is None
58
- assert isinstance(r.get('title'), dict)
59
- assert isinstance(r.get('title').get('sellerSku'), list)
60
-
61
-
62
- def test_load_all_pages():
63
- @throttle_retry()
64
- @load_all_pages(extras=dict(QueryType='NEXT_TOKEN'))
65
- def load_shipments(**kwargs):
66
- return FulfillmentInbound().get_shipments(**kwargs)
67
-
68
- for x in load_shipments(QueryType='SHIPMENT'):
69
- assert x.payload is not None
70
-
71
-
72
- def test_load_all_pages_orders():
73
- @throttle_retry()
74
- @load_all_pages()
75
- def load_all_orders(**kwargs):
76
- return Orders().get_orders(**kwargs)
77
-
78
- for x in load_all_orders(CreatedAfter='TEST_CASE_200', MarketplaceIds=["ATVPDKIKX0DER"]):
79
- assert x.payload is not None
80
-
81
-
82
- def test_make_sleep_time():
83
- x = make_sleep_time(2, False, 2)
84
- assert x == 2
85
-
86
- y = make_sleep_time(2, True, 2)
87
- assert y == 0.5
88
-
89
-
90
- def test_load_all_pages1():
91
- x = load_all_pages()
92
- assert x is not None
93
-
94
-
95
- def test_fill_query_params():
96
- assert fill_query_params('{}/{}', 'foo', 'bar') == 'foo/bar'
97
-
98
-
99
- def test_sp_endpoint_():
100
- assert sp_endpoint('foo') is not None
101
-
102
- @sp_endpoint('/api/call', method='POST')
103
- def my_endpoint(**kwargs):
104
- assert kwargs['path'] == '/api/call'
105
- assert kwargs['method'] == 'POST'
106
- my_endpoint()
107
- assert my_endpoint.__name__ == 'my_endpoint'
108
-
109
-
110
- def test_create_md5():
111
- b = BytesIO()
112
- b.write(b'foo')
113
- b.seek(0)
114
- m = create_md5(b)
115
- assert m == 'rL0Y20zC+Fzt72VPzMSk2A=='
116
-
117
-
118
- def test_nest_dict():
119
- x = nest_dict({
120
- "AmazonOrderId":1,
121
- "ShipFromAddress.Name" : "Seller",
122
- "ShipFromAddress.AddressLine1": "Street",
123
- })
124
- assert x['ShipFromAddress']['AddressLine1'] == 'Street'
125
-
126
-
127
- def test_deprecated():
128
- assert deprecated(lambda x: x + 1)(1) == 2
129
-
130
-
131
- @load_date_bound()
132
- def dummy(**kwargs):
133
- return lambda: kwargs
134
-
135
-
136
- def test_load_date_bound():
137
- start = datetime.now() - timedelta(days=70)
138
- end = datetime.now()
139
- x = list(dummy(dataStartTime=start, dataEndTime=end))
140
- assert len(x) == 3
141
- assert x[1]()['dataStartTime'] == start + timedelta(days=30)
142
- assert x[1]()['dataEndTime'] == start + timedelta(days=60)