简体   繁体   English

使用 Python 的亚马逊销售合作伙伴 API 提要加密文件

[英]Amazon selling-partner-api feed encrypt file with Python

I tried GreatFeedDocument , then I received a status code is 200 , but the get feed result's status:我试过GreatFeedDocument ,然后我收到一个状态码是200 ,但获取提要结果的状态:

"processingStatus": "FATAL" “处理状态”:“致命”

I have too many times tried but I can't understand,试了很多次还是看不懂

How I can encrypt the XML file?如何加密 XML 文件?

Here is my python script.这是我的 python 脚本。

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())

It is the GetFeed Response:这是 GetFeed 响应:

Can anyone help me with that?任何人都可以帮助我吗? Thanks in advance!提前致谢!

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:这是我的 Get Feed 回复:

{'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.然后我使用了 cartonID,我可以从 URL 下载获取标签 PDF 文件。

PackageLabelsToPrint is your cartonID you must set the CartonID here, for example: PackageLabelsToPrint 是您的 cartonID,您必须在此处设置 CartonID,例如: 在此处输入图像描述

Last, I could download a PDF file using the URL Here is my GetLabel:最后,我可以使用 URL 下载 PDF 文件这是我的 GetLabel: 在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM