- 后端
- 云原生
【免费下载链接】boto
For the latest version of boto, see https://github.com/boto/boto3 -- Python interface to Amazon Web Services
本指南以 boto 仓库中 MWS(Marketplace Web Service)相关文档与实现为核心,系统讲解boto.mws模块的架构设计、连接管理、声明式 XML 响应解析、异常模型与分页迭代等核心能力,并结合源码与单元测试给出可直接运行的实战用法。读完本文,你将掌握如何用MWSConnection调用 Feeds、Reports、Orders、Products、Inbound/Outbound、OffAmazonPayments 等 13 个 API 分区,如何利用iter_call/iter_response自动翻页,以及如何理解 MWS 响应对象内部的_result结构与声明式类型系统。
模块概览:boto.mws 由哪些部分组成
boto 仓库中的 MWS 支持位于 boto/mws 目录,主要由四个文件构成:
| 文件 | 职责 |
|---|---|
| init.py | 包声明(主要承载版权与许可信息,模块逻辑集中在其余文件) |
| connection.py | 定义核心类MWSConnection,实现全部 API 调用、装饰器工厂与请求发送 |
| exception.py | 定义ResponseErrorFactory及错误响应类型(ResponseError、RetriableResponseError等) |
| response.py | 声明式 XML 响应解析框架:ResponseElement、Element、ElementList、MemberList、SimpleList、ResponseFactory及大量具体结果类 |
对应 API 文档页 docs/source/ref/mws.rst 通过 Sphinx 的automodule指令,将boto.mws、boto.mws.connection、boto.mws.exception、boto.mws.response四个模块的公开成员(:members:与:undoc-members:)自动提取为参考手册,因此本文所讲的每个类与方法都能在该文档页及其源码中找到对应定义。
建立 MWS 连接:MWSConnection 的初始化与关键参数
构造参数与身份字段
MWSConnection继承自 boto 的AWSQueryConnection(见 connection.py),构造时默认host='mws.amazonservices.com',并重点处理两个身份参数:
Merchant:从关键字参数中弹出,作为商家标识;SellerId:从关键字参数中弹出,若未显式传入则回退为Merchant的值。
两个字段互为兜底:self.Merchant = kw.pop('Merchant', None) or kw.get('SellerId'),self.SellerId同理。构造示例:
from boto.mws.connection import MWSConnection mws = MWSConnection( aws_access_key_id='AKIA...', aws_secret_access_key='your-secret-key', Merchant='YOUR_MERCHANT_ID', # 或传 SellerId debug=0, )此外还支持两个特殊关键字:
sandbox=True:开启沙箱模式。_sandboxify方法会在请求路径的倒数第二个路径段追加_Sandbox后缀(见 connection.py),用于向 Amazon 沙箱环境发起调用,避免产生真实业务影响;factory_scopes=[...]:向响应工厂追加自定义查找作用域,用于扩展默认的解析器注册表(见_setup_factories,connection.py)。
MWSConnection还声明了_required_auth_capability()返回['mws'],表明该连接使用 MWS 专用签名认证能力。
API 分区与版本、路径映射
MWS 服务按业务域划分成多个独立的 API 分区,每个分区有独立的 API 版本、请求路径以及“卖家标识参数名”。这一映射集中在api_version_path字典中(connection.py):
| 分区名 | API 版本 | 卖家标识参数 | 请求路径 |
|---|---|---|---|
| Feeds | 2009-01-01 | Merchant | / |
| Reports | 2009-01-01 | Merchant | / |
| Orders | 2013-09-01 | SellerId | /Orders/2013-09-01 |
| Products | 2011-10-01 | SellerId | /Products/2011-10-01 |
| Sellers | 2011-07-01 | SellerId | /Sellers/2011-07-01 |
| Inbound | 2010-10-01 | SellerId | /FulfillmentInboundShipment/2010-10-01 |
| Outbound | 2010-10-01 | SellerId | /FulfillmentOutboundShipment/2010-10-01 |
| Inventory | 2010-10-01 | SellerId | /FulfillmentInventory/2010-10-01 |
| Recommendations | 2013-04-01 | SellerId | /Recommendations/2013-04-01 |
| CustomerInfo | 2014-03-01 | SellerId | /CustomerInformation/2014-03-01 |
| CartInfo | 2014-03-01 | SellerId | /CartInformation/2014-03-01 |
| Subscriptions | 2013-07-01 | SellerId | /Subscriptions/2013-07-01 |
| OffAmazonPayments | 2013-01-01 | SellerId | /OffAmazonPayments/2013-01-01 |
每次 API 调用通过@api_action装饰器读取该映射,自动填充Action与Version参数,并把Merchant/SellerId值写入对应字段(见 connection.py)。若构造连接时既未传Merchant也未传SellerId,调用时会抛出KeyError并提示“Set the MWSConnection.{attribute} attribute?”。
装饰器体系:参数校验、列表展平与请求构造的底层机制
boto.mws最鲜明的实现特色是使用装饰器栈对每个 API 方法做参数规范。所有装饰器都通过add_attrs_from把action、response、section、quota、restore、version等属性透传到包装函数上,并维护__wrapped__链(见 connection.py),单元测试 tests/unit/mws/test_connection.py 的test_decorator_order正是遍历api_call_map校验装饰器顺序。
参数约束装饰器
@requires(*groups):要求必须同时提供某组参数,支持多组“或”语义;例如submit_feed要求FeedType(connection.py),get_report要求ReportId,list_orders则叠加了多层约束;@exclusive(*groups):多组参数至多只能命中一组,防止同时传入互斥条件;@dependent(field, *groups):当某字段出现时,必须伴随指定参数组之一;@requires_some_of(*fields):要求至少提供其中一个字段。
这些装饰器在参数不满足时统一抛出KeyError,并在__doc__中追加“Required: ... / Either: ...”说明,开发者可通过help()查看约束。
请求构造装饰器
@structured_lists(*fields):把 Python 列表转换成 MWS 的重复参数格式。例如字段MarketplaceIdList.Id会被展开为MarketplaceIdList.Id.1、MarketplaceIdList.Id.2……(connection.py),这正是submit_feed与request_report支持多站点上传的原因;@structured_objects(*fields, members=False):将ResponseElement、字典、可迭代对象等“结构化对象”拍平为带前缀的请求参数,由destructure_object递归处理(connection.py):布尔值转小写字符串、字符串直接赋值、可迭代对象按member.1/member.2编号。test_destructure_object在 tests/unit/mws/test_connection.py 中给出了完整的输入/输出对照;@boolean_arguments(*fields):把 Python 布尔参数转为 MWS 需要的'true'/'false'小写字符串;@http_body(field):用于需要上传正文的调用(如submit_feed),从参数中取出FeedContent与content_type,自动计算Content-MD5摘要并放入请求头(connection.py)。
配额声明
每个 API 调用在@api_action中声明了quota与restore(恢复速率,单位每秒),如 Feeds 分区submit_feed的quota=15, restore=120,Orders 分区list_orders的quota=6, restore=60,Inbound/Outbound 分区多为quota=30, restore=0.5。api_call_map同时记录每个 Action 与对应方法名的映射(connection.py),供method_for反向查询。
API 调用速查:13 个分区的核心方法
MWSConnection将 100 余个 API 操作组织为同名方法,按分区归纳如下(完整定义见 connection.py):
Feeds(商品数据上传,版本 2009-01-01)
submit_feed(FeedType, FeedContent, MarketplaceIdList, content_type, PurgeAndReplace=False):上传数据 Feed,需要 FeedContent 正文与 content_type,自动附加 Content-MD5;get_feed_submission_list(...):查询近 90 天提交的 Feed 列表;get_feed_submission_list_by_next_token(NextToken):基于 NextToken 翻页;get_feed_submission_count(...):统计 Feed 提交数量;cancel_feed_submissions(...):取消一个或多个 Feed 提交;get_feed_submission_result(FeedSubmissionId):获取 Feed 处理报告。
Reports(报表,版本 2009-01-01)
request_report(ReportType, MarketplaceIdList, ReportOptions=...):创建报表请求;get_report_request_list / get_report_request_count / cancel_report_requests:管理报表请求;get_report_list / get_report_count / get_report(ReportId):查询并下载报表;manage_report_schedule(ReportType, Schedule):创建/更新/删除报表调度;get_report_schedule_list / get_report_schedule_count:查询调度计划;update_report_acknowledgements(ReportIdList, Acknowledged):更新报表确认状态。
Orders(订单,版本 2013-09-01)
list_orders(MarketplaceId, CreatedAfter 或 LastUpdatedAfter, ...):按时间窗查询订单,方法内部对BuyerEmail、SellerOrderId、时间字段等做了大量互斥校验(connection.py);list_orders_by_next_token(NextToken):订单翻页;get_order(AmazonOrderId):按订单号查询;list_order_items(AmazonOrderId) / list_order_items_by_next_token:查询订单商品明细。
Products(商品,版本 2011-10-01)
list_matching_products(MarketplaceId, Query):按关键词搜索商品;get_matching_product(ASINList) / get_matching_product_for_id(IdType, IdList):按 ASIN 或 ID 批量取商品;get_competitive_pricing_for_sku / _for_asin:获取竞争定价;get_lowest_offer_listings_for_sku / _for_asin:获取最低报价;get_my_price_for_sku / _for_asin:获取自有报价;get_product_categories_for_sku / _for_asin:获取商品类目。
Fulfillment(入库/出库/库存)
- Inbound:
create_inbound_shipment_plan、create_inbound_shipment、update_inbound_shipment、list_inbound_shipments、list_inbound_shipment_items及对应*_by_next_token; - Outbound:
get_fulfillment_preview(Address, Items)、create_fulfillment_order(...)、get_fulfillment_order(SellerFulfillmentOrderId)、list_all_fulfillment_orders、cancel_fulfillment_order、get_package_tracking_details(PackageNumber); - Inventory:
list_inventory_supply(SellerSkus 或 QueryStartDateTime)。
其余分区
- Sellers:
list_marketplace_participations(获取可销售站点与参与信息); - Recommendations:
get_last_updated_time_for_recommendations、list_recommendations; - CustomerInfo:
list_customers、get_customers_for_customer_id; - CartInfo:
list_carts、get_carts; - Subscriptions:
register_destination、create_subscription、get_subscription、update_subscription、delete_subscription、list_subscriptions、send_test_notification_to_destination等; - OffAmazonPayments:
set_order_reference_details、confirm_order_reference、cancel_order_reference、close_order_reference、authorize、capture、refund、get_authorization_details、get_capture_details、get_refund_details等支付全流程操作。
服务状态检查
每个分区都提供get_xxx_service_status()(配额2, restore=300)。注意get_service_status是一个“提示型”方法(connection.py):直接调用会抛出AttributeError,并在异常消息中列出所有可用分区名,提示应调用get_(section)_service_status()。集成测试 tests/integration/mws/test.py 中验证了get_inbound_service_status的返回状态值属于('GREEN', 'GREEN_I', 'YELLOW', 'RED')之一。
方法名双向解析与自动分页:method_for、iter_call、iter_response
方法名解析
method_for(name)(connection.py)接受 CamelCase(如ListOrders)或下划线小写(如list_orders)两种风格的方法名,通过api_call_map返回真正的调用方法。它是自动分页机制的基础设施。
自动分页
MWS 对大数据量结果采用NextToken+HasNext的分页协议。iter_call(call, *args, **kw)与iter_response(response)将其封装为生成器(connection.py):
# 方式一:按调用名自动翻页 for page in mws.iter_call('list_orders', MarketplaceId=..., CreatedAfter=...): result = page._result for order in result.Orders.Order: print(order.AmazonOrderId) # 方式二:拿到首个响应后自动翻页 first = mws.get_feed_submission_list() for page in mws.iter_response(first): for info in page._result.FeedSubmissionInfo: print(info.FeedSubmissionId, info.FeedType, info.FeedProcessingStatus)iter_response的判定逻辑为:只要当前响应_result.HasNext == 'true',就调用method_for(response._action + 'ByNextToken')获取下一页,并以NextToken继续请求。因此所有支持翻页的操作(Orders、Reports、Feeds、Inbound、Products 等)都可以复用同一套迭代代码。该机制依赖响应对象的_action属性:_action由响应类名去掉Response后缀得到(见 response.py)。
声明式响应解析:ResponseElement、Element 与成员列表
MWS 的 XML 响应结构复杂(含命名空间、嵌套元素、重复成员),boto.mws.response用一套“声明式”框架把 XML 直接映射成 Python 对象,这也是docs/source/ref/mws.rst中boto.mws.response一节所展示的主要内容。
核心类型
ResponseElement(dict):所有响应对象的基类,本身是 dict 子类,属性既可obj.Attr访问也可obj['Attr']访问。startElement/endElement由 SAX 解析驱动(response.py);Element:声明一个单值子元素(在start时实例化_hint类,teardown时把值写回父对象);SimpleList:收集一组标量文本,end时 append 到列表;ElementList:收集一组同名元素对象,每个元素都实例化_hint;MemberList:解析 MWS 特有的<member>...</member>包裹结构(response.py),可嵌套声明,支持空列表与缺失列表;ComplexType(dict):带Value属性的复合类型容器。
声明方式非常直观,例如 Feeds 分区的响应类:
class FeedSubmissionInfo(ResponseElement): pass class SubmitFeedResult(ResponseElement): FeedSubmissionInfo = Element(FeedSubmissionInfo) class GetFeedSubmissionListResult(ResponseElement): FeedSubmissionInfo = ElementList(FeedSubmissionInfo)响应工厂与 JIT 动态类型
ResponseFactory(response.py)负责“Action → 响应类”的寻址:
find_element(action, 'Response', Response)先在注册的作用域(默认是boto.mws.response模块)中查找{Action}Response类;- 若不存在,则回退到
{Action}Result基类,并自动为响应类装配{Action}Result的Element; ByNextToken后缀的操作会先尝试匹配去掉ByNextToken的响应类,再通过element_factory动态生成子类,保证xxxResult结构一致;- 若仍找不到,用
element_factory生成 JIT 动态类(类名形如JIT_...),在__repr__中会显示为^{name}^。
单元测试 tests/unit/mws/test_response.py 用 9 组测试覆盖了嵌套元素、MemberList、ElementList、SimpleList、空/缺失列表等全部解析分支,是理解该框架最好的示例。
复杂类型:金额、重量与尺寸
针对跨境电商场景,响应框架内置了专门的数值类型(均在 response.py):
ComplexAmount/ComplexMoney:货币类型,Amount/Value字段自动转Decimal,__repr__输出如USD 19.99,可直接float()转换;ComplexWeight:重量类型,含Value与Unit;ComplexDimensions/Dimension:包装尺寸,支持 Height/Length/Width/Weight 四维,__repr__输出如8.50in x 5.00in x 1.00in;- 这些类型在
FulfillmentPreview、Price、OrderItem、Product等类中大量复用,例如订单类Order的OrderTotal = Element(ComplexMoney)(response.py)。
响应对象的访问模式
所有响应对象均可通过_result属性直达业务结果(_result即{Action}Result属性,response.py):
resp = mws.list_matching_products(MarketplaceId='ATVPDKIKX0DER', Query='boto') for product in resp._result.Products.Product: print(product.Identifiers.MarketplaceASIN.ASIN) print(product.AttributeSets.ItemAttributes[0].Title)注意 Products 分区的商品对象声明了_namespace = 'ns2'(response.py),strip_namespace装饰器会在 SAX 回调前剥掉命名空间前缀(response.py),这也是boto.mws.response能正确处理跨命名空间响应的关键。
错误处理模型:ResponseError 与可重试错误
boto.mws.exception定义了 MWS 专属的异常体系(exception.py):
ResponseErrorFactory:__call__(status, reason, body)先构造BotoServerError,再用find_element(server.error_code, '', ResponseError)按错误码在异常模块中查找对应异常类,找不到则回退到ResponseError;ResponseError(BotoServerError):通用响应错误基类,带retry标志(默认False),__str__会拼出“异常名 + reason + (Retriable) 标记 + 错误信息”;RetriableResponseError(ResponseError):retry = True,代表可重试错误;- 具体错误类型:
InvalidParameterValue(参数值无效)、InvalidParameter(参数无效)、InvalidAddress(地址无效)等。
请求侧的处理位于_post_request(connection.py):
- 任何
BotoServerError(如鉴权失败、限流)都会经_response_error_factory转换为 MWS 异常类型后抛出; - 若响应体为空或 HTTP 状态码非 200,同样抛出对应的响应错误;
- 若响应头携带
Content-MD5,还会校验响应体摘要是否一致,防止传输损坏。
沙箱测试与集成验证
单元测试
- tests/unit/mws/test_response.py:覆盖响应解析的全部数据结构分支(嵌套元素、成员列表、空/缺失列表、简单列表等),并演示了如何用
ResponseFactory(scopes=[...])注入自定义作用域进行局部解析测试; - tests/unit/mws/test_connection.py:验证
destructure_object的输入输出转换、装饰器顺序约束,以及基于GetFeedSubmissionListResponse模拟 XML 的解析流程。
集成测试
tests/integration/mws/test.py 需要环境变量MWS_MERCHANT指向真实的 Merchant/SellerId 才能启用(未设置时会打印提示并跳过测试),验证内容包括:get_feed_submission_list、get_inbound_service_status状态值、list_marketplace_participations获取站点 ID、get_product_categories_for_asin的类目 ID 断言、list_matching_products搜索等。集成测试中的用法(如response.GetServiceStatusResult.Status、response._result.Self)正是上文响应访问模式的真实写照。
总结:什么时候该用 boto.mws
boto.mws是 boto 中对 Amazon MWS 的完整封装,覆盖从商品数据上传(Feeds)、报表(Reports)、订单(Orders)、商品检索(Products)、仓储履约(Fulfillment)到支付(OffAmazonPayments)的全链路。相比直接拼接 MWS 的 REST 请求,它提供:
- 用
@requires/@exclusive/@structured_lists等装饰器在调用前完成参数校验与格式化,避免手写重复的请求参数组装; - 用声明式响应类自动把嵌套 XML(含命名空间与
<member>包裹)解析为可点属性访问的 Python 对象,并通过ResponseFactory自动匹配Action对应的结果类型; - 用
iter_call/iter_response统一处理NextToken分页; - 用
ResponseErrorFactory将服务端错误码映射为带retry语义的异常类型。
需要注意的是:Amazon 已于 2023 年 3 月停止 MWS 服务并迁移至 SP-API,本模块的 API 版本与参数以当前仓库源码为准,适用于历史 MWS 对接场景或作为理解 MWS 协议及 boto 声明式 XML 框架的参考实现。若需编写基于本模块的代码,请以 boto/mws/connection.py 中的方法签名与文档字符串为最终依据,并可通过 docs/source/ref/mws.rst 生成的 API 参考页查阅每个类与方法的完整签名。
- 后端
- 云原生
【免费下载链接】boto
For the latest version of boto, see https://github.com/boto/boto3 -- Python interface to Amazon Web Services
相关推荐
Dopamine 指标采集体系(metrics 模块)完全指南:Collector、CollectorDispatcher 与三大内置收集器
Dopamine 指标采集体系(metrics 模块)完全指南:Collector、CollectorDispatcher 与三大内置收集器 Dopamine
后端云原生Mesop Web Components 实战指南:用 Python 封装任意 JavaScript 能力
Mesop Web Components 实战指南:用 Python 封装任意 JavaScript 能力 Mesop 提供了一套基于 Web Componen
前端后端Web框架boto.mturk 模块全解析:基于 boto 的 Amazon Mechanical Turk 请求方(Requester)API 开发指南
boto.mturk 模块全解析:基于 boto 的 Amazon Mechanical Turk 请求方(Requester)API 开发指南 导读 本文基于
后端云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考