python-amazon-paapi 7.0.0__tar.gz → 7.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/CHANGELOG.md +10 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/PKG-INFO +16 -3
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/README.md +15 -2
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/aio/api.py +5 -3
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/aio/auth.py +13 -5
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/aio/client.py +9 -5
- python_amazon_paapi-7.1.0/amazon_creatorsapi/aio/timeouts.py +49 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/api.py +5 -3
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/auth.py +9 -3
- python_amazon_paapi-7.1.0/amazon_creatorsapi/core/constants.py +35 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/validation.py +31 -4
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/conf.py +1 -1
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/pages/migration-guide-7.md +4 -3
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/pages/usage-guide.md +15 -2
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/pyproject.toml +1 -1
- python_amazon_paapi-7.1.0/tests/amazon_creatorsapi/aio/timeouts_test.py +37 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/api_test.py +54 -1
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/validation_test.py +24 -0
- python_amazon_paapi-7.0.0/amazon_creatorsapi/core/constants.py +0 -16
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.agent/rules/code-style-guide.md +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.env.template +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.github/ISSUE_TEMPLATE/---bug-report.md +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.github/ISSUE_TEMPLATE/---feature-request.md +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.github/workflows/check.yml +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.github/workflows/release.yml +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.gitignore +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.pre-commit-config.yaml +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.readthedocs.yml +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/CONTRIBUTING.md +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/LICENSE +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/Makefile +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/aio/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/error_handling.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/items.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/marketplaces.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/oauth.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/parsers.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/requests.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/resources.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/results.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/retry.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/errors.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/models.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/py.typed +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/api/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/api/default_api.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/api_client.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/api_response.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/auth/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/auth/oauth2_config.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/auth/oauth2_token_manager.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/configuration.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/exceptions.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/access_denied_exception_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/access_denied_reason.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/availability.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/browse_node.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/browse_node_ancestor.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/browse_node_child.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/browse_node_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/browse_nodes_result.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/by_line_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/classifications.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/condition.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/content_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/content_rating.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/contributor.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/customer_reviews.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/deal_details.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/delivery_flag.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/dimension_based_attribute.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/error_data.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/external_ids.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/feed.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/feed_type.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_browse_nodes_request_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_browse_nodes_resource.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_browse_nodes_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_feed_request_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_feed_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_items_request_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_items_resource.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_items_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_report_request_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_report_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_variations_request_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_variations_resource.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/get_variations_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/image_size.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/image_type.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/images.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/internal_server_exception_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/item.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/item_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/items_result.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/language_type.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/languages.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/list_feeds_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/list_reports_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/manufacture_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/money.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/multi_valued_attribute.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_availability_v2.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_condition_v2.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_listing_v2.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_loyalty_points_v2.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_merchant_info_v2.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_price_v2.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_saving_basis.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_savings.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offer_type.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/offers_v2.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/product_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/rating.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/refinement.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/refinement_bin.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/report_metadata.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/report_type.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/resource_not_found_exception_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/saving_basis_type.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/search_items_request_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/search_items_resource.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/search_items_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/search_refinements.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/search_result.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/single_boolean_valued_attribute.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/single_integer_valued_attribute.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/single_string_valued_attribute.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/sort_by.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/technical_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/throttle_exception_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/trade_in_info.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/trade_in_price.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/unauthorized_exception_reason.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/unauthorized_exception_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/unit_based_attribute.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/validation_exception_field.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/validation_exception_reason.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/validation_exception_response_content.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/variation_attribute.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/variation_dimension.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/variation_summary.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/variation_summary_price.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/variations_result.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/models/website_sales_rank.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/py.typed +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/creatorsapi_python_sdk/rest.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/Makefile +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/_static/pa-paapi-icon.ico +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/_static/pa-paapi-logo.png +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/amazon_creatorsapi.aio.rst +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/amazon_creatorsapi.core.rst +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/amazon_creatorsapi.errors.rst +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/amazon_creatorsapi.models.rst +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/amazon_creatorsapi.rst +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/index.rst +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/make.bat +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/pages/migration-guide-6.md +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/docs/requirements.txt +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/scripts/check_version.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/aio/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/aio/api_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/aio/auth_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/aio/client_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/aio/integration_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/__init__.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/auth_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/error_handling_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/items_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/oauth_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/requests_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/results_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/retry_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/core/sdk_parity_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/errors_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/integration_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/signatures_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/tools_test.py +0 -0
- {python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/integration_support.py +0 -0
|
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [7.1.0] - 2026-09-16
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `timeout` in `AmazonCreatorsApi` and `AsyncAmazonCreatorsApi` accepts a pair of `(connect, read)` seconds, bounding each leg of a request on its own, so a host resolving to several addresses cannot spend a read-sized timeout on every one of them
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- The default timeout is `(5, 25)` rather than `30`, five seconds to connect and twenty-five to read. It adds up to the thirty seconds that have always been documented and makes them true of the token request and of the async client too, where a single value was applied to each leg separately and allowed sixty. A response taking between twenty-five and thirty seconds now times out where it used to arrive
|
|
17
|
+
|
|
8
18
|
## [7.0.0] - 2026-09-04
|
|
9
19
|
|
|
10
20
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: python-amazon-paapi
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.1.0
|
|
4
4
|
Summary: Amazon Creators API wrapper for Python
|
|
5
5
|
Project-URL: Homepage, https://github.com/sergioteula/python-amazon-paapi
|
|
6
6
|
Project-URL: Repository, https://github.com/sergioteula/python-amazon-paapi
|
|
@@ -260,8 +260,11 @@ The interval is kept per client and is safe to share between threads.
|
|
|
260
260
|
|
|
261
261
|
### Timeout
|
|
262
262
|
|
|
263
|
-
Timeout value represents the number of seconds to wait for a response before failing
|
|
264
|
-
|
|
263
|
+
Timeout value represents the number of seconds to wait for a response before failing.
|
|
264
|
+
Use `None` to wait indefinitely.
|
|
265
|
+
|
|
266
|
+
The default is `(5, 25)`: five seconds to establish the connection and twenty-five to
|
|
267
|
+
read the response, thirty in total.
|
|
265
268
|
|
|
266
269
|
```python
|
|
267
270
|
api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=10) # Fails after 10 seconds
|
|
@@ -270,6 +273,16 @@ api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=0.5) # Fails
|
|
|
270
273
|
|
|
271
274
|
It applies to every API request, including the OAuth2 token refresh.
|
|
272
275
|
|
|
276
|
+
A pair of `(connect, read)` seconds bounds each leg of the request on its own. This
|
|
277
|
+
matters for a host resolving to several addresses: the connect leg is spent once per
|
|
278
|
+
address, so a single value generous enough to read a slow response is also spent on
|
|
279
|
+
every address that fails to answer.
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
# Gives up on an unresponsive address after 1 second, and still reads for 10
|
|
283
|
+
api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=(1, 10))
|
|
284
|
+
```
|
|
285
|
+
|
|
273
286
|
### Retries
|
|
274
287
|
|
|
275
288
|
Amazon asks clients to back off and try again when it throttles a request or fails to
|
|
@@ -226,8 +226,11 @@ The interval is kept per client and is safe to share between threads.
|
|
|
226
226
|
|
|
227
227
|
### Timeout
|
|
228
228
|
|
|
229
|
-
Timeout value represents the number of seconds to wait for a response before failing
|
|
230
|
-
|
|
229
|
+
Timeout value represents the number of seconds to wait for a response before failing.
|
|
230
|
+
Use `None` to wait indefinitely.
|
|
231
|
+
|
|
232
|
+
The default is `(5, 25)`: five seconds to establish the connection and twenty-five to
|
|
233
|
+
read the response, thirty in total.
|
|
231
234
|
|
|
232
235
|
```python
|
|
233
236
|
api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=10) # Fails after 10 seconds
|
|
@@ -236,6 +239,16 @@ api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=0.5) # Fails
|
|
|
236
239
|
|
|
237
240
|
It applies to every API request, including the OAuth2 token refresh.
|
|
238
241
|
|
|
242
|
+
A pair of `(connect, read)` seconds bounds each leg of the request on its own. This
|
|
243
|
+
matters for a host resolving to several addresses: the connect leg is spent once per
|
|
244
|
+
address, so a single value generous enough to read a slow response is also spent on
|
|
245
|
+
every address that fails to answer.
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
# Gives up on an unresponsive address after 1 second, and still reads for 10
|
|
249
|
+
api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=(1, 10))
|
|
250
|
+
```
|
|
251
|
+
|
|
239
252
|
### Retries
|
|
240
253
|
|
|
241
254
|
Amazon asks clients to back off and try again when it throttles a request or fails to
|
|
@@ -87,6 +87,7 @@ from creatorsapi_python_sdk.models.search_items_resource import SearchItemsResou
|
|
|
87
87
|
if TYPE_CHECKING:
|
|
88
88
|
from types import TracebackType
|
|
89
89
|
|
|
90
|
+
from amazon_creatorsapi.core.constants import TimeoutValue
|
|
90
91
|
from amazon_creatorsapi.core.marketplaces import CountryCode
|
|
91
92
|
from creatorsapi_python_sdk.models.availability import Availability
|
|
92
93
|
from creatorsapi_python_sdk.models.condition import Condition
|
|
@@ -168,8 +169,9 @@ class AsyncAmazonCreatorsApi:
|
|
|
168
169
|
country: Country code (e.g., "ES", "US"). Used to determine marketplace.
|
|
169
170
|
marketplace: Marketplace URL (e.g., "www.amazon.es"). Overrides country.
|
|
170
171
|
throttling: Wait time in seconds between API calls. Defaults to 1 second.
|
|
171
|
-
timeout: Request timeout in seconds,
|
|
172
|
-
|
|
172
|
+
timeout: Request timeout in seconds, a pair of ``(connect, read)``
|
|
173
|
+
seconds bounding each leg on its own, or None to wait
|
|
174
|
+
indefinitely. Defaults to 5 seconds to connect and 25 to read.
|
|
173
175
|
retries: Extra attempts for the failures that Amazon asks to retry,
|
|
174
176
|
waiting longer before every attempt. Defaults to 3.
|
|
175
177
|
host: Base URL of the API. Defaults to the Amazon Creators API.
|
|
@@ -196,7 +198,7 @@ class AsyncAmazonCreatorsApi:
|
|
|
196
198
|
country: CountryCode | None = None,
|
|
197
199
|
marketplace: str | None = None,
|
|
198
200
|
throttling: float = DEFAULT_THROTTLING,
|
|
199
|
-
timeout:
|
|
201
|
+
timeout: TimeoutValue | None = DEFAULT_TIMEOUT,
|
|
200
202
|
retries: int = DEFAULT_RETRIES,
|
|
201
203
|
host: str = DEFAULT_HOST,
|
|
202
204
|
auth_endpoint: str | None = None,
|
|
@@ -7,8 +7,9 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
import asyncio
|
|
9
9
|
import time
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import TYPE_CHECKING, Any
|
|
11
11
|
|
|
12
|
+
from amazon_creatorsapi.aio.timeouts import build_httpx_timeout
|
|
12
13
|
from amazon_creatorsapi.core.constants import DEFAULT_TIMEOUT, HTTP_OK
|
|
13
14
|
from amazon_creatorsapi.core.oauth import (
|
|
14
15
|
COGNITO_SCOPE,
|
|
@@ -23,6 +24,9 @@ from amazon_creatorsapi.core.oauth import (
|
|
|
23
24
|
)
|
|
24
25
|
from amazon_creatorsapi.errors import AuthenticationError
|
|
25
26
|
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from amazon_creatorsapi.core.constants import TimeoutValue
|
|
29
|
+
|
|
26
30
|
try:
|
|
27
31
|
import httpx
|
|
28
32
|
except ImportError as exc: # pragma: no cover
|
|
@@ -61,8 +65,10 @@ class AsyncOAuth2TokenManager:
|
|
|
61
65
|
credential_secret: OAuth2 credential secret.
|
|
62
66
|
version: API version (determines auth endpoint).
|
|
63
67
|
auth_endpoint: Optional custom auth endpoint URL.
|
|
64
|
-
timeout: Token request timeout in seconds,
|
|
65
|
-
|
|
68
|
+
timeout: Token request timeout in seconds, a pair of
|
|
69
|
+
``(connect, read)`` seconds bounding each leg on its own, or None
|
|
70
|
+
to wait indefinitely. Defaults to 5 seconds to connect and
|
|
71
|
+
25 to read.
|
|
66
72
|
|
|
67
73
|
"""
|
|
68
74
|
|
|
@@ -72,7 +78,7 @@ class AsyncOAuth2TokenManager:
|
|
|
72
78
|
credential_secret: str,
|
|
73
79
|
version: str,
|
|
74
80
|
auth_endpoint: str | None = None,
|
|
75
|
-
timeout:
|
|
81
|
+
timeout: TimeoutValue | None = DEFAULT_TIMEOUT,
|
|
76
82
|
) -> None:
|
|
77
83
|
"""Initialize the async OAuth2 token manager."""
|
|
78
84
|
self._credential_id = credential_id
|
|
@@ -189,7 +195,9 @@ class AsyncOAuth2TokenManager:
|
|
|
189
195
|
}
|
|
190
196
|
|
|
191
197
|
try:
|
|
192
|
-
async with httpx.AsyncClient(
|
|
198
|
+
async with httpx.AsyncClient(
|
|
199
|
+
timeout=build_httpx_timeout(self._timeout),
|
|
200
|
+
) as client:
|
|
193
201
|
if self.is_lwa():
|
|
194
202
|
response = await client.post(
|
|
195
203
|
self._auth_endpoint,
|
|
@@ -12,11 +12,14 @@ from typing import TYPE_CHECKING, Any
|
|
|
12
12
|
|
|
13
13
|
from typing_extensions import Self
|
|
14
14
|
|
|
15
|
+
from amazon_creatorsapi.aio.timeouts import build_httpx_timeout
|
|
15
16
|
from amazon_creatorsapi.core.constants import DEFAULT_TIMEOUT
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
18
19
|
from types import TracebackType
|
|
19
20
|
|
|
21
|
+
from amazon_creatorsapi.core.constants import TimeoutValue
|
|
22
|
+
|
|
20
23
|
try:
|
|
21
24
|
import httpx
|
|
22
25
|
except ImportError as exc: # pragma: no cover
|
|
@@ -65,15 +68,16 @@ class AsyncHttpClient:
|
|
|
65
68
|
|
|
66
69
|
Args:
|
|
67
70
|
host: Base URL for API requests. Defaults to Amazon Creators API.
|
|
68
|
-
timeout: Request timeout in seconds,
|
|
69
|
-
|
|
71
|
+
timeout: Request timeout in seconds, a pair of ``(connect, read)``
|
|
72
|
+
seconds bounding each leg on its own, or None to wait
|
|
73
|
+
indefinitely. Defaults to 5 seconds to connect and 25 to read.
|
|
70
74
|
|
|
71
75
|
"""
|
|
72
76
|
|
|
73
77
|
def __init__(
|
|
74
78
|
self,
|
|
75
79
|
host: str = DEFAULT_HOST,
|
|
76
|
-
timeout:
|
|
80
|
+
timeout: TimeoutValue | None = DEFAULT_TIMEOUT,
|
|
77
81
|
) -> None:
|
|
78
82
|
"""Initialize the async HTTP client."""
|
|
79
83
|
self._host = host
|
|
@@ -85,7 +89,7 @@ class AsyncHttpClient:
|
|
|
85
89
|
"""Enter async context manager, creating a persistent client."""
|
|
86
90
|
self._client = httpx.AsyncClient(
|
|
87
91
|
base_url=self._host,
|
|
88
|
-
timeout=self._timeout,
|
|
92
|
+
timeout=build_httpx_timeout(self._timeout),
|
|
89
93
|
headers={"User-Agent": USER_AGENT},
|
|
90
94
|
)
|
|
91
95
|
self._owns_client = True
|
|
@@ -134,7 +138,7 @@ class AsyncHttpClient:
|
|
|
134
138
|
# Create a new client for this request (standalone mode)
|
|
135
139
|
async with httpx.AsyncClient(
|
|
136
140
|
base_url=self._host,
|
|
137
|
-
timeout=self._timeout,
|
|
141
|
+
timeout=build_httpx_timeout(self._timeout),
|
|
138
142
|
) as client:
|
|
139
143
|
response = await client.post(
|
|
140
144
|
path,
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Conversion of the timeout values into the ones httpx understands.
|
|
2
|
+
|
|
3
|
+
It lives here rather than next to the values themselves because httpx is an
|
|
4
|
+
optional dependency, and the synchronous client must keep importing without
|
|
5
|
+
it.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from amazon_creatorsapi.core.constants import TimeoutValue
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import httpx
|
|
17
|
+
except ImportError as exc: # pragma: no cover
|
|
18
|
+
msg = (
|
|
19
|
+
"httpx is required for async support. "
|
|
20
|
+
"Install it with: pip install python-amazon-paapi[async]"
|
|
21
|
+
)
|
|
22
|
+
raise ImportError(msg) from exc
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def build_httpx_timeout(
|
|
26
|
+
timeout: TimeoutValue | None,
|
|
27
|
+
) -> float | httpx.Timeout | None:
|
|
28
|
+
"""Return the timeout to hand to httpx for a value the clients accept.
|
|
29
|
+
|
|
30
|
+
A pair is the only value httpx needs help with. Everything else is passed
|
|
31
|
+
through as it is, so httpx keeps reading it exactly as it did before pairs
|
|
32
|
+
were accepted.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
timeout: Seconds for the whole request, ``(connect, read)`` seconds
|
|
36
|
+
per leg, or None to wait indefinitely.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
The seconds, the httpx timeout built from the pair, or None to wait
|
|
40
|
+
indefinitely.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
if not isinstance(timeout, tuple):
|
|
44
|
+
return timeout
|
|
45
|
+
connect, read = timeout
|
|
46
|
+
# httpx reads a pair as (connect, read, write, pool) and leaves the two it
|
|
47
|
+
# does not find unbounded, which would drop a timeout that the single
|
|
48
|
+
# value form applies. The read value covers them instead.
|
|
49
|
+
return httpx.Timeout(connect=connect, read=read, write=read, pool=read)
|
|
@@ -77,6 +77,7 @@ from creatorsapi_python_sdk.models.search_items_resource import SearchItemsResou
|
|
|
77
77
|
if TYPE_CHECKING:
|
|
78
78
|
from types import TracebackType
|
|
79
79
|
|
|
80
|
+
from amazon_creatorsapi.core.constants import TimeoutValue
|
|
80
81
|
from amazon_creatorsapi.core.marketplaces import CountryCode
|
|
81
82
|
from creatorsapi_python_sdk.models.availability import Availability
|
|
82
83
|
from creatorsapi_python_sdk.models.browse_node import BrowseNode
|
|
@@ -109,8 +110,9 @@ class AmazonCreatorsApi:
|
|
|
109
110
|
country: Country code (e.g., "ES", "US"). Used to determine marketplace.
|
|
110
111
|
marketplace: Marketplace URL (e.g., "www.amazon.es"). Overrides country.
|
|
111
112
|
throttling: Wait time in seconds between API calls. Defaults to 1 second.
|
|
112
|
-
timeout: Request timeout in seconds,
|
|
113
|
-
|
|
113
|
+
timeout: Request timeout in seconds, a pair of ``(connect, read)``
|
|
114
|
+
seconds bounding each leg on its own, or None to wait
|
|
115
|
+
indefinitely. Defaults to 5 seconds to connect and 25 to read.
|
|
114
116
|
retries: Extra attempts for the failures that Amazon asks to retry,
|
|
115
117
|
waiting longer before every attempt. Defaults to 3.
|
|
116
118
|
host: Base URL of the API. Defaults to the Amazon Creators API.
|
|
@@ -151,7 +153,7 @@ class AmazonCreatorsApi:
|
|
|
151
153
|
country: CountryCode | None = None,
|
|
152
154
|
marketplace: str | None = None,
|
|
153
155
|
throttling: float = DEFAULT_THROTTLING,
|
|
154
|
-
timeout:
|
|
156
|
+
timeout: TimeoutValue | None = DEFAULT_TIMEOUT,
|
|
155
157
|
retries: int = DEFAULT_RETRIES,
|
|
156
158
|
host: str = DEFAULT_HOST,
|
|
157
159
|
auth_endpoint: str | None = None,
|
|
@@ -14,6 +14,7 @@ from amazon_creatorsapi.errors import AuthenticationError
|
|
|
14
14
|
from creatorsapi_python_sdk.auth.oauth2_token_manager import OAuth2TokenManager
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
|
+
from amazon_creatorsapi.core.constants import TimeoutValue
|
|
17
18
|
from creatorsapi_python_sdk.auth.oauth2_config import OAuth2Config
|
|
18
19
|
|
|
19
20
|
|
|
@@ -28,12 +29,17 @@ class TimeoutOAuth2TokenManager(OAuth2TokenManager):
|
|
|
28
29
|
|
|
29
30
|
Args:
|
|
30
31
|
config: OAuth2 configuration with the credentials and the endpoint.
|
|
31
|
-
timeout: Token request timeout in seconds,
|
|
32
|
-
|
|
32
|
+
timeout: Token request timeout in seconds, a pair of
|
|
33
|
+
``(connect, read)`` seconds bounding each leg on its own, or None
|
|
34
|
+
to wait indefinitely.
|
|
33
35
|
|
|
34
36
|
"""
|
|
35
37
|
|
|
36
|
-
def __init__(
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
config: OAuth2Config,
|
|
41
|
+
timeout: TimeoutValue | None,
|
|
42
|
+
) -> None:
|
|
37
43
|
"""Initialize the token manager with its timeout."""
|
|
38
44
|
super().__init__(config)
|
|
39
45
|
self._timeout = timeout
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Constants for the Amazon Creators API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
TimeoutValue = Union[float, "tuple[float, float]"]
|
|
8
|
+
"""Seconds for the whole request, or ``(connect, read)`` seconds per leg.
|
|
9
|
+
|
|
10
|
+
The pair matters for a host that resolves to several addresses: the connect
|
|
11
|
+
leg is spent once per address, so a single value generous enough to read a
|
|
12
|
+
slow response is also spent on every address that fails to answer.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
DEFAULT_HOST = "https://creatorsapi.amazon"
|
|
16
|
+
DEFAULT_THROTTLING = 1
|
|
17
|
+
# Connect and read seconds, rather than one value covering both. The connect
|
|
18
|
+
# leg is spent once per address the host resolves to, so a single value
|
|
19
|
+
# generous enough to read a slow response is also spent on every address that
|
|
20
|
+
# fails to answer: at 30 seconds, a host resolving to four addresses takes two
|
|
21
|
+
# minutes to give up. The two add up to the 30 seconds this has always
|
|
22
|
+
# documented, and a connection that takes longer than five seconds to
|
|
23
|
+
# establish is not one that a longer wait rescues.
|
|
24
|
+
DEFAULT_TIMEOUT = (5.0, 25.0)
|
|
25
|
+
|
|
26
|
+
# Maximum amount of item identifiers accepted in a single request
|
|
27
|
+
MAX_ITEMS_PER_REQUEST = 10
|
|
28
|
+
|
|
29
|
+
# HTTP status codes
|
|
30
|
+
HTTP_OK = 200
|
|
31
|
+
HTTP_BAD_REQUEST = 400
|
|
32
|
+
HTTP_UNAUTHORIZED = 401
|
|
33
|
+
HTTP_FORBIDDEN = 403
|
|
34
|
+
HTTP_NOT_FOUND = 404
|
|
35
|
+
HTTP_TOO_MANY_REQUESTS = 429
|
{python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/amazon_creatorsapi/core/validation.py
RENAMED
|
@@ -10,6 +10,7 @@ from amazon_creatorsapi.core.marketplaces import MARKETPLACES
|
|
|
10
10
|
from amazon_creatorsapi.errors import InvalidArgumentError
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
|
+
from amazon_creatorsapi.core.constants import TimeoutValue
|
|
13
14
|
from amazon_creatorsapi.core.marketplaces import CountryCode
|
|
14
15
|
|
|
15
16
|
RequestT = TypeVar("RequestT", bound=BaseModel)
|
|
@@ -44,21 +45,47 @@ def validate_and_get_marketplace(
|
|
|
44
45
|
raise InvalidArgumentError(msg)
|
|
45
46
|
|
|
46
47
|
|
|
47
|
-
def validate_timeout(timeout:
|
|
48
|
+
def validate_timeout(timeout: TimeoutValue | None) -> TimeoutValue | None:
|
|
48
49
|
"""Validate the request timeout value.
|
|
49
50
|
|
|
50
51
|
Args:
|
|
51
|
-
timeout: Request timeout in seconds,
|
|
52
|
+
timeout: Request timeout in seconds, a pair of ``(connect, read)``
|
|
53
|
+
seconds bounding each leg on its own, or None to wait
|
|
54
|
+
indefinitely.
|
|
52
55
|
|
|
53
56
|
Returns:
|
|
54
|
-
The timeout as a float, or None when disabled.
|
|
57
|
+
The timeout as a float, as a pair of floats, or None when disabled.
|
|
55
58
|
|
|
56
59
|
Raises:
|
|
57
|
-
InvalidArgumentError: If
|
|
60
|
+
InvalidArgumentError: If a timeout is not greater than zero, or if a
|
|
61
|
+
pair does not hold exactly two of them.
|
|
58
62
|
|
|
59
63
|
"""
|
|
60
64
|
if timeout is None:
|
|
61
65
|
return None
|
|
66
|
+
if not isinstance(timeout, tuple):
|
|
67
|
+
return _validate_seconds(timeout)
|
|
68
|
+
try:
|
|
69
|
+
connect, read = timeout
|
|
70
|
+
except ValueError as error:
|
|
71
|
+
msg = f"Timeout must be a pair of (connect, read) seconds: {timeout!r}"
|
|
72
|
+
raise InvalidArgumentError(msg) from error
|
|
73
|
+
return _validate_seconds(connect), _validate_seconds(read)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _validate_seconds(timeout: float) -> float:
|
|
77
|
+
"""Validate a number of seconds used as a timeout.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
timeout: Timeout in seconds, whether on its own or one leg of a pair.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The timeout as a float.
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
InvalidArgumentError: If it is not a number greater than zero.
|
|
87
|
+
|
|
88
|
+
"""
|
|
62
89
|
try:
|
|
63
90
|
value = float(timeout)
|
|
64
91
|
except (TypeError, ValueError) as error:
|
|
@@ -18,7 +18,7 @@ the changes that look breaking and are not.
|
|
|
18
18
|
| `search_items` needs a criterion | A search with only filters | Add `keywords` or any other criterion |
|
|
19
19
|
| `get_items` raises when nothing is found | `if not items:` | Catch `ItemsNotFoundError`, or use `include_unavailable` |
|
|
20
20
|
| `get_items` returns the requested order | Reading the response by position | Read it by position, or match by `asin` |
|
|
21
|
-
| The synchronous client times out | Requests above
|
|
21
|
+
| The synchronous client times out | Requests above 5 seconds to connect or 25 to read | Pass `timeout` |
|
|
22
22
|
| Failed requests are retried | Handling a `429` yourself | Pass `retries=0` |
|
|
23
23
|
| `get_asin` rejects a long identifier | Malformed URLs | Fix the URLs |
|
|
24
24
|
| The version is validated on creation | An unsupported `version` | Use a supported one, or pass `auth_endpoint` |
|
|
@@ -156,8 +156,9 @@ every ten items, each one waiting for the configured `throttling`.
|
|
|
156
156
|
|
|
157
157
|
## Timeouts
|
|
158
158
|
|
|
159
|
-
The synchronous client waited indefinitely for a response. It now uses the same
|
|
160
|
-
|
|
159
|
+
The synchronous client waited indefinitely for a response. It now uses the same default
|
|
160
|
+
timeout as the asynchronous one, five seconds to establish the connection and
|
|
161
|
+
twenty-five to read the response:
|
|
161
162
|
|
|
162
163
|
```python
|
|
163
164
|
api = AmazonCreatorsApi(..., timeout=60) # Wait up to a minute
|
|
@@ -258,8 +258,11 @@ so several threads sharing a client still make one request every `throttling` se
|
|
|
258
258
|
|
|
259
259
|
## Timeout
|
|
260
260
|
|
|
261
|
-
Timeout value represents the number of seconds to wait for a response before failing
|
|
262
|
-
|
|
261
|
+
Timeout value represents the number of seconds to wait for a response before failing.
|
|
262
|
+
Use `None` to wait indefinitely.
|
|
263
|
+
|
|
264
|
+
The default is `(5, 25)`: five seconds to establish the connection and twenty-five to
|
|
265
|
+
read the response, thirty in total.
|
|
263
266
|
|
|
264
267
|
```python
|
|
265
268
|
api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=10) # Fails after 10 seconds
|
|
@@ -268,6 +271,16 @@ api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=0.5) # Fails
|
|
|
268
271
|
|
|
269
272
|
It applies to every API request, including the OAuth2 token refresh.
|
|
270
273
|
|
|
274
|
+
A pair of `(connect, read)` seconds bounds each leg of the request on its own. This
|
|
275
|
+
matters for a host resolving to several addresses: the connect leg is spent once per
|
|
276
|
+
address, so a single value generous enough to read a slow response is also spent on
|
|
277
|
+
every address that fails to answer.
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
# Gives up on an unresponsive address after 1 second, and still reads for 10
|
|
281
|
+
api = AmazonCreatorsApi(ID, SECRET, VERSION, TAG, COUNTRY, timeout=(1, 10))
|
|
282
|
+
```
|
|
283
|
+
|
|
271
284
|
## Retries
|
|
272
285
|
|
|
273
286
|
Amazon asks clients to back off and try again when it throttles a request or fails to
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Unit tests for the conversion of the timeouts into httpx timeouts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import unittest
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
|
|
9
|
+
from amazon_creatorsapi.aio.timeouts import build_httpx_timeout
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestBuildHttpxTimeout(unittest.TestCase):
|
|
13
|
+
"""Tests for build_httpx_timeout function."""
|
|
14
|
+
|
|
15
|
+
def test_none_waits_indefinitely(self) -> None:
|
|
16
|
+
"""Test that None is passed through as no timeout."""
|
|
17
|
+
self.assertIsNone(build_httpx_timeout(None))
|
|
18
|
+
|
|
19
|
+
def test_seconds_are_passed_through(self) -> None:
|
|
20
|
+
"""Test that a single value reaches httpx as it did before."""
|
|
21
|
+
self.assertEqual(build_httpx_timeout(5), 5)
|
|
22
|
+
|
|
23
|
+
def test_pair_bounds_every_leg(self) -> None:
|
|
24
|
+
"""Test that a pair bounds each leg, leaving none of them unbounded.
|
|
25
|
+
|
|
26
|
+
Handed a pair of its own, httpx reads it as the first two of
|
|
27
|
+
(connect, read, write, pool) and leaves the write and the pool legs
|
|
28
|
+
unbounded, dropping a timeout that the single value form applies. The
|
|
29
|
+
read value covers them instead.
|
|
30
|
+
"""
|
|
31
|
+
timeout = build_httpx_timeout((1, 5))
|
|
32
|
+
|
|
33
|
+
self.assertEqual(timeout, httpx.Timeout(connect=1, read=5, write=5, pool=5))
|
|
34
|
+
self.assertNotEqual(
|
|
35
|
+
timeout,
|
|
36
|
+
httpx.Timeout(connect=1, read=5, write=None, pool=None),
|
|
37
|
+
)
|
{python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/tests/amazon_creatorsapi/api_test.py
RENAMED
|
@@ -12,7 +12,7 @@ import urllib3
|
|
|
12
12
|
|
|
13
13
|
from amazon_creatorsapi import AmazonCreatorsApi
|
|
14
14
|
from amazon_creatorsapi.core.auth import TimeoutOAuth2TokenManager
|
|
15
|
-
from amazon_creatorsapi.core.constants import DEFAULT_TIMEOUT
|
|
15
|
+
from amazon_creatorsapi.core.constants import DEFAULT_TIMEOUT, TimeoutValue
|
|
16
16
|
from amazon_creatorsapi.core.oauth import VERSION_ENDPOINTS
|
|
17
17
|
from amazon_creatorsapi.errors import (
|
|
18
18
|
AccessDeniedError,
|
|
@@ -1533,6 +1533,59 @@ class TestAmazonCreatorsApiItems(unittest.TestCase):
|
|
|
1533
1533
|
self.assertEqual(token_manager._timeout, 12.0)
|
|
1534
1534
|
self.assertEqual(api.timeout, 12.0)
|
|
1535
1535
|
|
|
1536
|
+
@mock.patch("amazon_creatorsapi.api.ApiClient")
|
|
1537
|
+
def test_timeout_accepts_a_pair(self, mock_client_class: MagicMock) -> None:
|
|
1538
|
+
"""Test that a pair reaches the SDK and the token request alike."""
|
|
1539
|
+
mock_client = MagicMock()
|
|
1540
|
+
mock_client_class.return_value = mock_client
|
|
1541
|
+
|
|
1542
|
+
api = self.build_api_with_timeouts(timeout=(1.0, 12.0))
|
|
1543
|
+
|
|
1544
|
+
self.assertEqual(api.timeout, (1.0, 12.0))
|
|
1545
|
+
self.assertEqual(mock_client._token_manager._timeout, (1.0, 12.0))
|
|
1546
|
+
|
|
1547
|
+
@mock.patch("amazon_creatorsapi.api.ApiClient")
|
|
1548
|
+
def test_invalid_pair_raises_library_error(
|
|
1549
|
+
self,
|
|
1550
|
+
mock_client_class: MagicMock,
|
|
1551
|
+
) -> None:
|
|
1552
|
+
"""Test that a pair is validated like a single value."""
|
|
1553
|
+
mock_client_class.return_value = MagicMock()
|
|
1554
|
+
|
|
1555
|
+
with self.assertRaises(InvalidArgumentError):
|
|
1556
|
+
self.build_api_with_timeouts(timeout=(0, 12.0))
|
|
1557
|
+
|
|
1558
|
+
@mock.patch("amazon_creatorsapi.api.ApiClient")
|
|
1559
|
+
def test_default_timeout_bounds_connect_and_read_apart(
|
|
1560
|
+
self,
|
|
1561
|
+
mock_client_class: MagicMock,
|
|
1562
|
+
) -> None:
|
|
1563
|
+
"""Test that the default bounds each leg, and still adds up to 30.
|
|
1564
|
+
|
|
1565
|
+
A single value is spent on the connect leg once per address the host
|
|
1566
|
+
resolves to, so the default splits the thirty seconds it has always
|
|
1567
|
+
documented rather than applying them twice over.
|
|
1568
|
+
"""
|
|
1569
|
+
mock_client_class.return_value = MagicMock()
|
|
1570
|
+
|
|
1571
|
+
api = self.build_api_with_timeouts()
|
|
1572
|
+
|
|
1573
|
+
self.assertEqual(api.timeout, (5.0, 25.0))
|
|
1574
|
+
|
|
1575
|
+
def build_api_with_timeouts(
|
|
1576
|
+
self,
|
|
1577
|
+
timeout: TimeoutValue | None = DEFAULT_TIMEOUT,
|
|
1578
|
+
) -> AmazonCreatorsApi:
|
|
1579
|
+
"""Build an API client with the given timeout."""
|
|
1580
|
+
return AmazonCreatorsApi(
|
|
1581
|
+
credential_id=self.credential_id,
|
|
1582
|
+
credential_secret=self.credential_secret,
|
|
1583
|
+
version=self.version,
|
|
1584
|
+
tag=self.tag,
|
|
1585
|
+
country=self.country,
|
|
1586
|
+
timeout=timeout,
|
|
1587
|
+
)
|
|
1588
|
+
|
|
1536
1589
|
@mock.patch("amazon_creatorsapi.api.DefaultApi")
|
|
1537
1590
|
@mock.patch("amazon_creatorsapi.api.ApiClient")
|
|
1538
1591
|
def test_get_items_without_items_raises_library_error(
|
|
@@ -66,6 +66,30 @@ class TestValidateTimeout(unittest.TestCase):
|
|
|
66
66
|
with self.assertRaises(InvalidArgumentError):
|
|
67
67
|
validate_timeout("slow") # type: ignore[arg-type]
|
|
68
68
|
|
|
69
|
+
def test_returns_a_pair_of_floats(self) -> None:
|
|
70
|
+
"""Test that a pair of connect and read timeouts is returned."""
|
|
71
|
+
self.assertEqual(validate_timeout((1, 5)), (1.0, 5.0))
|
|
72
|
+
|
|
73
|
+
def test_pair_of_the_wrong_length_is_rejected(self) -> None:
|
|
74
|
+
"""Test that a tuple that is not a pair is rejected."""
|
|
75
|
+
for timeout in ((5,), (1, 5, 10)):
|
|
76
|
+
with self.subTest(timeout=timeout):
|
|
77
|
+
with self.assertRaises(InvalidArgumentError) as context:
|
|
78
|
+
validate_timeout(timeout) # type: ignore[arg-type]
|
|
79
|
+
self.assertIn("pair of (connect, read)", str(context.exception))
|
|
80
|
+
|
|
81
|
+
def test_pair_holding_zero_is_rejected(self) -> None:
|
|
82
|
+
"""Test that neither leg of a pair may be zero."""
|
|
83
|
+
for timeout in ((0, 5), (1, 0)):
|
|
84
|
+
with self.subTest(timeout=timeout):
|
|
85
|
+
with self.assertRaises(InvalidArgumentError):
|
|
86
|
+
validate_timeout(timeout)
|
|
87
|
+
|
|
88
|
+
def test_pair_holding_something_else_is_rejected(self) -> None:
|
|
89
|
+
"""Test that a pair holding a value that is not a number is rejected."""
|
|
90
|
+
with self.assertRaises(InvalidArgumentError):
|
|
91
|
+
validate_timeout((1, "slow")) # type: ignore[arg-type]
|
|
92
|
+
|
|
69
93
|
|
|
70
94
|
class TestValidateRetries(unittest.TestCase):
|
|
71
95
|
"""Tests for validate_retries function."""
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"""Constants for the Amazon Creators API."""
|
|
2
|
-
|
|
3
|
-
DEFAULT_HOST = "https://creatorsapi.amazon"
|
|
4
|
-
DEFAULT_THROTTLING = 1
|
|
5
|
-
DEFAULT_TIMEOUT = 30.0
|
|
6
|
-
|
|
7
|
-
# Maximum amount of item identifiers accepted in a single request
|
|
8
|
-
MAX_ITEMS_PER_REQUEST = 10
|
|
9
|
-
|
|
10
|
-
# HTTP status codes
|
|
11
|
-
HTTP_OK = 200
|
|
12
|
-
HTTP_BAD_REQUEST = 400
|
|
13
|
-
HTTP_UNAUTHORIZED = 401
|
|
14
|
-
HTTP_FORBIDDEN = 403
|
|
15
|
-
HTTP_NOT_FOUND = 404
|
|
16
|
-
HTTP_TOO_MANY_REQUESTS = 429
|
|
File without changes
|
|
File without changes
|
{python_amazon_paapi-7.0.0 → python_amazon_paapi-7.1.0}/.github/ISSUE_TEMPLATE/---bug-report.md
RENAMED
|
File without changes
|