博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
An Example Using boto Amazon MWS Package
阅读量:4054 次
发布时间:2019-05-25

本文共 6660 字,大约阅读时间需要 22 分钟。

Overview

This article is a follow up of the Here we give a complete example of submitting a product feed.

This implementation uses boto 2.33 to call Amazon MWS apis. To create a product feed XML, we use the  because it has rich features and is widely used by Python developers as Web page or Email templates.

XML Template of Product Feed

Amazon recommends XML, not a flat file, as the preferred data format to send MWS request. According to  from a boto MWS developer (Andy Davidoff), boto's MWS module does not support generating XML from a Python object for two reasons:

First, redistribution of the XSD files is (supposedly) not permitted. Second, there are many defects in these files.

He suggested using an XML template engine and recommended . Because many Python web developers are already familiar with Jinja2, we use it as our XML template engine.
Using Jianja2 template engine is straight forward because its syntax is similar to Python code. To make the example simple, the below Jinja2 template is used to change titles of one or more products.

Please remove the backslashes in the following code. Without it, I couldn't show Jinja2 code using GitHub markdown

1.01
Product
false
\{\% for message in FeedMessages \%\}
\{\{ loop.index \}\}
PartialUpdate
\{\{ message.SKU \}\}
\{\{ message.Title \}\}
\{\% endfor \%\}

The Amazon MWS XML schema is defined in the  and links embedded in the file. There are some subtle things that cause Amazon to reject the a submitted XML feed. For example:

  • There is nothing before the the XML declaration.
  • There is a space after the "utf-8" in the XML declaration

boto MWS API Call

The boto MWS package doesn't have good document and even good code comments. We had to read the code to figure out the calling conventions. The use is not hard once we know where to look in the source code.

The API to submit a product feed are defined in boto.mws.connection module. An MWSConnection usually needs three keyword arguments: Merchant, awsaccesskeyid, and awssecretaccesskey. A connection object is created using the following code:

MarketPlaceID = 'Your_Market_Place_ID'MerchantID = 'Your_Merchant_ID'AccessKeyID = 'Your_AccessKey_ID'SecretKey = 'Your_SecreteKey_ID'conn = connection.MWSConnection(    aws_access_key_id=AccessKeyID,    aws_secret_access_key=SecretKey,    Merchant=MerchantID)

To change a product tile, we need to make three calls: the submit_feed call to submit the feed, the get_feed_submission_list call to find out the call processing status, the get_feed_submission_result call to find out the call processing result. Each call has different requirements. For example, thesubmit_feed has the following decorators:

@requires(['FeedType'])@boolean_arguments('PurgeAndReplace')@http_body('FeedContent')@structured_lists('MarketplaceIdList.Id')@api_action('Feeds', 15, 120)

The above decorators specify the following call conventions:

  • It requires a 'FeedType' keyword argument
  • It has a boolean 'PurgeAndReplace' keyword argument
  • The HTTP request body is passed as the 'FeedContent' keyword argument
  • It is in 'Feed' section with a quota of 15 and restoration time of 120 seconds.

It seems there is no need to pass any request or header arguments to make a call. All needed is to provide the required keyword arguments. The following is the code to call submit_feed:

feed = conn.submit_feed(    FeedType='_POST_PRODUCT_DATA_',    PurgeAndReplace=False,    MarketplaceIdList=[MarketPlaceID],    content_type='text/xml',    FeedContent=feed_content)

Call Response

Though boto doesn't generate request XML content, it parses an XML response into a Python object. A response XML message usually has two parts. For thesubmit_feed call, they are: and . The generated Python object has attributes that have one-to-one mapping to the XML response message. The attribute names can be found in Amazon MWS API document. For example,  describes the XML structure for the boto submit_feedmethod response. All attributes can be easily accessed as Python object attribute. All attribute values are of 'UTF-8' string type.

Complete Source Code

There are three files in this example. There are arranged in the following structure:

boto_test\    __init__.py    connnection_test.py    templates\        product_feed_template.xml

The init.py is an empty file used to define a Python package. 'productfeedtemplate.xml' is the template described above. The following is the source code of 'connection_test.py'.

# -*- coding: utf-8 -*-from boto.mws import connectionimport timefrom jinja2 import Environment, PackageLoader# Amazon US MWS IDMarketPlaceID = 'ATVPDKIKX0DER'MerchantID = 'MID'AccessKeyID = 'AKID'SecretKey = 'SID'env = Environment(loader=PackageLoader('boto_test', 'templates'),                  trim_blocks=True,                  lstrip_blocks=True)template = env.get_template('product_feed_template.xml')class Message(object):    def __init__(self, sku, title):        self.SKU = sku        self.Title = titlefeed_messages = [    Message('SDK1', 'Title1'),    Message('SDK2', 'Title2'),]namespace = dict(MerchantId=MerchantID, FeedMessages=feed_messages)feed_content = template.render(namespace).encode('utf-8')conn = connection.MWSConnection(    aws_access_key_id=AccessKeyID,    aws_secret_access_key=SecretKey,    Merchant=MerchantID)feed = conn.submit_feed(    FeedType='_POST_PRODUCT_DATA_',    PurgeAndReplace=False,    MarketplaceIdList=[MarketPlaceID],    content_type='text/xml',    FeedContent=feed_content)feed_info = feed.SubmitFeedResult.FeedSubmissionInfoprint 'Submitted product feed: ' + str(feed_info)while True:    submission_list = conn.get_feed_submission_list(        FeedSubmissionIdList=[feed_info.FeedSubmissionId]    )    info =  submission_list.GetFeedSubmissionListResult.FeedSubmissionInfo[0]    id = info.FeedSubmissionId    status = info.FeedProcessingStatus    print 'Submission Id: {}. Current status: {}'.format(id, status)    if (status in ('_SUBMITTED_', '_IN_PROGRESS_', '_UNCONFIRMED_')):        print 'Sleeping and check again....'        time.sleep(60)    elif (status == '_DONE_'):        feedResult = conn.get_feed_submission_result(FeedSubmissionId=id)        print feedResult        break    else:        print "Submission processing error. Quit."        break
你可能感兴趣的文章
No.182 - LeetCode1325 - C指针的魅力
查看>>
mysql:sql alter database修改数据库字符集
查看>>
mysql:sql truncate (清除表数据)
查看>>
yuv to rgb 转换失败呀。天呀。谁来帮帮我呀。
查看>>
yuv420 format
查看>>
yuv420 还原为RGB图像
查看>>
LED恒流驱动芯片
查看>>
驱动TFT要SDRAM做为显示缓存
查看>>
使用file查看可执行文件的平台性,x86 or arm ?
查看>>
qt 创建异形窗体
查看>>
简单Linux C线程池
查看>>
内存池
查看>>
gstreamer相关工具集合
查看>>
RS232 四入四出模块控制代码
查看>>
linux 驱动开发 头文件
查看>>
container_of()传入结构体中的成员,返回该结构体的首地址
查看>>
ipconfig,ifconfig,iwconfig
查看>>
opensuse12.2 PL2303 minicom
查看>>
网络视频服务器移植
查看>>
Encoding Schemes
查看>>