python-amazon-sp-api 1.9.39__py3-none-any.whl → 2.0.10__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.
Files changed (163) hide show
  1. {python_amazon_sp_api-1.9.39.dist-info → python_amazon_sp_api-2.0.10.dist-info}/METADATA +44 -8
  2. python_amazon_sp_api-2.0.10.dist-info/RECORD +253 -0
  3. {python_amazon_sp_api-1.9.39.dist-info → python_amazon_sp_api-2.0.10.dist-info}/WHEEL +1 -1
  4. {python_amazon_sp_api-1.9.39.dist-info → python_amazon_sp_api-2.0.10.dist-info}/top_level.txt +0 -1
  5. sp_api/__version__.py +1 -1
  6. sp_api/api/__init__.py +9 -3
  7. sp_api/api/application_integrations/application_integrations.py +2 -2
  8. sp_api/api/catalog/catalog.py +3 -4
  9. sp_api/api/catalog_items/catalog_items.py +3 -6
  10. sp_api/api/customer_feedback/customer_feedback.py +110 -0
  11. sp_api/api/data_kiosk/data_kiosk.py +5 -6
  12. sp_api/api/easy_ship/easy_ship.py +5 -5
  13. sp_api/api/external_fulfillment/external_fulfillment.py +706 -0
  14. sp_api/api/feeds/feeds.py +11 -8
  15. sp_api/api/fulfillment_inbound/fulfillment_inbound.py +35 -2
  16. sp_api/api/inventories/inventories.py +2 -7
  17. sp_api/api/listings_items/listings_items.py +3 -24
  18. sp_api/api/messaging/messaging.py +42 -0
  19. sp_api/api/orders/orders.py +59 -3
  20. sp_api/api/orders/orders_2026_01_01.py +54 -0
  21. sp_api/api/product_fees/product_fees.py +31 -74
  22. sp_api/api/products/products.py +3 -1
  23. sp_api/api/products/products_definitions.py +11 -169
  24. sp_api/api/reports/reports.py +61 -96
  25. sp_api/api/sales/sales.py +2 -2
  26. sp_api/asyncio/api/__init__.py +167 -0
  27. sp_api/asyncio/api/amazon_warehousing_and_distribu/__init__.py +9 -0
  28. sp_api/asyncio/api/amazon_warehousing_and_distribu/amazon_warehousing_and_distribu.py +130 -0
  29. sp_api/asyncio/api/aplus_content/__init__.py +5 -0
  30. sp_api/asyncio/api/aplus_content/aplus_content.py +330 -0
  31. sp_api/asyncio/api/application_integrations/__init__.py +5 -0
  32. sp_api/asyncio/api/application_integrations/application_integrations.py +119 -0
  33. sp_api/asyncio/api/application_management/__init__.py +5 -0
  34. sp_api/asyncio/api/application_management/application_management.py +36 -0
  35. sp_api/asyncio/api/authorization/__init__.py +5 -0
  36. sp_api/asyncio/api/authorization/authorization.py +54 -0
  37. sp_api/asyncio/api/catalog/__init__.py +5 -0
  38. sp_api/asyncio/api/catalog/catalog.py +111 -0
  39. sp_api/asyncio/api/catalog_items/__init__.py +6 -0
  40. sp_api/asyncio/api/catalog_items/catalog_items.py +93 -0
  41. sp_api/asyncio/api/clients/__init__.py +1 -0
  42. sp_api/asyncio/api/customer_feedback/__init__.py +5 -0
  43. sp_api/asyncio/api/customer_feedback/customer_feedback.py +111 -0
  44. sp_api/asyncio/api/data_kiosk/__init__.py +5 -0
  45. sp_api/asyncio/api/data_kiosk/data_kiosk.py +236 -0
  46. sp_api/asyncio/api/easy_ship/__init__.py +5 -0
  47. sp_api/asyncio/api/easy_ship/easy_ship.py +191 -0
  48. sp_api/asyncio/api/external_fulfillment/__init__.py +5 -0
  49. sp_api/asyncio/api/external_fulfillment/external_fulfillment.py +706 -0
  50. sp_api/asyncio/api/fba_inbound_eligibility/__init__.py +5 -0
  51. sp_api/asyncio/api/fba_inbound_eligibility/fba_inbound_eligibility.py +96 -0
  52. sp_api/asyncio/api/fba_small_and_light/__init__.py +5 -0
  53. sp_api/asyncio/api/fba_small_and_light/fba_small_and_light.py +213 -0
  54. sp_api/asyncio/api/feeds/feeds.py +260 -0
  55. sp_api/asyncio/api/finances/finances.py +100 -0
  56. sp_api/asyncio/api/fulfillment_inbound/fulfillment_inbound.py +1798 -0
  57. sp_api/asyncio/api/fulfillment_outbound/fulfillment_outbound.py +736 -0
  58. sp_api/asyncio/api/inventories/inventories.py +74 -0
  59. sp_api/asyncio/api/listings_items/listings_items.py +170 -0
  60. sp_api/asyncio/api/listings_restrictions/listings_restrictions.py +36 -0
  61. sp_api/asyncio/api/merchant_fulfillment/__init__.py +0 -0
  62. sp_api/asyncio/api/merchant_fulfillment/merchant_fulfillment.py +384 -0
  63. sp_api/asyncio/api/messaging/__init__.py +0 -0
  64. sp_api/asyncio/api/messaging/messaging.py +511 -0
  65. sp_api/asyncio/api/models/__init__.py +4 -0
  66. sp_api/asyncio/api/notifications/__init__.py +0 -0
  67. sp_api/asyncio/api/notifications/notifications.py +295 -0
  68. sp_api/asyncio/api/orders/__init__.py +0 -0
  69. sp_api/asyncio/api/orders/orders.py +412 -0
  70. sp_api/asyncio/api/orders/orders_2026_01_01.py +40 -0
  71. sp_api/asyncio/api/overrides/__init__.py +1 -0
  72. sp_api/asyncio/api/product_fees/__init__.py +0 -0
  73. sp_api/asyncio/api/product_fees/product_fees.py +194 -0
  74. sp_api/asyncio/api/product_type_definitions/__init__.py +0 -0
  75. sp_api/asyncio/api/product_type_definitions/product_type_definitions.py +75 -0
  76. sp_api/asyncio/api/products/__init__.py +0 -0
  77. sp_api/asyncio/api/products/products.py +405 -0
  78. sp_api/asyncio/api/products/products_definitions.py +11 -0
  79. sp_api/asyncio/api/replenishment/__init__.py +0 -0
  80. sp_api/asyncio/api/replenishment/replenishment.py +121 -0
  81. sp_api/asyncio/api/reports/__init__.py +0 -0
  82. sp_api/asyncio/api/reports/reports.py +439 -0
  83. sp_api/asyncio/api/sales/__init__.py +0 -0
  84. sp_api/asyncio/api/sales/sales.py +93 -0
  85. sp_api/asyncio/api/sellers/__init__.py +0 -0
  86. sp_api/asyncio/api/sellers/sellers.py +70 -0
  87. sp_api/asyncio/api/services/__init__.py +0 -0
  88. sp_api/asyncio/api/services/services.py +218 -0
  89. sp_api/asyncio/api/shipping/__init__.py +0 -0
  90. sp_api/asyncio/api/shipping/shipping.py +459 -0
  91. sp_api/asyncio/api/shipping/shippingV2.py +651 -0
  92. sp_api/asyncio/api/solicitations/__init__.py +0 -0
  93. sp_api/asyncio/api/solicitations/solicitations.py +78 -0
  94. sp_api/asyncio/api/supply_sources/__init__.py +0 -0
  95. sp_api/asyncio/api/supply_sources/supply_sources.py +138 -0
  96. sp_api/asyncio/api/tokens/__init__.py +0 -0
  97. sp_api/asyncio/api/tokens/tokens.py +65 -0
  98. sp_api/asyncio/api/upload/__init__.py +0 -0
  99. sp_api/asyncio/api/upload/upload.py +18 -0
  100. sp_api/asyncio/api/vendor_direct_fulfillment_inventory/__init__.py +0 -0
  101. sp_api/asyncio/api/vendor_direct_fulfillment_inventory/vendor_direct_fulfillment_inventory.py +64 -0
  102. sp_api/asyncio/api/vendor_direct_fulfillment_orders/__init__.py +0 -0
  103. sp_api/asyncio/api/vendor_direct_fulfillment_orders/vendor_direct_fulfillment_orders.py +196 -0
  104. sp_api/asyncio/api/vendor_direct_fulfillment_payments/__init__.py +0 -0
  105. sp_api/asyncio/api/vendor_direct_fulfillment_payments/vendor_direct_fulfillment_payments.py +254 -0
  106. sp_api/asyncio/api/vendor_direct_fulfillment_shipping/__init__.py +0 -0
  107. sp_api/asyncio/api/vendor_direct_fulfillment_shipping/vendor_direct_fulfillment_shipping.py +627 -0
  108. sp_api/asyncio/api/vendor_direct_fulfillment_transactions/__init__.py +0 -0
  109. sp_api/asyncio/api/vendor_direct_fulfillment_transactions/vendor_direct_fulfillment_transactions.py +43 -0
  110. sp_api/asyncio/api/vendor_invoices/__init__.py +0 -0
  111. sp_api/asyncio/api/vendor_invoices/vendor_invoices.py +295 -0
  112. sp_api/asyncio/api/vendor_orders/__init__.py +0 -0
  113. sp_api/asyncio/api/vendor_orders/vendor_orders.py +210 -0
  114. sp_api/asyncio/api/vendor_shipments/__init__.py +0 -0
  115. sp_api/asyncio/api/vendor_shipments/vendor_shipments.py +118 -0
  116. sp_api/asyncio/api/vendor_transaction_status/__init__.py +0 -0
  117. sp_api/asyncio/api/vendor_transaction_status/vendor_transaction_status.py +41 -0
  118. sp_api/asyncio/auth/__init__.py +12 -0
  119. sp_api/asyncio/auth/access_token_client.py +145 -0
  120. sp_api/asyncio/auth/exceptions.py +5 -0
  121. sp_api/asyncio/base/__init__.py +53 -0
  122. sp_api/asyncio/base/_transport_httpx.py +50 -0
  123. sp_api/asyncio/base/base_client.py +8 -0
  124. sp_api/asyncio/base/client.py +169 -0
  125. sp_api/asyncio/util/__init__.py +29 -0
  126. sp_api/asyncio/util/key_maker.py +5 -0
  127. sp_api/asyncio/util/load_all_pages.py +55 -0
  128. sp_api/asyncio/util/load_date_bound.py +53 -0
  129. sp_api/asyncio/util/retry.py +88 -0
  130. sp_api/auth/_core.py +39 -0
  131. sp_api/auth/access_token_client.py +18 -29
  132. sp_api/base/ApiResponse.py +2 -2
  133. sp_api/base/_core.py +110 -0
  134. sp_api/base/_transport_httpx.py +39 -0
  135. sp_api/base/client.py +40 -63
  136. sp_api/base/helpers.py +1 -1
  137. sp_api/util/__init__.py +36 -0
  138. sp_api/util/params.py +57 -0
  139. sp_api/util/product_fees.py +40 -0
  140. sp_api/util/products_definitions.py +169 -0
  141. sp_api/util/report_document.py +154 -0
  142. python_amazon_sp_api-1.9.39.dist-info/RECORD +0 -148
  143. tests/api/finances/test_finances.py +0 -19
  144. tests/api/notifications/test_notifications.py +0 -26
  145. tests/api/orders/test_orders.py +0 -122
  146. tests/api/product_fees/product_fees.py +0 -49
  147. tests/api/reports/test_reports.py +0 -127
  148. tests/client/test_auth.py +0 -59
  149. tests/client/test_base.py +0 -163
  150. tests/client/test_credential_provider.py +0 -45
  151. tests/client/test_helpers.py +0 -142
  152. {python_amazon_sp_api-1.9.39.data → python_amazon_sp_api-2.0.10.data}/scripts/make_endpoint +0 -0
  153. {python_amazon_sp_api-1.9.39.dist-info → python_amazon_sp_api-2.0.10.dist-info}/licenses/LICENSE +0 -0
  154. {tests → sp_api/api/customer_feedback}/__init__.py +0 -0
  155. {tests/api → sp_api/api/external_fulfillment}/__init__.py +0 -0
  156. {tests/api/finances → sp_api/asyncio}/__init__.py +0 -0
  157. {tests/api/notifications → sp_api/asyncio/api/feeds}/__init__.py +0 -0
  158. {tests/api/orders → sp_api/asyncio/api/finances}/__init__.py +0 -0
  159. {tests/api/product_fees → sp_api/asyncio/api/fulfillment_inbound}/__init__.py +0 -0
  160. {tests/api/reports → sp_api/asyncio/api/fulfillment_outbound}/__init__.py +0 -0
  161. {tests/api/sellers → sp_api/asyncio/api/inventories}/__init__.py +0 -0
  162. {tests/client → sp_api/asyncio/api/listings_items}/__init__.py +0 -0
  163. /tests/api/sellers/test_sellers.py → /sp_api/asyncio/api/listings_restrictions/__init__.py +0 -0
@@ -1,169 +1,11 @@
1
- from enum import Enum
2
- from typing import Optional, List, Dict, Union
3
- from dataclasses import dataclass, asdict
4
-
5
-
6
- class CompetitiveSummaryIncludedData(Enum):
7
- FEATURED_BUYING_OPTIONS = "featuredBuyingOptions"
8
- LOWEST_PRICED_OFFERS = "lowestPricedOffers"
9
- REFERENCE_PRICES = "referencePrices"
10
-
11
-
12
- @dataclass
13
- class ItemOffersRequest:
14
- """Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v0-reference
15
- #itemoffersrequest"""
16
-
17
- uri: str
18
- method: str
19
- MarketplaceId: str
20
- ItemCondition: str = None
21
- CustomerType: str = None
22
- headers: Dict = None
23
-
24
-
25
- @dataclass
26
- class GetItemOffersBatchRequest:
27
- """Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v0-reference
28
- #getitemoffersbatchrequest"""
29
-
30
- requests: Optional[List[Union[ItemOffersRequest, Dict]]] = None
31
-
32
- def __post_init__(self):
33
- self.requests = self.parse_requests(self.requests)
34
-
35
- def to_dict(self):
36
- return asdict(self)
37
-
38
- @staticmethod
39
- def parse_requests(requests) -> List[ItemOffersRequest]:
40
- parsed_requestes = []
41
-
42
- for request in requests:
43
- if isinstance(request, Dict):
44
- request = ItemOffersRequest(**request)
45
-
46
- if not isinstance(request, ItemOffersRequest):
47
- raise TypeError
48
-
49
- parsed_requestes.append(request)
50
-
51
- return parsed_requestes
52
-
53
-
54
- @dataclass
55
- class ListingOffersRequest:
56
- """Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v0-reference
57
- #listingoffersrequest"""
58
-
59
- uri: str
60
- MarketplaceId: str
61
- ItemCondition: str
62
- method: str = "GET"
63
- CustomerType: str = "Consumer"
64
-
65
-
66
- @dataclass
67
- class GetListingOffersBatchRequest:
68
- """Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v0-reference
69
- #getlistingoffersbatchrequest"""
70
-
71
- requests: Optional[List[Union[ListingOffersRequest, Dict]]] = None
72
-
73
- def __post_init__(self):
74
- self.requests = self.parse_requests(self.requests)
75
-
76
- def to_dict(self):
77
- return asdict(self)
78
-
79
- @staticmethod
80
- def parse_requests(requests) -> List[ListingOffersRequest]:
81
- parsed_requestes = []
82
-
83
- for request in requests:
84
- if isinstance(request, Dict):
85
- request = ListingOffersRequest(**request)
86
-
87
- if not isinstance(request, ListingOffersRequest):
88
- raise TypeError
89
-
90
- parsed_requestes.append(request)
91
-
92
- return parsed_requestes
93
-
94
-
95
- @dataclass
96
- class FeaturedOfferExpectedPriceRequest:
97
- """ Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v2022-05-01-reference
98
- #FeaturedOfferExpectedPriceRequest """
99
- marketplaceId: str
100
- sku: str
101
- uri: str = "/products/pricing/2022-05-01/offer/featuredOfferExpectedPrice"
102
- method: str = "GET"
103
-
104
-
105
- @dataclass
106
- class GetFeaturedOfferExpectedPriceBatch:
107
- """ Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v2022-05-01-reference
108
- #getFeaturedOfferExpectedPriceBatch """
109
- requests: Optional[List[Union[FeaturedOfferExpectedPriceRequest, Dict]]] = None
110
-
111
- def __post_init__(self):
112
- self.requests = self.parse_requests(self.requests)
113
-
114
- def to_dict(self):
115
- return asdict(self)
116
-
117
- @staticmethod
118
- def parse_requests(requests) -> List[FeaturedOfferExpectedPriceRequest]:
119
- parsed_requests = []
120
-
121
- for request in requests:
122
- if isinstance(request, Dict):
123
- request = FeaturedOfferExpectedPriceRequest(**request)
124
-
125
- if not isinstance(request, FeaturedOfferExpectedPriceRequest):
126
- raise TypeError
127
-
128
- parsed_requests.append(request)
129
-
130
- return parsed_requests
131
-
132
-
133
- @dataclass
134
- class CompetitiveSummaryRequest:
135
- """ Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v2022-05-01-reference
136
- #FeaturedOfferExpectedPriceRequest """
137
- marketplaceId: str
138
- asin: str
139
- includedData: List[CompetitiveSummaryIncludedData]
140
- uri: str = "/products/pricing/2022-05-01/items/competitiveSummary"
141
- method: str = "GET"
142
-
143
-
144
- @dataclass
145
- class GetCompetitiveSummaryBatch:
146
- """ Implements definition: https://developer-docs.amazon.com/sp-api/docs/product-pricing-api-v2022-05-01-reference
147
- #getCompetitiveSummary """
148
- requests: Optional[List[Union[CompetitiveSummaryRequest, Dict]]] = None
149
-
150
- def __post_init__(self):
151
- self.requests = self.parse_requests(self.requests)
152
-
153
- def to_dict(self):
154
- return asdict(self)
155
-
156
- @staticmethod
157
- def parse_requests(requests) -> List[CompetitiveSummaryRequest]:
158
- parsed_requests = []
159
-
160
- for request in requests:
161
- if isinstance(request, Dict):
162
- request = CompetitiveSummaryRequest(**request)
163
-
164
- if not isinstance(request, CompetitiveSummaryRequest):
165
- raise TypeError
166
-
167
- parsed_requests.append(request)
168
-
169
- return parsed_requests
1
+ from sp_api.util.products_definitions import (
2
+ CompetitiveSummaryIncludedData,
3
+ ItemOffersRequest,
4
+ GetItemOffersBatchRequest,
5
+ ListingOffersRequest,
6
+ GetListingOffersBatchRequest,
7
+ FeaturedOfferExpectedPriceRequest,
8
+ GetFeaturedOfferExpectedPriceBatch,
9
+ CompetitiveSummaryRequest,
10
+ GetCompetitiveSummaryBatch,
11
+ )
@@ -1,10 +1,7 @@
1
- import zlib
2
- from collections import abc
3
1
  from datetime import datetime
4
- from io import BytesIO, StringIO
5
2
  from typing import Optional, Union
6
3
 
7
- import requests
4
+ import httpx
8
5
 
9
6
  from sp_api.base import (
10
7
  Client,
@@ -13,6 +10,19 @@ from sp_api.base import (
13
10
  ApiResponse,
14
11
  Marketplaces,
15
12
  )
13
+ from sp_api.util import (
14
+ normalize_csv_param,
15
+ normalize_datetime_kwargs,
16
+ normalize_marketplace_ids,
17
+ should_add_marketplace,
18
+ )
19
+ from sp_api.util.report_document import (
20
+ decode_document,
21
+ decompress_bytes,
22
+ handle_file,
23
+ resolve_character_code,
24
+ stream_to_file_sync,
25
+ )
16
26
 
17
27
 
18
28
  class Reports(Client):
@@ -60,42 +70,16 @@ class Reports(Client):
60
70
  Returns:
61
71
  ApiResponse
62
72
  """
63
- if (
64
- kwargs.get("reportTypes", None)
65
- and isinstance(kwargs.get("reportTypes"), abc.Iterable)
66
- and not isinstance(kwargs.get("reportTypes"), str)
67
- ):
68
- kwargs.update({"reportTypes": ",".join(kwargs.get("reportTypes"))})
69
- if (
70
- kwargs.get("processingStatuses", None)
71
- and isinstance(kwargs.get("processingStatuses"), abc.Iterable)
72
- and not isinstance(kwargs.get("processingStatuses"), str)
73
- ):
74
- kwargs.update(
75
- {"processingStatuses": ",".join(kwargs.get("processingStatuses"))}
76
- )
77
- if (
78
- kwargs.get("marketplaceIds", None)
79
- and isinstance(kwargs.get("marketplaceIds"), abc.Iterable)
80
- and not isinstance(kwargs.get("marketplaceIds"), str)
81
- ):
82
- marketplaces = kwargs.get("marketplaceIds")
83
- kwargs.update(
84
- {
85
- "marketplaceIds": ",".join(
86
- [
87
- m.marketplace_id if isinstance(m, Marketplaces) else m
88
- for m in marketplaces
89
- ]
90
- )
91
- }
92
- )
93
- for k in ["createdSince", "createdUntil"]:
94
- if kwargs.get(k, None) and isinstance(kwargs.get(k), datetime):
95
- kwargs.update({k: kwargs.get(k).isoformat()})
96
- if not kwargs.get("nextToken"):
97
- return self._request(kwargs.pop("path"), params=kwargs)
98
- return self._request(kwargs.pop("path"), params=kwargs, add_marketplace=False)
73
+ normalize_csv_param(kwargs, "reportTypes")
74
+ normalize_csv_param(kwargs, "processingStatuses")
75
+ normalize_marketplace_ids(kwargs, marketplace_cls=Marketplaces)
76
+ normalize_datetime_kwargs(kwargs, ["createdSince", "createdUntil"])
77
+ add_marketplace = should_add_marketplace(kwargs, "nextToken")
78
+ return self._request(
79
+ kwargs.pop("path"),
80
+ params=kwargs,
81
+ add_marketplace=add_marketplace,
82
+ )
99
83
 
100
84
  @sp_endpoint("/reports/2021-06-30/reports", method="POST")
101
85
  def create_report(self, **kwargs) -> ApiResponse:
@@ -134,10 +118,7 @@ class Reports(Client):
134
118
  Returns:
135
119
  ApiResponse
136
120
  """
137
- if isinstance(kwargs.get("dataStartTime", None), datetime):
138
- kwargs.update({"dataStartTime": kwargs.get("dataStartTime").isoformat()})
139
- if isinstance(kwargs.get("dataEndTime", None), datetime):
140
- kwargs.update({"dataEndTime": kwargs.get("dataEndTime").isoformat()})
121
+ normalize_datetime_kwargs(kwargs, ["dataStartTime", "dataEndTime"])
141
122
  return self._request(kwargs.pop("path"), data=kwargs)
142
123
 
143
124
  @sp_endpoint("/reports/2021-06-30/reports/{}", method="DELETE")
@@ -223,12 +204,7 @@ class Reports(Client):
223
204
  Returns:
224
205
  ApiResponse
225
206
  """
226
- if (
227
- kwargs.get("reportTypes", None)
228
- and isinstance(kwargs.get("reportTypes"), abc.Iterable)
229
- and not isinstance(kwargs.get("reportTypes"), str)
230
- ):
231
- kwargs.update({"reportTypes": ",".join(kwargs.get("reportTypes"))})
207
+ normalize_csv_param(kwargs, "reportTypes")
232
208
 
233
209
  return self._request(kwargs.pop("path"), params=kwargs)
234
210
 
@@ -371,6 +347,7 @@ class Reports(Client):
371
347
  download: bool = False,
372
348
  file=None,
373
349
  character_code: Optional[str] = None,
350
+ stream: bool = False,
374
351
  timeout: Optional[Union[float,int]] = None,
375
352
  **kwargs
376
353
  ) -> ApiResponse:
@@ -410,6 +387,7 @@ class Reports(Client):
410
387
  obtaining the document from the document URL.
411
388
  It fallbacks to 'iso-8859-1' if no encoding was found.
412
389
  Only valid if decrypt=True.
390
+ stream: bool | if True and file is provided, stream the document to disk
413
391
  timeout: int | optional, the timeout for the request to download the document
414
392
 
415
393
  Returns:
@@ -420,53 +398,40 @@ class Reports(Client):
420
398
  add_marketplace=False,
421
399
  )
422
400
  if download or file or ("decrypt" in kwargs and kwargs["decrypt"]):
423
- document_response = requests.get(
424
- res.payload.get("url"),
401
+ compression_algorithm = res.payload.get("compressionAlgorithm")
402
+ with httpx.Client(
425
403
  proxies=self.proxies,
426
404
  verify=self.verify,
427
405
  timeout=timeout,
428
- )
429
- document = document_response.content
430
- if not character_code:
431
- character_code = (
432
- document_response.encoding
433
- if document_response and document_response.encoding
434
- else "iso-8859-1"
435
- )
436
- if character_code.lower() == "windows-31j":
437
- character_code = "cp932"
438
- if "compressionAlgorithm" in res.payload:
439
- try:
440
- document = zlib.decompress(bytearray(document), 15 + 32)
441
- except Exception as e:
442
- pass
443
-
444
- if character_code:
445
- try:
446
- decoded_document = document.decode(character_code)
447
- except Exception as e:
448
- decoded_document = document
449
-
450
- if download:
451
- res.payload.update(
452
- {
453
- "document": decoded_document,
454
- }
455
- )
456
- if file:
457
- self._handle_file(file, decoded_document, character_code)
406
+ ) as client:
407
+ if stream and file:
408
+ with client.stream("GET", res.payload.get("url")) as document_response:
409
+ if not character_code:
410
+ character_code = resolve_character_code(
411
+ document_response.encoding, fallback="iso-8859-1"
412
+ )
413
+ stream_to_file_sync(
414
+ document_response,
415
+ file,
416
+ character_code,
417
+ compression_algorithm,
418
+ )
419
+ else:
420
+ document_response = client.get(res.payload.get("url"))
421
+ if not character_code:
422
+ character_code = resolve_character_code(
423
+ document_response.encoding, fallback="iso-8859-1"
424
+ )
425
+ document = decompress_bytes(
426
+ document_response.content, compression_algorithm
427
+ )
428
+ decoded_document = decode_document(document, character_code)
429
+ if download:
430
+ res.payload.update(
431
+ {
432
+ "document": decoded_document,
433
+ }
434
+ )
435
+ if file:
436
+ handle_file(file, decoded_document, character_code)
458
437
  return res
459
-
460
- @staticmethod
461
- def _handle_file(file, document, encoding):
462
- if isinstance(file, str):
463
- with open(file, "w+", encoding=encoding) as text_file:
464
- text_file.write(document)
465
- elif isinstance(file, BytesIO):
466
- file.write(document.encode(encoding))
467
- file.seek(0)
468
- elif isinstance(file, StringIO):
469
- file.write(document)
470
- file.seek(0)
471
- else:
472
- file.write(document)
sp_api/api/sales/sales.py CHANGED
@@ -3,6 +3,7 @@ from datetime import datetime
3
3
 
4
4
  from sp_api.base import Client, Marketplaces, sp_endpoint, Granularity, ApiResponse
5
5
  import logging
6
+ from sp_api.util import encode_kwarg
6
7
 
7
8
 
8
9
  class Sales(Client):
@@ -71,8 +72,7 @@ class Sales(Client):
71
72
  )
72
73
  if granularityTimeZone:
73
74
  kwargs.update({"granularityTimeZone": granularityTimeZone})
74
- if "sku" in kwargs:
75
- kwargs.update({"sku": urllib.parse.quote(kwargs.pop("sku"), safe="")})
75
+ encode_kwarg(kwargs, "sku", lambda value: urllib.parse.quote(value, safe=""))
76
76
  return self._request(kwargs.pop("path"), params=kwargs)
77
77
 
78
78
  @staticmethod
@@ -0,0 +1,167 @@
1
+ from .finances.finances import Finances, FinancesVersion
2
+ from .notifications.notifications import Notifications
3
+ from .orders.orders import Orders, OrdersVersion
4
+ from .orders.orders_2026_01_01 import OrdersV20260101
5
+ from .product_fees.product_fees import ProductFees
6
+ from .sellers.sellers import Sellers
7
+ from .reports.reports import Reports
8
+ from .reports.reports import Reports as ReportsV2
9
+
10
+ from .products.products import Products
11
+ from .sales.sales import Sales
12
+ from .catalog.catalog import Catalog
13
+ from .feeds.feeds import Feeds
14
+ from .feeds.feeds import Feeds as FeedsV2
15
+
16
+ from .inventories.inventories import Inventories
17
+ from .fulfillment_inbound.fulfillment_inbound import (
18
+ FulfillmentInbound,
19
+ FulfillmentInboundVersion,
20
+ )
21
+ from .upload.upload import Upload
22
+ from .messaging.messaging import Messaging
23
+ from .merchant_fulfillment.merchant_fulfillment import MerchantFulfillment
24
+
25
+ ##### DO NOT DELETE ########## INSERT IMPORT HERE #######
26
+ from .application_integrations.application_integrations import ApplicationIntegrations
27
+
28
+ from .easy_ship.easy_ship import EasyShip
29
+
30
+ from .customer_feedback.customer_feedback import CustomerFeedback
31
+
32
+ from .listings_restrictions.listings_restrictions import ListingsRestrictions
33
+
34
+ from .messaging.messaging import Messaging
35
+
36
+ from .catalog_items.catalog_items import CatalogItems, CatalogItemsVersion
37
+
38
+ from .product_type_definitions.product_type_definitions import ProductTypeDefinitions
39
+
40
+ from .listings_items.listings_items import ListingsItems
41
+
42
+ from .vendor_transaction_status.vendor_transaction_status import VendorTransactionStatus
43
+
44
+ from .vendor_shipments.vendor_shipments import VendorShipments
45
+
46
+ from .vendor_orders.vendor_orders import VendorOrders
47
+
48
+ from .vendor_invoices.vendor_invoices import VendorInvoices
49
+
50
+ from .vendor_direct_fulfillment_transactions.vendor_direct_fulfillment_transactions import (
51
+ VendorDirectFulfillmentTransactions,
52
+ )
53
+
54
+ from .vendor_direct_fulfillment_shipping.vendor_direct_fulfillment_shipping import (
55
+ VendorDirectFulfillmentShipping,
56
+ )
57
+
58
+ from .vendor_direct_fulfillment_payments.vendor_direct_fulfillment_payments import (
59
+ VendorDirectFulfillmentPayments,
60
+ )
61
+
62
+ from .vendor_direct_fulfillment_orders.vendor_direct_fulfillment_orders import (
63
+ VendorDirectFulfillmentOrders,
64
+ )
65
+
66
+ from .vendor_direct_fulfillment_inventory.vendor_direct_fulfillment_inventory import (
67
+ VendorDirectFulfillmentInventory,
68
+ )
69
+
70
+ from .tokens.tokens import Tokens
71
+
72
+ from .solicitations.solicitations import Solicitations
73
+
74
+ from .shipping.shipping import Shipping
75
+
76
+ from .services.services import Services
77
+
78
+ from .fba_small_and_light.fba_small_and_light import FbaSmallAndLight
79
+
80
+ from .fba_inbound_eligibility.fba_inbound_eligibility import FbaInboundEligibility
81
+
82
+ from .authorization.authorization import Authorization
83
+
84
+ from .aplus_content.aplus_content import AplusContent
85
+
86
+ from .fulfillment_outbound.fulfillment_outbound import FulfillmentOutbound
87
+
88
+ from .replenishment.replenishment import Replenishment
89
+
90
+ from .supply_sources.supply_sources import SupplySources
91
+
92
+ from .data_kiosk.data_kiosk import DataKiosk
93
+
94
+ from .application_management.application_management import ApplicationManagement
95
+
96
+ from .amazon_warehousing_and_distribu.amazon_warehousing_and_distribu import (
97
+ AmazonWarehousingAndDistribution,
98
+ AmazonWarehousingAndDistributionVersion,
99
+ )
100
+
101
+ from .external_fulfillment.external_fulfillment import ExternalFulfillment
102
+
103
+ __all__ = [
104
+ "Sales",
105
+ "Products",
106
+ "Reports",
107
+ "Orders",
108
+ "OrdersVersion",
109
+ "OrdersV20260101",
110
+ "Sellers",
111
+ "Notifications",
112
+ "ProductFees",
113
+ "Finances",
114
+ "Catalog",
115
+ "Feeds",
116
+ "Inventories",
117
+ "FulfillmentInbound",
118
+ "Upload",
119
+ "Messaging",
120
+ "FulfillmentInbound",
121
+ "MerchantFulfillment",
122
+ ##### DO NOT DELETE ########## INSERT TITLE HERE #######
123
+ "ExternalFulfillment",
124
+ "ApplicationIntegrations",
125
+ "CustomerFeedback",
126
+ "FulfillmentInbound",
127
+
128
+ "EasyShip",
129
+
130
+
131
+ "FulfillmentInbound",
132
+ "FinancesVersion",
133
+ "ListingsRestrictions",
134
+ "CatalogItemsVersion",
135
+ "AmazonWarehousingAndDistributionVersion",
136
+ "FulfillmentInboundVersion",
137
+ "Feeds",
138
+ "FeedsV2",
139
+ "ReportsV2",
140
+ "Messaging",
141
+ "CatalogItems",
142
+ "ProductTypeDefinitions",
143
+ "ListingsItems",
144
+ "VendorTransactionStatus",
145
+ "VendorShipments",
146
+ "VendorOrders",
147
+ "VendorInvoices",
148
+ "VendorDirectFulfillmentTransactions",
149
+ "VendorDirectFulfillmentShipping",
150
+ "VendorDirectFulfillmentPayments",
151
+ "VendorDirectFulfillmentOrders",
152
+ "VendorDirectFulfillmentInventory",
153
+ "Tokens",
154
+ "Solicitations",
155
+ "Shipping",
156
+ "Services",
157
+ "FbaSmallAndLight",
158
+ "FbaInboundEligibility",
159
+ "Authorization",
160
+ "AplusContent",
161
+ "FulfillmentOutbound",
162
+ "Replenishment",
163
+ "SupplySources",
164
+ "DataKiosk",
165
+ "ApplicationManagement",
166
+ "AmazonWarehousingAndDistribution",
167
+ ]
@@ -0,0 +1,9 @@
1
+ from .amazon_warehousing_and_distribu import (
2
+ AmazonWarehousingAndDistribution,
3
+ AmazonWarehousingAndDistributionVersion,
4
+ )
5
+
6
+ __all__ = [
7
+ "AmazonWarehousingAndDistribution",
8
+ "AmazonWarehousingAndDistributionVersion",
9
+ ]