diff --git a/CHANGELOG.md b/CHANGELOG.md index 00361ec..5b5b6e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next Release - Removes the deprecated `create_list` tracker endpoint function as it is no longer available via API +- Routes `AmazonShippingAccount` create/update requests to the new `/register_oauth` endpoint ## v9.4.1 (2024-08-09) diff --git a/easypost/constant.py b/easypost/constant.py index d8aca25..4c477de 100644 --- a/easypost/constant.py +++ b/easypost/constant.py @@ -36,6 +36,9 @@ "FedexAccount", "FedexSmartpostAccount", ] +_CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH = [ + "AmazonShippingAccount", +] _UPS_OAUTH_CARRIER_ACCOUNT_TYPES = [ "UpsAccount", "UpsMailInnovationsAccount", diff --git a/easypost/services/base_service.py b/easypost/services/base_service.py index b9499d0..dfd93b2 100644 --- a/easypost/services/base_service.py +++ b/easypost/services/base_service.py @@ -77,7 +77,6 @@ def _update_resource( """Update an EasyPost object via the EasyPost API.""" url = self._instance_url(class_name, id) wrapped_params = {self._snakecase_name(class_name): params} - response = Requestor(self._client).request(method=method, url=url, params=wrapped_params, beta=beta) return convert_to_easypost_object(response=response) diff --git a/easypost/services/carrier_account_service.py b/easypost/services/carrier_account_service.py index 53d3cea..a279025 100644 --- a/easypost/services/carrier_account_service.py +++ b/easypost/services/carrier_account_service.py @@ -6,6 +6,7 @@ ) from easypost.constant import ( + _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH, _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_WORKFLOWS, _UPS_OAUTH_CARRIER_ACCOUNT_TYPES, MISSING_PARAMETER_ERROR, @@ -35,6 +36,8 @@ def create(self, **params) -> CarrierAccount: url = self._select_carrier_account_creation_endpoint(carrier_account_type=carrier_account_type) if carrier_account_type in _UPS_OAUTH_CARRIER_ACCOUNT_TYPES: wrapped_params = {"ups_oauth_registrations": params} + elif carrier_account_type in _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH: + wrapped_params = {"carrier_account_oauth_registrations": params} else: wrapped_params = {self._snakecase_name(self._model_class): params} @@ -56,6 +59,13 @@ def update(self, id: str, **params) -> CarrierAccount: if carrier_account.get("type") in _UPS_OAUTH_CARRIER_ACCOUNT_TYPES: class_name = "UpsOauthRegistrations" + elif carrier_account.get("type") in _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH: + response = Requestor(self._client).request( + method=RequestMethod.PATCH, + url=f"/carrier_accounts/register_oauth/{id}", + params={}, + ) + return convert_to_easypost_object(response=response) else: class_name = self._model_class @@ -77,5 +87,7 @@ def _select_carrier_account_creation_endpoint(self, carrier_account_type: Option return "/carrier_accounts/register" elif carrier_account_type in _UPS_OAUTH_CARRIER_ACCOUNT_TYPES: return "/ups_oauth_registrations" + elif carrier_account_type in _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH: + return "/carrier_accounts/register_oauth" return "/carrier_accounts" diff --git a/tests/cassettes/test_carrier_account_create_amazon_shipping.yaml b/tests/cassettes/test_carrier_account_create_amazon_shipping.yaml new file mode 100644 index 0000000..3a3ca1e --- /dev/null +++ b/tests/cassettes/test_carrier_account_create_amazon_shipping.yaml @@ -0,0 +1,137 @@ +interactions: +- request: + body: '{"carrier_account_oauth_registrations": {"type": "AmazonShippingAccount", + "selling_partner_id": 123456, "description": "Test Amazon Shipping Account", + "reference": "Test reference id"}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '185' + Content-Type: + - application/json + authorization: + - + user-agent: + - + method: POST + uri: https://api.easypost.com/v2/carrier_accounts/register_oauth + response: + body: + string: '{"id": "ca_42645bd4efec44d19990311923247889", "object": "CarrierAccount", + "type": "AmazonShippingAccount", "clone": false, "created_at": "2024-10-21T17:29:15Z", + "updated_at": "2024-10-21T17:29:15Z", "description": "Test Amazon Shipping + Account", "reference": "Test reference id", "billing_type": "carrier", "readable": + "Amazon Shipping", "logo": null, "fields": [], "credentials": {}, "test_credentials": + {}}' + headers: + cache-control: + - private, no-cache, no-store + content-length: + - '1477' + content-type: + - application/json; charset=utf-8 + expires: + - '0' + pragma: + - no-cache + referrer-policy: + - strict-origin-when-cross-origin + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-backend: + - easypost + x-content-type-options: + - nosniff + x-download-options: + - noopen + x-ep-request-uuid: + - 5b98ae6c67168f6be786a35a006ad145 + x-frame-options: + - SAMEORIGIN + x-node: + - bigweb36nuq + x-permitted-cross-domain-policies: + - none + x-proxied: + - intlb4nuq b6e1b5034c + - extlb1nuq 99aac35317 + x-runtime: + - '0.111175' + x-version-label: + - easypost-202410211500-2da9256a8e-master + x-xss-protection: + - 1; mode=block + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + authorization: + - + user-agent: + - + method: DELETE + uri: https://api.easypost.com/v2/carrier_accounts/ca_42645bd4efec44d19990311923247889 + response: + body: + string: '{}' + headers: + cache-control: + - private, no-cache, no-store + content-length: + - '2' + content-type: + - application/json; charset=utf-8 + expires: + - '0' + pragma: + - no-cache + referrer-policy: + - strict-origin-when-cross-origin + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-backend: + - easypost + x-content-type-options: + - nosniff + x-download-options: + - noopen + x-ep-request-uuid: + - 5b98ae6c67168f6be786a35a006ad17a + x-frame-options: + - SAMEORIGIN + x-node: + - bigweb36nuq + x-permitted-cross-domain-policies: + - none + x-proxied: + - intlb3nuq b6e1b5034c + - extlb1nuq 99aac35317 + x-runtime: + - '0.061416' + x-version-label: + - easypost-202410211500-2da9256a8e-master + x-xss-protection: + - 1; mode=block + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_carrier_account_update_amazon_shipping.yaml b/tests/cassettes/test_carrier_account_update_amazon_shipping.yaml new file mode 100644 index 0000000..60d54ae --- /dev/null +++ b/tests/cassettes/test_carrier_account_update_amazon_shipping.yaml @@ -0,0 +1,268 @@ +interactions: +- request: + body: '{"carrier_account_oauth_registrations": {"type": "AmazonShippingAccount"}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '74' + Content-Type: + - application/json + authorization: + - + user-agent: + - + method: POST + uri: https://api.easypost.com/v2/carrier_accounts/register_oauth + response: + body: + string: '{"id": "ca_102f186f791648b692501b0c6b8971a4", "object": "CarrierAccount", + "type": "AmazonShippingAccount", "clone": false, "created_at": "2024-10-21T21:55:03Z", + "updated_at": "2024-10-21T21:55:03Z", "description": null, "reference": null, + "billing_type": "carrier", "readable": "Amazon Shipping", "logo": null, "fields": + [], "credentials": {}, "test_credentials": {}}' + headers: + cache-control: + - private, no-cache, no-store + content-length: + - '1432' + content-type: + - application/json; charset=utf-8 + expires: + - '0' + pragma: + - no-cache + referrer-policy: + - strict-origin-when-cross-origin + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-backend: + - easypost + x-content-type-options: + - nosniff + x-download-options: + - noopen + x-ep-request-uuid: + - 6c7e76b86716cdb7e7874d4300480c14 + x-frame-options: + - SAMEORIGIN + x-node: + - bigweb42nuq + x-permitted-cross-domain-policies: + - none + x-proxied: + - intlb4nuq b6e1b5034c + - extlb2nuq 99aac35317 + x-runtime: + - '0.080434' + x-version-label: + - easypost-202410212124-540267707a-master + x-xss-protection: + - 1; mode=block + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + authorization: + - + user-agent: + - + method: GET + uri: https://api.easypost.com/v2/carrier_accounts/ca_102f186f791648b692501b0c6b8971a4 + response: + body: + string: '{"id": "ca_102f186f791648b692501b0c6b8971a4", "object": "CarrierAccount", + "type": "AmazonShippingAccount", "clone": false, "created_at": "2024-10-21T21:55:03Z", + "updated_at": "2024-10-21T21:55:03Z", "description": null, "reference": null, + "billing_type": "carrier", "readable": "Amazon Shipping", "logo": null, "fields": + [], "credentials": {}, "test_credentials": {}}' + headers: + cache-control: + - private, no-cache, no-store + content-length: + - '1432' + content-type: + - application/json; charset=utf-8 + expires: + - '0' + pragma: + - no-cache + referrer-policy: + - strict-origin-when-cross-origin + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-backend: + - easypost + x-content-type-options: + - nosniff + x-download-options: + - noopen + x-ep-request-uuid: + - 6c7e76b86716cdbce7874d430048118f + x-frame-options: + - SAMEORIGIN + x-node: + - bigweb42nuq + x-permitted-cross-domain-policies: + - none + x-proxied: + - intlb4nuq b6e1b5034c + - extlb2nuq 99aac35317 + x-runtime: + - '0.033679' + x-version-label: + - easypost-202410212124-540267707a-master + x-xss-protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: '{}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2' + Content-Type: + - application/json + authorization: + - + user-agent: + - + method: PATCH + uri: https://api.easypost.com/v2/carrier_accounts/register_oauth/ca_102f186f791648b692501b0c6b8971a4 + response: + body: + string: '{"id": "ca_102f186f791648b692501b0c6b8971a4", "object": "CarrierAccount", + "type": "AmazonShippingAccount", "clone": false, "created_at": "2024-10-21T21:55:03Z", + "updated_at": "2024-10-21T21:55:08Z", "description": null, "reference": null, + "billing_type": "carrier", "readable": "Amazon Shipping", "logo": null, "fields": + [], "credentials": {}, "test_credentials": {}}' + headers: + cache-control: + - private, no-cache, no-store + content-length: + - '1440' + content-type: + - application/json; charset=utf-8 + expires: + - '0' + pragma: + - no-cache + referrer-policy: + - strict-origin-when-cross-origin + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-backend: + - easypost + x-content-type-options: + - nosniff + x-download-options: + - noopen + x-ep-request-uuid: + - 6c7e76b86716cdbce7874d43004811bd + x-frame-options: + - SAMEORIGIN + x-node: + - bigweb36nuq + x-permitted-cross-domain-policies: + - none + x-proxied: + - intlb4nuq b6e1b5034c + - extlb2nuq 99aac35317 + x-runtime: + - '0.066719' + x-version-label: + - easypost-202410212124-540267707a-master + x-xss-protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + authorization: + - + user-agent: + - + method: DELETE + uri: https://api.easypost.com/v2/carrier_accounts/ca_102f186f791648b692501b0c6b8971a4 + response: + body: + string: '{}' + headers: + cache-control: + - private, no-cache, no-store + content-length: + - '2' + content-type: + - application/json; charset=utf-8 + expires: + - '0' + pragma: + - no-cache + referrer-policy: + - strict-origin-when-cross-origin + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-backend: + - easypost + x-content-type-options: + - nosniff + x-download-options: + - noopen + x-ep-request-uuid: + - 6c7e76b86716cdbde7874d4300481200 + x-frame-options: + - SAMEORIGIN + x-node: + - bigweb53nuq + x-permitted-cross-domain-policies: + - none + x-proxied: + - intlb3nuq b6e1b5034c + - extlb2nuq 99aac35317 + x-runtime: + - '0.063692' + x-version-label: + - easypost-202410212124-540267707a-master + x-xss-protection: + - 1; mode=block + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_carrier_account.py b/tests/test_carrier_account.py index 72e1a69..f70db90 100644 --- a/tests/test_carrier_account.py +++ b/tests/test_carrier_account.py @@ -1,3 +1,7 @@ +import inspect +import os +import time + import pytest from easypost.errors.api.api_error import ApiError from easypost.models import CarrierAccount @@ -131,3 +135,44 @@ def test_carrier_account_update_ups(prod_client): prod_client.carrier_account.delete( updated_carrier_account.id ) # Delete the carrier account once it's done being tested. + + +@pytest.mark.vcr() +def test_carrier_account_create_amazon_shipping(prod_client): + """Test registering an Amazon Shipping Carrier Account which uses a different URL and schema.""" + params = { + "type": "AmazonShippingAccount", + "selling_partner_id": 123456, + "description": "Test Amazon Shipping Account", + "reference": "Test reference id", + } + + carrier_account = prod_client.carrier_account.create(**params) + + assert isinstance(carrier_account, CarrierAccount) + assert str.startswith(carrier_account.id, "ca_") + assert carrier_account.type == "AmazonShippingAccount" + + prod_client.carrier_account.delete(carrier_account.id) # Delete the carrier account once it's done being tested. + + +@pytest.mark.vcr() +def test_carrier_account_update_amazon_shipping(prod_client, synchronous_sleep_seconds): + """Test updating an Amazon Shipping Carrier Account which uses a different URL and schema.""" + function_name = inspect.stack()[0][3] + params = { + "type": "AmazonShippingAccount", + } + + amazon_shipping_account = prod_client.carrier_account.create(**params) + if not os.path.exists(os.path.join("tests", "cassettes", f"{function_name}.yaml")): + time.sleep(synchronous_sleep_seconds) # Wait enough time for updating the carrier account + updated_amazon_shipping_account = prod_client.carrier_account.update(amazon_shipping_account.id) + + assert isinstance(updated_amazon_shipping_account, CarrierAccount) + assert str.startswith(updated_amazon_shipping_account.id, "ca_") + assert amazon_shipping_account.updated_at != updated_amazon_shipping_account.updated_at + + prod_client.carrier_account.delete( + amazon_shipping_account.id + ) # Delete the carrier account once it's done being tested.