saleweaver / python-amazon-sp-api

Python wrapper to access the amazon selling partner API
https://python-amazon-sp-api.readthedocs.io/en/latest/
MIT License
531 stars 234 forks source link

load_all_pages not working with AplusContents list_content_document_asin_relations #1389

Closed tilschuenemann closed 6 months ago

tilschuenemann commented 6 months ago

Describe the bug While using the AplusContent API I stumbled upon the following issue:

Calling list_content_document_asin_relations() on a A+ content document with more then 1000 ASINs will only return the first 1000 ASINs, if includedDataSet is empty. This is problematic when you want to fetch metadata for all ASINs for a A+ document.

To Reproduce

Steps to reproduce the behavior:


from sp_api.api import AplusContent
from sp_api.util import load_all_pages
from sp_api.base import Marketplaces

crk = "" # this A+ has 1066 ASINs
mp_id = "A1PA6795UKMFR9"
mp = Marketplaces.DE
credentials = {
    "lwa_app_id": "",
    "lwa_client_secret": "",
    "refresh_token": "",
}

ac = AplusContent(
    credentials=credentials,
    marketplace=mp,
)
 res_1 = ac.list_content_document_asin_relations(contentReferenceKey=crk, marketplaceId=mp_id, includedDataSet="METADATA")
print(len(res_1.payload["asinMetadataSet"]))  # 1000

res_2 = ac.list_content_document_asin_relations(contentReferenceKey=crk, marketplaceId=mp_id, includedDataSet="")
print(len(res_2.payload["asinMetadataSet"]))  # 1066, but no metadata :(

# In order to use load_all_pages, I'd check for the name of key containing the next token:
print(res_1.next_token) # None
print(res_1.payload["nextPageToken"])  # 'B0C8CK2D22'

# What I would expect to work, having read the docs:
# @load_all_pages(next_token_param="nextPageToken")
# def list_content_document_asin_relations(*args, **kwargs):
#     return ac.list_content_document_asin_relations(*args, **kwargs)

Upon further inspection of load_all_pages(), one can see that only res.next_token gets checked.

My workaround:

@load_all_pages(next_token_param="pageToken")
def list_content_document_asin_relations(*args, **kwargs):
    tmp = ac.list_content_document_asin_relations(*args, **kwargs)
    tmp.next_token = tmp.payload["nextPageToken"]
    return tmp
res_3 = []
for page in list_content_document_asin_relations(contentReferenceKey=crk, marketplaceId=mp_id, includedDataSet="METADATA"):
    res_3 += page.payload["asinMetadataSet"]
print(len(res_3))  # 1066, with metadata :)

Expected behavior

When specifying next_token_param in load_all_pages(), it should check the payload as well.

Desktop (please complete the following information):

saleweaver commented 6 months ago

Hi,

thanks for raising this. Please upgrade to 1.5.1, should be fixed there.

saleweaver commented 6 months ago

.... @tilschuenemann you can use the load_all_pages decorator like described in the docs, the next token param gets parsed for the endpoint now...