Reputation: 31
I tried GreatFeedDocument, then I received a status code is 200, but the get feed result's status:
"processingStatus": "FATAL"
I have too many times tried but I can't understand,
How I can encrypt the XML file?
Here is my python script.
from aws_auth import Auth
import requests
import json
from pprint import pprint
import base64, os
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
ownercd = "****"
sp_auth = Auth(ownercd)
def pad(s):
# Data will be padded to 16 byte boundary in CBC mode
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
def getKey(password):
# Use SHA256 to hash password for encrypting AES
hasher = SHA256.new(password.encode())
return hasher.digest()
# Encrypt message with password
def encrypt(message, key, iv, key_size=256):
message = pad(message)
cipher = AES.new(key, AES.MODE_CBC, iv)
return iv + cipher.encrypt(message)
# Encrypt file
def encrypt_file(file_name, key, iv):
# Open file to get file Data
with open(file_name, "rb") as fo:
plaintext = fo.read()
# Encrypt plaintext with key has been hash by SHA256.
enc = encrypt(plaintext, key, iv)
# write Encrypted file
with open(file_name + ".enc", "wb") as fo:
fo.write(enc)
return enc
if sp_auth != False:
x_amz_access_token = sp_auth[0] # AWS SP-api access token
AWSRequestsAuth = sp_auth[1] # AWS signature
config = sp_auth[2] # From mongo's config
feed_headers = {
"Content-Type": "application/json",
"x-amz-access-token": x_amz_access_token,
}
contentType = {"contentType": "application/xml; charset=UTF-8"}
# [1.1] Create a FeedDocument
creat_feed_res = requests.post(
config["BASE_URL"] + "/feeds/2020-09-04/documents",
headers=feed_headers,
auth=AWSRequestsAuth,
data=json.dumps(contentType),
)
# [1.2] Store the response
CreatFeedResponse = creat_feed_res.json()["payload"]
feedDocumentId = CreatFeedResponse["feedDocumentId"]
initializationVector = CreatFeedResponse["encryptionDetails"][ "initializationVector"]
url = CreatFeedResponse["url"]
key = CreatFeedResponse["encryptionDetails"]["key"]
# [1.3] Upload and encrypt document
filename = "carton.xml"
iv = base64.b64decode(initializationVector)
encrypt_data = encrypt_file(filename, getKey(key), iv)
headers = {"Content-Type": "application/xml; charset=UTF-8"}
res = requests.put(url, headers=headers, data=encrypt_data)
print(res.status_code) # 200
print(res.request.body) # b'8L^\xbeY\xf....
print(res.content.decode())
Can anyone help me with that? Thanks in advance!
Upvotes: 2
Views: 1620
Reputation: 31
I solved my problem. Here is my example code.
import requests
import json
from pprint import pprint
import base64, os
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from base64 import b64encode
import pyaes
dirname = os.path.dirname(os.path.abspath(__file__))
xmlFile_Name = dirname + "/template/carton.xml"
def encrypt(key, initializationVector):
# Create random 16 bytes IV, Create 32 bytes key
key = base64.b64decode(key)
iv = base64.b64decode(initializationVector)
# Encryption with AES-256-CBC
if os.path.isfile(xmlFile_Name) == False:
print("===== CARTON FILE NOT FOUND FROM ===== : {}".format(xmlFile_Name))
sys.exit()
with open(xmlFile_Name, "r") as fo:
plaintext = fo.read()
# print(plaintext)
encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC(key, iv))
ciphertext = encrypter.feed(plaintext.encode("utf8"))
ciphertext += encrypter.feed()
res = requests.put(
url,
data=ciphertext,
headers=contentType,
)
print("STATUS UPLOAD: ", res.status_code) # 200
if res.status_code == 200:
print("===== FILE UPLOAD DONE =====")
# REQUEST
feed_headers = {
"Content-Type": "application/json",
"x-amz-access-token": x_amz_access_token,
}
contentType = {"contentType": "application/xml; charset=UTF-8"}
creat_feed_res = requests.post(
config["BASE_URL"] + "/feeds/2020-09-04/documents",
headers=feed_headers,
auth=AWSRequestsAuth,
data=json.dumps(contentType),
)
# [1.2] Store the response
CreatFeedResponse = creat_feed_res.json()["payload"]
feedDocumentId = CreatFeedResponse["feedDocumentId"]
initializationVector = CreatFeedResponse["encryptionDetails"][ "initializationVector"]
url = CreatFeedResponse["url"]
key = CreatFeedResponse["encryptionDetails"]["key"]
# print(feedDocumentId)
# print("KEY =>", key)
# print("IV =>", initializationVector)
# print(url) #s3 url
contentType = {"Content-Type": "application/xml; charset=UTF-8"}
encryptFile = encrypt(key, initializationVector)
# [3.1] Create a feed
feedType = "POST_FBA_INBOUND_CARTON_CONTENTS"
marketplaceIds = "A1VC38T7*****"
inputFeedDocumentId = feedDocumentId
createdFeedURL = "https://sellingpartnerapi-fe.amazon.com/feeds/2020-09-04/feeds"
createFeedBody = {
"inputFeedDocumentId": inputFeedDocumentId,
"feedType": feedType,
"marketplaceIds": [marketplaceIds],
}
resCreatFeed = requests.post(
createdFeedURL,
headers=feed_headers,
auth=AWSRequestsAuth,
data=json.dumps(createFeedBody),
)
createFeedStatusCode = resCreatFeed.json()
if resCreatFeed.status_code == 202:
# print("Steph 2).")
feedId = createFeedStatusCode["payload"]["feedId"]
print("FEED ID: ", feedId)
# [3.2] CET a feed
getFeed = requests.get(
config["BASE_URL"] +
"/feeds/2020-09-04/feeds/{}".format(str(feedId)),
headers=feed_headers,
auth=AWSRequestsAuth,
)
pprint(getFeed.json()['payload'])
Here is my Get Feed response:
{'payload': {
'createdTime': '2021-02-24T07:43:22+00:00',
'feedId': '14795****',
'feedType': 'POST_FBA_INBOUND_CARTON_CONTENTS',
'marketplaceIds': ['A1VC38T7****'],
'processingStatus': 'DONE'}
}
Then I used the cartonID, I could download the get labels PDF file from the URL.
PackageLabelsToPrint is your cartonID you must set the CartonID here, for example:
Last, I could download a PDF file using the URL
Here is my GetLabel:
Upvotes: 1