click_and_drop_api 3.0.2__tar.gz → 3.0.3__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.
- {click_and_drop_api-3.0.2/click_and_drop_api.egg-info → click_and_drop_api-3.0.3}/PKG-INFO +1 -1
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/shipping_countries.py +6 -1
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/api.py +5 -42
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/base.py +126 -32
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/mock.py +6 -15
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/package_shipping_option.py +40 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3/click_and_drop_api.egg-info}/PKG-INFO +1 -1
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/pyproject.toml +1 -1
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_mock_api.py +43 -63
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_shipping_option_model.py +15 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/LICENSE +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/MANIFEST.in +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/README.md +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/__init__.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/api/__init__.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/api/labels_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/api/manifests_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/api/orders_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/api/version_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/api_client.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/api_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/configuration.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/__init__.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/__main__.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/check_oba.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/create_order.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/generate_label.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/package_size_and_cost.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/view_order.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/view_specific_orders.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/examples/view_version.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/exceptions.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/__init__.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/address_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/billing_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/create_order_error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/create_order_label_error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/create_order_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/create_order_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/create_orders_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/create_orders_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/create_packages_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/delete_orders_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/deleted_order_info.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/dimensions_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/failed_order_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_order_details_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_order_info_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_order_line_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_orders_details_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_orders_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_postal_details_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_shipping_details_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_tag_details_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/get_version_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/importer.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/label_generation_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/manifest_details_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/manifest_eligible_orders_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/manifest_errors_error_details_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/manifest_errors_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/manifest_orders_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/order_error_info.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/order_error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/order_field_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/order_update_error.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/postage_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/product_item_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/recipient_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/sender_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/shipment_package_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/tag_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/update_order_status_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/update_order_status_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/update_orders_status_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/models/updated_order_info.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/py.typed +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/rest.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/__init__.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/addresses.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/errors.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/__init__.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/db.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/documents.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/format_dimensions.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/large_letter.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/large_parcel.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/letter.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/medium_parcel.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/large_letter-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/large_letter-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/large_parcel-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/large_parcel-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/letter-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/letter-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/medium_parcel-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/medium_parcel-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/small_parcel-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/non-oba codes/small_parcel-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba-codes/documents-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba-codes/large_letter-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba-codes/large_letter-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba-codes/letter-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba-codes/letter-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba-codes/parcel-DE.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba-codes/parcel-GB.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/oba_parser.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/parcel.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/parser.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping/small_parcel.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/shipping_test_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api/simple/types.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api.egg-info/SOURCES.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api.egg-info/dependency_links.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api.egg-info/requires.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/click_and_drop_api.egg-info/top_level.txt +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/setup.cfg +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/setup.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_address_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_billing_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_choose_size_by_weight.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_create_order_error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_create_order_label_error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_create_order_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_create_order_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_create_orders_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_create_orders_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_create_packages_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_delete_orders_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_deleted_order_info.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_dimensions_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_failed_order_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_order_details_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_order_info_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_order_line_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_orders_details_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_orders_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_postal_details_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_shipping_details_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_tag_details_result.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_get_version_resource.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_importer.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_label_generation_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_labels_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_manifest_details_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_manifest_eligible_orders_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_manifest_errors_error_details_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_manifest_errors_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_manifest_orders_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_manifests_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_oba_parser.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_order_error_info.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_order_error_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_order_field_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_order_update_error.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_orders_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_parcel_constraints.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_parcel_weights.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_postage_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_product_item_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_recipient_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_sender_details_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_shipment_package_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_shipping_options.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_simple_create_api.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_tag_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_update_order_status_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_update_order_status_response.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_update_orders_status_request.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_updated_order_info.py +0 -0
- {click_and_drop_api-3.0.2 → click_and_drop_api-3.0.3}/test/test_version_api.py +0 -0
|
@@ -3,9 +3,14 @@
|
|
|
3
3
|
|
|
4
4
|
Uses test_shipping internally: a test order is created and immediately deleted
|
|
5
5
|
for each country, so no real shipments are made.
|
|
6
|
+
|
|
7
|
+
Arguments:
|
|
8
|
+
|
|
9
|
+
- service code (optional, defaults to OLP1)
|
|
6
10
|
"""
|
|
7
11
|
|
|
8
12
|
import os
|
|
13
|
+
import sys
|
|
9
14
|
|
|
10
15
|
from click_and_drop_api.simple import ClickAndDrop
|
|
11
16
|
|
|
@@ -14,7 +19,7 @@ API_KEY = os.environ["API_KEY"]
|
|
|
14
19
|
api = ClickAndDrop(API_KEY)
|
|
15
20
|
|
|
16
21
|
PACKAGE_SIZE = "letter"
|
|
17
|
-
SERVICE_CODE = "OLP1"
|
|
22
|
+
SERVICE_CODE = "OLP1" if len(sys.argv) == 1 else sys.argv[1]
|
|
18
23
|
|
|
19
24
|
countries = api.get_countries_for_shipping(
|
|
20
25
|
package_size=PACKAGE_SIZE,
|
|
@@ -101,60 +101,23 @@ class ClickAndDrop(AbstractClickAndDrop):
|
|
|
101
101
|
"""The API key in use."""
|
|
102
102
|
return self._key
|
|
103
103
|
|
|
104
|
-
def
|
|
105
|
-
self, order_identifiers: Union[list[Union[str, int]]
|
|
104
|
+
def _get_orders(
|
|
105
|
+
self, order_identifiers: Union[list[Union[str, int]]]
|
|
106
106
|
) -> list[click_and_drop_api.GetOrderInfoResource]:
|
|
107
|
-
"""Get specific orders.
|
|
108
|
-
|
|
109
|
-
Parameters:
|
|
110
|
-
order_identifiers:
|
|
111
|
-
One or several Order Identifiers or Order References.
|
|
112
|
-
Order Identifiers are integer numbers.
|
|
113
|
-
Order References are strings.
|
|
114
|
-
The maximum number of identifiers is 100.
|
|
115
|
-
|
|
116
|
-
Returns:
|
|
117
|
-
A list of orders
|
|
118
|
-
|
|
119
|
-
Raises:
|
|
120
|
-
click_and_drop_api.exceptions.BadRequestException if an order with the same reference already exists
|
|
121
|
-
|
|
122
|
-
https://api.parcel.royalmail.com/#tag/Orders/operation/GetSpecificOrdersAsync
|
|
123
|
-
"""
|
|
124
107
|
return self._orders_api.get_specific_orders_async(
|
|
125
108
|
order_identifiers=order_identifiers_to_string(order_identifiers)
|
|
126
109
|
)
|
|
127
110
|
|
|
128
|
-
def
|
|
129
|
-
self, order_identifiers:
|
|
111
|
+
def _delete_orders(
|
|
112
|
+
self, order_identifiers: list[Union[str, int]]
|
|
130
113
|
) -> click_and_drop_api.DeleteOrdersResource:
|
|
131
|
-
"""Delete specific orders.
|
|
132
|
-
|
|
133
|
-
Please be aware labels generated on orders which are deleted are no longer valid and must be destroyed.
|
|
134
|
-
Cancelled label information is automatically shared with Royal Mail Revenue Protection,
|
|
135
|
-
and should a cancelled label be identified on an item in the Royal Mail Network,
|
|
136
|
-
you will be charged on your account and an additional handling fee applied.
|
|
137
|
-
|
|
138
|
-
Parameters:
|
|
139
|
-
order_identifiers:
|
|
140
|
-
One or several Order Identifiers or Order References.
|
|
141
|
-
Order Identifiers are integer numbers.
|
|
142
|
-
Order References are strings.
|
|
143
|
-
The maximum number of identifiers is 100.
|
|
144
|
-
|
|
145
|
-
https://api.parcel.royalmail.com/#tag/Orders/operation/DeleteOrdersAsync
|
|
146
|
-
"""
|
|
147
114
|
return self._orders_api.delete_orders_async(
|
|
148
115
|
order_identifiers=order_identifiers_to_string(order_identifiers)
|
|
149
116
|
)
|
|
150
117
|
|
|
151
|
-
def
|
|
118
|
+
def _create_orders(
|
|
152
119
|
self, orders: Union[list[CreateOrder], CreateOrder]
|
|
153
120
|
) -> click_and_drop_api.CreateOrdersResponse:
|
|
154
|
-
"""Create a new order.
|
|
155
|
-
|
|
156
|
-
https://api.parcel.royalmail.com/#tag/Orders/operation/CreateOrdersAsync
|
|
157
|
-
"""
|
|
158
121
|
if not isinstance(orders, list):
|
|
159
122
|
orders = [orders]
|
|
160
123
|
request = click_and_drop_api.CreateOrdersRequest(items=orders)
|
|
@@ -27,6 +27,8 @@ from click_and_drop_api.simple.addresses import get_address, get_all_country_cod
|
|
|
27
27
|
class AbstractClickAndDrop(ABC):
|
|
28
28
|
"""Common interface shared by ClickAndDrop and MockClickAndDrop."""
|
|
29
29
|
|
|
30
|
+
max_order_count: int = 100
|
|
31
|
+
|
|
30
32
|
@property
|
|
31
33
|
@abstractmethod
|
|
32
34
|
def key(self) -> str:
|
|
@@ -37,10 +39,35 @@ class AbstractClickAndDrop(ABC):
|
|
|
37
39
|
"""Get the API version."""
|
|
38
40
|
|
|
39
41
|
@abstractmethod
|
|
42
|
+
def _create_orders(
|
|
43
|
+
self, orders: list[CreateOrder]
|
|
44
|
+
) -> click_and_drop_api.CreateOrdersResponse:
|
|
45
|
+
"""Create one or more orders."""
|
|
46
|
+
|
|
40
47
|
def create_orders(
|
|
41
48
|
self, orders: Union[list[CreateOrder], CreateOrder]
|
|
42
49
|
) -> click_and_drop_api.CreateOrdersResponse:
|
|
43
|
-
"""Create
|
|
50
|
+
"""Create a new orders.
|
|
51
|
+
|
|
52
|
+
Parameters:
|
|
53
|
+
orders: One or more :class:`~click_and_drop_api.simple.types.CreateOrder` instances.
|
|
54
|
+
Returns:
|
|
55
|
+
A :class:`~click_and_drop_api.CreateOrdersResponse` instance containing created and failed orders.
|
|
56
|
+
|
|
57
|
+
https://api.parcel.royalmail.com/#tag/Orders/operation/CreateOrdersAsync
|
|
58
|
+
"""
|
|
59
|
+
if isinstance(orders, CreateOrder):
|
|
60
|
+
orders = [orders]
|
|
61
|
+
result = click_and_drop_api.CreateOrdersResponse(
|
|
62
|
+
created_orders=[], failed_orders=[], success_count=0, errors_count=0
|
|
63
|
+
)
|
|
64
|
+
for i in range(0, len(orders), self.max_order_count):
|
|
65
|
+
response = self._create_orders(orders[i : i + self.max_order_count])
|
|
66
|
+
result.created_orders.extend(response.created_orders)
|
|
67
|
+
result.failed_orders.extend(response.failed_orders)
|
|
68
|
+
result.success_count += response.success_count
|
|
69
|
+
result.errors_count += response.errors_count
|
|
70
|
+
return result
|
|
44
71
|
|
|
45
72
|
def create_order(
|
|
46
73
|
self, order: CreateOrder
|
|
@@ -49,23 +76,87 @@ class AbstractClickAndDrop(ABC):
|
|
|
49
76
|
return self.create_orders(order)
|
|
50
77
|
|
|
51
78
|
@abstractmethod
|
|
79
|
+
def _get_orders(
|
|
80
|
+
self, order_identifiers: list[Union[str, int]]
|
|
81
|
+
) -> list[click_and_drop_api.GetOrderInfoResource]:
|
|
82
|
+
"""Retrieve orders by identifier or reference."""
|
|
83
|
+
|
|
52
84
|
def get_orders(
|
|
53
85
|
self, order_identifiers: Union[list[Union[str, int]], str, int]
|
|
54
86
|
) -> list[click_and_drop_api.GetOrderInfoResource]:
|
|
55
|
-
"""
|
|
87
|
+
"""Get specific orders.
|
|
88
|
+
|
|
89
|
+
Parameters:
|
|
90
|
+
order_identifiers:
|
|
91
|
+
One or several Order Identifiers or Order References.
|
|
92
|
+
Order Identifiers are integer numbers.
|
|
93
|
+
Order References are strings.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
A list of orders
|
|
97
|
+
|
|
98
|
+
Raises:
|
|
99
|
+
click_and_drop_api.exceptions.BadRequestException if an order with the same reference already exists
|
|
100
|
+
|
|
101
|
+
https://api.parcel.royalmail.com/#tag/Orders/operation/GetSpecificOrdersAsync
|
|
102
|
+
"""
|
|
103
|
+
if not isinstance(order_identifiers, list):
|
|
104
|
+
order_identifiers = [order_identifiers]
|
|
105
|
+
result = []
|
|
106
|
+
for i in range(0, len(order_identifiers), self.max_order_count):
|
|
107
|
+
result.extend(
|
|
108
|
+
self._get_orders(order_identifiers[i : i + self.max_order_count])
|
|
109
|
+
)
|
|
110
|
+
return result
|
|
56
111
|
|
|
57
112
|
def get_order(
|
|
58
113
|
self, order_identifier: Union[str, int]
|
|
59
114
|
) -> Optional[click_and_drop_api.GetOrderInfoResource]:
|
|
60
|
-
"""Retrieve a single order
|
|
115
|
+
"""Retrieve a single order.
|
|
116
|
+
|
|
117
|
+
Parameters:
|
|
118
|
+
order_identifier: Order Identifier (integer) or Order Reference (string).
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
The order if found, else None.
|
|
122
|
+
"""
|
|
61
123
|
orders = self.get_orders(order_identifier)
|
|
62
124
|
return orders[0] if orders else None
|
|
63
125
|
|
|
64
126
|
@abstractmethod
|
|
127
|
+
def _delete_orders(
|
|
128
|
+
self, order_identifiers: list[Union[str, int]]
|
|
129
|
+
) -> click_and_drop_api.DeleteOrdersResource:
|
|
130
|
+
"""Delete orders by identifier or reference."""
|
|
131
|
+
|
|
65
132
|
def delete_orders(
|
|
66
133
|
self, order_identifiers: Union[list[Union[str, int]], str, int]
|
|
67
134
|
) -> click_and_drop_api.DeleteOrdersResource:
|
|
68
|
-
"""Delete orders
|
|
135
|
+
"""Delete specific orders.
|
|
136
|
+
|
|
137
|
+
Please be aware labels generated on orders which are deleted are no longer valid and must be destroyed.
|
|
138
|
+
Cancelled label information is automatically shared with Royal Mail Revenue Protection,
|
|
139
|
+
and should a cancelled label be identified on an item in the Royal Mail Network,
|
|
140
|
+
you will be charged on your account and an additional handling fee applied.
|
|
141
|
+
|
|
142
|
+
Parameters:
|
|
143
|
+
order_identifiers:
|
|
144
|
+
One or several Order Identifiers or Order References.
|
|
145
|
+
Order Identifiers are integer numbers.
|
|
146
|
+
Order References are strings.
|
|
147
|
+
|
|
148
|
+
https://api.parcel.royalmail.com/#tag/Orders/operation/DeleteOrdersAsync
|
|
149
|
+
"""
|
|
150
|
+
if not isinstance(order_identifiers, list):
|
|
151
|
+
order_identifiers = [order_identifiers]
|
|
152
|
+
result = click_and_drop_api.DeleteOrdersResource(deleted_orders=[], errors=[])
|
|
153
|
+
for i in range(0, len(order_identifiers), self.max_order_count):
|
|
154
|
+
deleted = self._delete_orders(
|
|
155
|
+
order_identifiers[i : i + self.max_order_count]
|
|
156
|
+
)
|
|
157
|
+
result.deleted_orders.extend(deleted.deleted_orders)
|
|
158
|
+
result.errors.extend(deleted.errors)
|
|
159
|
+
return result
|
|
69
160
|
|
|
70
161
|
def delete_order(
|
|
71
162
|
self, order_identifier: Union[str, int]
|
|
@@ -101,6 +192,10 @@ class AbstractClickAndDrop(ABC):
|
|
|
101
192
|
"""Get a list of ISO 3166-1 alpha-2 country code strings.
|
|
102
193
|
|
|
103
194
|
These are the countries that can be shipped with this service.
|
|
195
|
+
|
|
196
|
+
Note:
|
|
197
|
+
This method only seems to work for OBA accounts
|
|
198
|
+
to limit the countries.
|
|
104
199
|
"""
|
|
105
200
|
countries = get_all_country_codes()
|
|
106
201
|
result = self.test_shipping(
|
|
@@ -129,6 +224,10 @@ class AbstractClickAndDrop(ABC):
|
|
|
129
224
|
|
|
130
225
|
Returns:
|
|
131
226
|
:class:`ShippingTestResult` with ``success=True/False`` and a message.
|
|
227
|
+
|
|
228
|
+
Note:
|
|
229
|
+
This method only seems to work for OBA accounts
|
|
230
|
+
to limit the countries.
|
|
132
231
|
"""
|
|
133
232
|
if not isinstance(address, list):
|
|
134
233
|
address = [address]
|
|
@@ -153,35 +252,30 @@ class AbstractClickAndDrop(ABC):
|
|
|
153
252
|
failed_messages = []
|
|
154
253
|
to_delete = []
|
|
155
254
|
# we can request at max 100 orders at a time
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
f"Error {e.error_code} in "
|
|
178
|
-
f"{self.format_fields_for_error_message(e.fields)}: "
|
|
179
|
-
f"{e.error_message}"
|
|
180
|
-
for e in fo.errors
|
|
181
|
-
)
|
|
255
|
+
try:
|
|
256
|
+
response = self.create_orders(orders)
|
|
257
|
+
except ApiException as e:
|
|
258
|
+
failed_addresses += [get_order_address(order) for order in orders]
|
|
259
|
+
failed_messages += [
|
|
260
|
+
f"API error ({e.status} {e.reason}): {e.body or e.data or ''}"
|
|
261
|
+
] * len(orders)
|
|
262
|
+
except Exception as e:
|
|
263
|
+
failed_addresses += [get_order_address(order) for order in orders]
|
|
264
|
+
failed_messages += [f"Unexpected error: {e}"] * len(orders)
|
|
265
|
+
for co in response.created_orders:
|
|
266
|
+
successful_addresses.append(get_order_address(co))
|
|
267
|
+
to_delete.append(co.order_identifier)
|
|
268
|
+
for fo in response.failed_orders:
|
|
269
|
+
failed_addresses.append(get_order_address(fo.order))
|
|
270
|
+
failed_messages.append(
|
|
271
|
+
";".join(
|
|
272
|
+
f"Error {e.error_code} in "
|
|
273
|
+
f"{self.format_fields_for_error_message(e.fields)}: "
|
|
274
|
+
f"{e.error_message}"
|
|
275
|
+
for e in fo.errors
|
|
182
276
|
)
|
|
183
|
-
|
|
184
|
-
|
|
277
|
+
)
|
|
278
|
+
self.delete_orders(to_delete)
|
|
185
279
|
return ShippingTestResult(
|
|
186
280
|
successful_addresses, failed_addresses, failed_messages
|
|
187
281
|
)
|
|
@@ -50,12 +50,9 @@ class MockClickAndDrop(AbstractClickAndDrop):
|
|
|
50
50
|
release_date=datetime.now(timezone.utc),
|
|
51
51
|
)
|
|
52
52
|
|
|
53
|
-
def
|
|
54
|
-
self, orders:
|
|
53
|
+
def _create_orders(
|
|
54
|
+
self, orders: list[CreateOrder]
|
|
55
55
|
) -> click_and_drop_api.CreateOrdersResponse:
|
|
56
|
-
if not isinstance(orders, list):
|
|
57
|
-
orders = [orders]
|
|
58
|
-
|
|
59
56
|
now = datetime.now(timezone.utc)
|
|
60
57
|
created = []
|
|
61
58
|
for order in orders:
|
|
@@ -83,12 +80,9 @@ class MockClickAndDrop(AbstractClickAndDrop):
|
|
|
83
80
|
failed_orders=[],
|
|
84
81
|
)
|
|
85
82
|
|
|
86
|
-
def
|
|
87
|
-
self, order_identifiers:
|
|
83
|
+
def _get_orders(
|
|
84
|
+
self, order_identifiers: list[Union[str, int]]
|
|
88
85
|
) -> list[click_and_drop_api.GetOrderInfoResource]:
|
|
89
|
-
if not isinstance(order_identifiers, list):
|
|
90
|
-
order_identifiers = [order_identifiers]
|
|
91
|
-
|
|
92
86
|
result = []
|
|
93
87
|
for identifier in order_identifiers:
|
|
94
88
|
if isinstance(identifier, int):
|
|
@@ -102,12 +96,9 @@ class MockClickAndDrop(AbstractClickAndDrop):
|
|
|
102
96
|
break
|
|
103
97
|
return result
|
|
104
98
|
|
|
105
|
-
def
|
|
106
|
-
self, order_identifiers:
|
|
99
|
+
def _delete_orders(
|
|
100
|
+
self, order_identifiers: list[Union[str, int]]
|
|
107
101
|
) -> click_and_drop_api.DeleteOrdersResource:
|
|
108
|
-
if not isinstance(order_identifiers, list):
|
|
109
|
-
order_identifiers = [order_identifiers]
|
|
110
|
-
|
|
111
102
|
deleted = []
|
|
112
103
|
errors = []
|
|
113
104
|
for identifier in order_identifiers:
|
|
@@ -5,6 +5,8 @@ from dataclasses import dataclass
|
|
|
5
5
|
from decimal import Decimal as D
|
|
6
6
|
from typing import Literal, Optional
|
|
7
7
|
|
|
8
|
+
from click_and_drop_api.simple.addresses import get_all_country_codes
|
|
9
|
+
|
|
8
10
|
from click_and_drop_api.models.dimensions_request import DimensionsRequest
|
|
9
11
|
from click_and_drop_api.models.shipment_package_request import ShipmentPackageRequest
|
|
10
12
|
from click_and_drop_api.simple.types import PostageDetails
|
|
@@ -12,6 +14,24 @@ from click_and_drop_api.simple.errors import InvalidWeight, InvalidDimensions
|
|
|
12
14
|
|
|
13
15
|
MIN_WEIGHT_IN_GRAMS = 1
|
|
14
16
|
|
|
17
|
+
# Country codes treated as domestic (national) by Royal Mail.
|
|
18
|
+
NATIONAL_COUNTRY_CODES: frozenset[str] = frozenset({"GB", "GG", "IM", "JE"})
|
|
19
|
+
|
|
20
|
+
# Country codes excluded from international shipping options.
|
|
21
|
+
NON_INTERNATIONAL_COUNTRY_CODES: frozenset[str] = frozenset(
|
|
22
|
+
{
|
|
23
|
+
"GB",
|
|
24
|
+
"GG",
|
|
25
|
+
"IM",
|
|
26
|
+
"JE", # Royal Mail domestic
|
|
27
|
+
"GS", # South Georgia (BFPO)
|
|
28
|
+
"CC",
|
|
29
|
+
"NF", # Australia Post territories
|
|
30
|
+
"FM", # USPS territory
|
|
31
|
+
"PM", # La Poste (France)
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
15
35
|
|
|
16
36
|
@dataclass
|
|
17
37
|
class PackageShippingOption:
|
|
@@ -76,6 +96,26 @@ class PackageShippingOption:
|
|
|
76
96
|
"""Effective weight limit in kilograms."""
|
|
77
97
|
return self.max_weight_g / 1000
|
|
78
98
|
|
|
99
|
+
@property
|
|
100
|
+
def country_codes(self) -> list[str]:
|
|
101
|
+
"""Country codes this option ships to.
|
|
102
|
+
|
|
103
|
+
Returns the four national codes (GB, GG, IM, JE) for domestic services,
|
|
104
|
+
or all other known country codes for international services,
|
|
105
|
+
excluding those that Royal Mail does not serve.
|
|
106
|
+
|
|
107
|
+
If you want to get an updated list of contry codes
|
|
108
|
+
that the live API accepts, use
|
|
109
|
+
``api.get_countries_for_shipping(package_size, service_code)`` instead.
|
|
110
|
+
"""
|
|
111
|
+
if not self.international:
|
|
112
|
+
return sorted(NATIONAL_COUNTRY_CODES)
|
|
113
|
+
return [
|
|
114
|
+
c
|
|
115
|
+
for c in get_all_country_codes()
|
|
116
|
+
if c not in NON_INTERNATIONAL_COUNTRY_CODES
|
|
117
|
+
]
|
|
118
|
+
|
|
79
119
|
# ── Convenience ─────────────────────────────────────────────────────────
|
|
80
120
|
|
|
81
121
|
@property
|