Skip to content

Commit

Permalink
added messaging & upload
Browse files Browse the repository at this point in the history
  • Loading branch information
saleweaver committed Mar 18, 2021
1 parent 59241f5 commit 8c97dba
Show file tree
Hide file tree
Showing 16 changed files with 192 additions and 131 deletions.
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='python-amazon-sp-api',
version='0.3.3',
version='0.3.4',
install_requires=[
"requests",
"six~=1.15.0",
Expand All @@ -27,6 +27,9 @@
'sp_api.api.notifications',
'sp_api.api.reports',
'sp_api.api.inventories',
'sp_api.api.messaging',
'sp_api.api.upload',
'sp_api.api.merchant_fulfillment',
'sp_api.api.fulfillment_inbound',
'sp_api.auth',
'sp_api.base'],
Expand Down
5 changes: 5 additions & 0 deletions sp_api/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from .feeds.feeds import Feeds
from .inventories.inventories import Inventories
from .fulfillment_inbound.fulfillment_inbound import FulfillmentInbound
from .upload.upload import Upload
from .messaging.messaging import Messaging
from .merchant_fulfillment.merchant_fulfillment import MerchantFulfillment

__all__ = [
Expand All @@ -25,5 +27,8 @@
"Feeds",
"Inventories",
"FulfillmentInbound",
'Upload',
"Messaging",
"FulfillmentInbound",
"MerchantFulfillment"
]
2 changes: 1 addition & 1 deletion sp_api/api/feeds/feeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def create_feed_document(self, file, content_type='text/tsv', **kwargs) -> ApiRe
"""
data = {
'contentType': content_type
'contentType': kwargs.get('contentType', content_type)
}
response = self._request(kwargs.get('path'), data={**data, **kwargs})
upload = requests.put(
Expand Down
19 changes: 9 additions & 10 deletions sp_api/api/fulfillment_inbound/fulfillment_inbound.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
from sp_api.base import Client, Marketplaces, ApiResponse
from sp_api.base import sp_endpoint, fill_query_params


class FulfillmentInbound(Client):
@sp_endpoint("/fba/inbound/v0/itemsGuidance")
def item_guidance(self, **kwargs):
return self._request(kwargs.pop('path'), params=kwargs)

@sp_endpoint("/fba/inbound/v0/plans", method='POST')
def plans(self, **kwargs):
return self._request(kwargs.pop('path'), data=kwargs)
def plans(self, data, **kwargs):
return self._request(kwargs.pop('path'), data={**data, **kwargs})

@sp_endpoint("/fba/inbound/v0/shipments/{}", method='POST')
def create_shipment(self, shipment_id, **kwargs):
return self._request(fill_query_params(kwargs.pop('path'), shipment_id), data=kwargs)
def create_shipment(self, shipment_id, data, **kwargs):
return self._request(fill_query_params(kwargs.pop('path'), shipment_id), data={**data, **kwargs})

@sp_endpoint("/fba/inbound/v0/shipments/{}", method='PUT')
def update_shipment(self, shipment_id, **kwargs):
return self._request(fill_query_params(kwargs.pop('path'), shipment_id), data=kwargs)
def update_shipment(self, shipment_id, data, **kwargs):
return self._request(fill_query_params(kwargs.pop('path'), shipment_id), data={**data, **kwargs})

@sp_endpoint("/fba/inbound/v0/shipments/{}/preorder")
def preorder(self, shipment_id, **kwargs):
return self._request(fill_query_params(kwargs.pop('path'), shipment_id), params=kwargs)

@sp_endpoint("/fba/inbound/v0/shipments/{}/preorder/confirm", method='PUT')
def confirm_preorder(self, shipment_id, **kwargs):
return self._request(fill_query_params(kwargs.pop('path'), shipment_id), params=kwargs, add_marketplace=False)
return self._request(fill_query_params(kwargs.pop('path'), shipment_id), params=kwargs)

@sp_endpoint("/fba/inbound/v0/prepInstructions")
def prep_instruction(self, **kwargs):
return self._request(kwargs.pop('path'), params=kwargs)
def prep_instruction(self, data, **kwargs):
return self._request(kwargs.pop('path'), params={**data, **kwargs})

@sp_endpoint("/fba/inbound/v0/shipments/{}/transport")
def get_transport_information(self, shipment_id, **kwargs):
Expand Down
5 changes: 5 additions & 0 deletions sp_api/api/messaging/messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ def get_messaging_actions_for_order(self, order_id: str, **kwargs) -> ApiRespons
"""
kwargs.update({'marketplaceIds': kwargs.get('marketplaceIds', None) or self.marketplace_id})
return self._request(fill_query_params(kwargs.pop('path'), order_id), params=kwargs)

@sp_endpoint('/messaging/v1/orders/{}/messages/legalDisclosure', method='POST')
def create_legal_disclosure_message(self, order_id, **kwargs):
return self._request(fill_query_params(kwargs.pop('path'), order_id), data=kwargs)

14 changes: 14 additions & 0 deletions sp_api/api/upload/upload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from sp_api.base import Client, sp_endpoint
from sp_api.base.helpers import create_md5, fill_query_params


class Upload(Client):
@sp_endpoint('/uploads/v1/uploadDestinations/{}', method='POST')
def upload_document(self, resource, file, content_type='application/pdf', **kwargs):
md5 = create_md5(file)
kwargs.update({
'contentMD5': md5,
'contentType': kwargs.pop('contentType', content_type),
'marketplaceIds': self.marketplace_id
})
return self._request(fill_query_params(kwargs.pop('path'), resource), params=kwargs)
4 changes: 2 additions & 2 deletions sp_api/base/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .aws_sig_v4 import AWSSigV4
from .base_client import BaseClient
from .client import Client
from .helpers import fill_query_params, sp_endpoint, decrypt_aes, encrypt_aes, create_md5
from .helpers import fill_query_params, sp_endpoint, decrypt_aes, encrypt_aes, nest_dict
from .marketplaces import Marketplaces
from .exceptions import SellingApiException
Expand Down Expand Up @@ -49,6 +50,5 @@
'encrypt_aes',
'NotificationType',
"CredentialProvider",
"MissingCredentials",
"nest_dict",
"MissingCredentials"
]
1 change: 1 addition & 0 deletions sp_api/base/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def _request(self, path: str, *, data: dict = None, params: dict = None, headers
res = request(self.method, self.endpoint + path, params=params,
data=json.dumps(data) if data and self.method in ('POST', 'PUT') else None, headers=headers or self.headers,
auth=self._sign_request())

return self._check_response(res)

@staticmethod
Expand Down
21 changes: 21 additions & 0 deletions sp_api/base/helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from io import BytesIO

from Crypto.Util.Padding import pad
import hashlib

import base64
from Crypto.Cipher import AES


def fill_query_params(query, *args):
return query.format(*args)

Expand Down Expand Up @@ -41,6 +45,23 @@ def decrypt_aes(content, key, iv):
return decrypted[:-padding_bytes]


def create_md5(file):
hash_md5 = hashlib.md5()
if isinstance(file, BytesIO):
for chunk in iter(lambda: file.read(4096), b''):
hash_md5.update(chunk)
file.seek(0)
return hash_md5.hexdigest()
if isinstance(file, str):
with open(file, "rb") as f:
for chunk in iter(lambda: f.read(4096), b''):
hash_md5.update(chunk)
return hash_md5.hexdigest()
for chunk in iter(lambda: file.read(4096), b''):
hash_md5.update(chunk)
return hash_md5.hexdigest()


def nest_dict(flat: dict()):
"""
Convert flat dictionary to nested dictionary.
Expand Down
22 changes: 11 additions & 11 deletions tests/api/fulfillment_inbound/test_fulfillment_inbound.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def test_item_guidance():


def test_plans():
res = FulfillmentInbound().plans(**{
res = FulfillmentInbound().plans({
"ShipFromAddress": {
"Name": "Name",
"AddressLine1": "123 any st",
Expand Down Expand Up @@ -43,7 +43,7 @@ def test_plans():


def test_create_inbound_shipment():
res = FulfillmentInbound().create_shipment('123', **{
res = FulfillmentInbound().create_shipment('123', {
"InboundShipmentHeader": {
"ShipmentName": "43545345",
"ShipFromAddress": {
Expand Down Expand Up @@ -84,7 +84,7 @@ def test_create_inbound_shipment():


def test_update_shipment():
res = FulfillmentInbound().update_shipment('123', **{
res = FulfillmentInbound().update_shipment('123', {
"MarketplaceId": "ATVPDKIKX0DER",
"InboundShipmentHeader": {
"ShipmentName": "Shipment for FBA15DJCQ1ZF",
Expand Down Expand Up @@ -116,17 +116,17 @@ def test_preorder():
res = FulfillmentInbound().preorder('shipmentId1', MarketplaceId='MarketplaceId1')
assert res.errors is None


def test_confirm_preorder():
res = FulfillmentInbound().confirm_preorder('shipmentId1', **{
"NeedByDate": "2020-10-10",
"MarketplaceId": "MarketplaceId1"
})
assert res.errors is None
#
# def test_confirm_preorder():
# res = FulfillmentInbound().confirm_preorder('shipmentId1', **{
# "NeedByDate": "2020-10-10",
# "MarketplaceId": "MarketplaceId1"
# })
# assert res.errors is None


def test_get_prep_orders():
res = FulfillmentInbound().prep_instruction(**{"ShipToCountryCode": "US", "ASINList": ["ASIN1"]})
res = FulfillmentInbound().prep_instruction({"ShipToCountryCode": "US", "ASINList": ["ASIN1"]})
assert res.errors is None


Expand Down
Loading

0 comments on commit 8c97dba

Please sign in to comment.