user3220892 user3220892 - 5 months ago 30
Python Question

Amazon MWS Boto parsed XML missing values

Boto 2.40, Python 3.5

When querying Amazon MWS

get_competitive_pricing_for_asin
some values that are present in the raw XML are missing once parsed by Boto.

The raw XML contains the number of offers for each condition in
NumberOfOfferListings


<CompetitivePricing>
<CompetitivePrices>
<CompetitivePrice belongsToRequester="false" condition="New" subcondition="New">
<CompetitivePriceId>1</CompetitivePriceId>
<Price>
<LandedPrice>
<CurrencyCode>USD</CurrencyCode>
<Amount>18.00</Amount>
</LandedPrice>
<ListingPrice>
<CurrencyCode>USD</CurrencyCode>
<Amount>18.00</Amount>
</ListingPrice>
<Shipping>
<CurrencyCode>USD</CurrencyCode>
<Amount>0.00</Amount>
</Shipping>
</Price>
</CompetitivePrice>
<CompetitivePrice belongsToRequester="false" condition="Used" subcondition="VeryGood">
<CompetitivePriceId>2</CompetitivePriceId>
<Price>
<LandedPrice>
<CurrencyCode>USD</CurrencyCode>
<Amount>100.00</Amount>
</LandedPrice>
<ListingPrice>
<CurrencyCode>USD</CurrencyCode>
<Amount>100.00</Amount>
</ListingPrice>
<Shipping>
<CurrencyCode>USD</CurrencyCode>
<Amount>0.00</Amount>
</Shipping>
</Price>
</CompetitivePrice>
</CompetitivePrices>
<NumberOfOfferListings>
<OfferListingCount condition="New">109</OfferListingCount>
<OfferListingCount condition="Collectible">1</OfferListingCount>
<OfferListingCount condition="Used">51</OfferListingCount>
<OfferListingCount condition="Any">161</OfferListingCount>
</NumberOfOfferListings>
</CompetitivePricing>


However only the
Any
value is kept by Boto:

CompetitivePricing{}(
TradeInValue: None,
CompetitivePrices: CompetitivePriceList{}(
CompetitivePrice: [
CompetitivePrice{'condition': 'New', 'belongsToRequester': 'false', 'subcondition': 'New'}(
CompetitivePriceId: '1',
Price: Price{}(
Shipping: USD 0.00,
LandedPrice: USD 18.00,
ListingPrice: USD 18.00
)
),
CompetitivePrice{'condition': 'Used', 'belongsToRequester': 'false', 'subcondition': 'VeryGood'}(
CompetitivePriceId: '2',
Price: Price{}(
Shipping: USD 0.00,
LandedPrice: USD 100.00,
ListingPrice: USD 100.00
)
)
]
),
NumberOfOfferListings: [''],
OfferListingCount: 161{'condition': 'Any'}
)


Note that
NumberOfOfferListings
contains an empty string in the parsed response, and only one
OfferListingCount
from the XML was saved and added as a new attribute.

Does anyone know why the other
OfferListingCount
values are being dropped, or have a good suggestion on how to preserve those values?

I've searched and read the source code: https://github.com/boto/boto/blob/develop/boto/mws/response.py#L520 and can't figure out where it's dropping those values. I have tried this with multiple products and get the same results.

EDIT: I've tried playing around with monkey-patching
CompetitivePricing
:

class OfferListingCount(ResponseElement):
pass


CompetitivePricing.NumberOfOfferListings = Element(OfferListingCount=ElementList(OfferListingCount))


That gives me a full list of conditions:

NumberOfOfferListings: ^NumberOfOfferListings^{}(
OfferListingCount: [
OfferListingCount{'condition': 'New'}(),
OfferListingCount{'condition': 'Collectible'}(),
OfferListingCount{'condition': 'Used'}(),
OfferListingCount{'condition': 'Any'}()
]
)


But without the values.

If I use
SimpleList
:

class OfferListingCount(ResponseElement):
pass


CompetitivePricing.NumberOfOfferListings = Element(OfferListingCount=SimpleList(OfferListingCount))


I get the values but not the conditions:

NumberOfOfferListings: ^NumberOfOfferListings^{}(
OfferListingCount: ['109', '1', '54', '164']
)


So close

Answer

This is the monkey patch I finally came up with:

from boto.mws.response import CompetitivePricing, ElementList, ResponseElement, Element

class OfferListingCount(ResponseElement):
    OfferCount = 0

    def endElement(self, name, value, connection):
        self.OfferCount = value
        super(OfferListingCount, self).endElement(name, value, connection)

CompetitivePricing.NumberOfOfferListings = Element(OfferListingCount=ElementList(OfferListingCount))

Which gives me the output I want:

CompetitivePricing{}(
    NumberOfOfferListings: ^NumberOfOfferListings^{}(
        OfferListingCount: [
            OfferListingCount{'condition': 'New'}(OfferCount: '105'), 
            OfferListingCount{'condition': 'Collectible'}(OfferCount: '2'), 
            OfferListingCount{'condition': 'Used'}(OfferCount: '58'), 
            OfferListingCount{'condition': 'Any'}(OfferCount: '165')]
    )
)
Comments