From 11eabea46a5e76489cd628039ec5bd4e5b833aed Mon Sep 17 00:00:00 2001 From: Justintime50 <39606064+Justintime50@users.noreply.github.com> Date: Fri, 23 May 2025 13:17:19 -0600 Subject: [PATCH 1/2] fix: endpoint used for UPS create/update --- CHANGELOG.md | 4 + easypost/constant.py | 29 ++-- easypost/services/base_service.py | 5 +- easypost/services/carrier_account_service.py | 16 +-- setup.py | 3 +- .../test_carrier_account_create_ups.yaml | 37 +++--- .../test_carrier_account_update_ups.yaml | 124 +++++------------- tests/test_billing.py | 2 +- 8 files changed, 77 insertions(+), 143 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15990011..f5ea0517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v10.0.1 (2025-05-27) + +- Corrects the endpoint used for creating/updating UPS accounts + ## v10.0.0 (2025-04-28) See our [Upgrade Guide](UPGRADE_GUIDE.md#upgrading-from-9x-to-100) for more details. diff --git a/easypost/constant.py b/easypost/constant.py index 9604d2bf..a45f2b17 100644 --- a/easypost/constant.py +++ b/easypost/constant.py @@ -1,6 +1,6 @@ # flake8: noqa # Library version -VERSION = "10.0.0" +VERSION = "10.0.1" VERSION_INFO = [str(number) for number in VERSION.split(".")] # Client defaults @@ -13,21 +13,33 @@ # Error messages COMMUNICATION_ERROR = "Unexpected error communicating with EasyPost. If this problem persists please let us know at {}. Original error: {}" INVALID_DELIVER_ACCURACY_ERROR = "Invalid delivery_accuracy value, must be one of: {}" -INVALID_PAYMENT_METHOD_ERROR = "The chosen payment method is not valid. Please try again." -INVALID_REQUEST_LIB_ERROR = "Bug discovered: invalid request_lib: {}. Please report to {}." -INVALID_REQUEST_METHOD_ERROR = "Bug discovered: invalid request method: {}. Please report to {}." +INVALID_PAYMENT_METHOD_ERROR = ( + "The chosen payment method is not valid. Please try again." +) +INVALID_REQUEST_LIB_ERROR = ( + "Bug discovered: invalid request_lib: {}. Please report to {}." +) +INVALID_REQUEST_METHOD_ERROR = ( + "Bug discovered: invalid request method: {}. Please report to {}." +) INVALID_REQUEST_PARAMETERS_ERROR = "Only GET and DELETE requests support parameters." INVALID_REQUESTS_VERSION_ERROR = 'EasyPost requires an up to date requests library. Update requests via "pip install -U requests" or contact us at {}.' INVALID_RESPONSE_BODY_ERROR = "Invalid response from API: ({}) {}" INVALID_SIGNATURE_ERROR = "Webhook received does not contain an HMAC signature." -INVALID_WEBHOOK_VALIDATION_ERROR = "Webhook received did not originate from EasyPost or had a webhook secret mismatch." +INVALID_WEBHOOK_VALIDATION_ERROR = ( + "Webhook received did not originate from EasyPost or had a webhook secret mismatch." +) MISSING_PARAMETER_ERROR = "Missing required parameter: {}" NO_ATTRIBUTE_ERROR = "{} object has no attribute {}" -NO_BILLING_ERROR = "Billing has not been setup for this user. Please add a payment method." +NO_BILLING_ERROR = ( + "Billing has not been setup for this user. Please add a payment method." +) NO_MORE_PAGES_ERROR = "There are no more pages to retrieve." NO_RATES_ERROR = "No rates found." NO_USER_FOUND = "No user found with the given id." -SEND_STRIPE_DETAILS_ERROR = "Could not send card details to Stripe, please try again later." +SEND_STRIPE_DETAILS_ERROR = ( + "Could not send card details to Stripe, please try again later." +) TIMEOUT_ERROR = "Request timed out." # Internal constants (user's should not use these) @@ -38,11 +50,8 @@ ] _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH = [ "AmazonShippingAccount", -] -_UPS_OAUTH_CARRIER_ACCOUNT_TYPES = [ "UpsAccount", "UpsMailInnovationsAccount", "UpsSurepostAccount", ] _FILTERS_KEY = "filters" -_EXCLUDED_CLASS_NAMES = ["ups_oauth_registrations"] diff --git a/easypost/services/base_service.py b/easypost/services/base_service.py index cb6b5d76..7dc643e0 100644 --- a/easypost/services/base_service.py +++ b/easypost/services/base_service.py @@ -5,7 +5,6 @@ ) from easypost.constant import ( - _EXCLUDED_CLASS_NAMES, _FILTERS_KEY, NO_MORE_PAGES_ERROR, ) @@ -30,9 +29,7 @@ def _snakecase_name(self, class_name: str) -> str: def _class_url(self, class_name: str) -> str: """Generate a URL based on class name.""" transformed_class_name = self._snakecase_name(class_name) - if transformed_class_name in _EXCLUDED_CLASS_NAMES: - return f"/{transformed_class_name}" - elif transformed_class_name[-1:] in ("s", "h"): + if transformed_class_name[-1:] in ("s", "h"): return f"/{transformed_class_name}es" else: return f"/{transformed_class_name}s" diff --git a/easypost/services/carrier_account_service.py b/easypost/services/carrier_account_service.py index 5708b35c..63b16f77 100644 --- a/easypost/services/carrier_account_service.py +++ b/easypost/services/carrier_account_service.py @@ -6,7 +6,6 @@ from easypost.constant import ( _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH, _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_WORKFLOWS, - _UPS_OAUTH_CARRIER_ACCOUNT_TYPES, MISSING_PARAMETER_ERROR, ) from easypost.easypost_object import convert_to_easypost_object @@ -32,9 +31,7 @@ def create(self, **params) -> CarrierAccount: raise MissingParameterError(MISSING_PARAMETER_ERROR.format("type")) 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: + if 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} @@ -53,14 +50,7 @@ def retrieve(self, id: str) -> CarrierAccount: def update(self, id: str, **params) -> CarrierAccount: """Update a CarrierAccount.""" - carrier_account = self.retrieve(id) - - if carrier_account.get("type") in _UPS_OAUTH_CARRIER_ACCOUNT_TYPES: - class_name = "UpsOauthRegistrations" - else: - class_name = self._model_class - - return self._update_resource(class_name, id, **params) + return self._update_resource(self._model_class, id, **params) def delete(self, id: str) -> None: """Delete a CarrierAccount.""" @@ -76,8 +66,6 @@ def _select_carrier_account_creation_endpoint(self, carrier_account_type: Option """Determines which API endpoint to use for the creation call.""" if carrier_account_type in _CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_WORKFLOWS: 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" diff --git a/setup.py b/setup.py index 37687afe..4b9d0132 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,6 @@ setup, ) - REQUIREMENTS = [ "requests >= 2.4.3", ] @@ -27,7 +26,7 @@ setup( name="easypost", - version="10.0.0", + version="10.0.1", description="EasyPost Shipping API Client Library for Python", author="EasyPost", author_email="support@easypost.com", diff --git a/tests/cassettes/test_carrier_account_create_ups.yaml b/tests/cassettes/test_carrier_account_create_ups.yaml index 978a3d6c..0a5daabc 100644 --- a/tests/cassettes/test_carrier_account_create_ups.yaml +++ b/tests/cassettes/test_carrier_account_create_ups.yaml @@ -1,6 +1,7 @@ interactions: - request: - body: '{"ups_oauth_registrations": {"type": "UpsAccount", "account_number": "123456789"}}' + body: '{"carrier_account_oauth_registrations": {"type": "UpsAccount", "account_number": + "123456789"}}' headers: Accept: - '*/*' @@ -9,7 +10,7 @@ interactions: Connection: - keep-alive Content-Length: - - '82' + - '94' Content-Type: - application/json authorization: @@ -17,19 +18,19 @@ interactions: user-agent: - method: POST - uri: https://api.easypost.com/v2/ups_oauth_registrations + uri: https://api.easypost.com/v2/carrier_accounts/register_oauth response: body: - string: '{"id": "ca_47c106e98d8442018f3712e8e1e9bf32", "object": "CarrierAccount", - "type": "UpsAccount", "clone": false, "created_at": "2025-03-06T19:47:55Z", - "updated_at": "2025-03-06T19:47:55Z", "description": null, "reference": null, + string: '{"id": "ca_b42eeb389ad6481698e3aff5002502c3", "object": "CarrierAccount", + "type": "UpsAccount", "clone": false, "created_at": "2025-05-23T19:13:53Z", + "updated_at": "2025-05-23T19:13:53Z", "description": null, "reference": null, "billing_type": "carrier", "readable": "UPS", "logo": null, "fields": [], "credentials": {}, "test_credentials": {}}' headers: cache-control: - private, no-cache, no-store content-length: - - '1412' + - '1416' content-type: - application/json; charset=utf-8 expires: @@ -49,20 +50,20 @@ interactions: x-download-options: - noopen x-ep-request-uuid: - - 8e8eb62967c9fbebe2b97a8f001871de + - 6be4a8f16830c8f1e787301c003e936f x-frame-options: - SAMEORIGIN x-node: - - bigweb55nuq + - bigweb59nuq x-permitted-cross-domain-policies: - none x-proxied: - - intlb4nuq 51d74985a2 + - intlb4nuq 668d3fc830 - extlb1nuq 99aac35317 x-runtime: - - '0.077926' + - '0.104749' x-version-label: - - easypost-202503061913-8f39069a2d-master + - easypost-202505231841-d89645a184-master x-xss-protection: - 1; mode=block status: @@ -84,7 +85,7 @@ interactions: user-agent: - method: DELETE - uri: https://api.easypost.com/v2/carrier_accounts/ca_47c106e98d8442018f3712e8e1e9bf32 + uri: https://api.easypost.com/v2/carrier_accounts/ca_b42eeb389ad6481698e3aff5002502c3 response: body: string: '{}' @@ -112,20 +113,20 @@ interactions: x-download-options: - noopen x-ep-request-uuid: - - 8e8eb62967c9fbebe2b97a8f001871fe + - 6be4a8f16830c8f1e787301c003e9394 x-frame-options: - SAMEORIGIN x-node: - - bigweb38nuq + - bigweb41nuq x-permitted-cross-domain-policies: - none x-proxied: - - intlb4nuq 51d74985a2 + - intlb3nuq 668d3fc830 - extlb1nuq 99aac35317 x-runtime: - - '0.067735' + - '0.065988' x-version-label: - - easypost-202503061913-8f39069a2d-master + - easypost-202505231841-d89645a184-master x-xss-protection: - 1; mode=block status: diff --git a/tests/cassettes/test_carrier_account_update_ups.yaml b/tests/cassettes/test_carrier_account_update_ups.yaml index f113ef40..1cd438e2 100644 --- a/tests/cassettes/test_carrier_account_update_ups.yaml +++ b/tests/cassettes/test_carrier_account_update_ups.yaml @@ -1,6 +1,7 @@ interactions: - request: - body: '{"ups_oauth_registrations": {"type": "UpsAccount", "account_number": "123456789"}}' + body: '{"carrier_account_oauth_registrations": {"type": "UpsAccount", "account_number": + "123456789"}}' headers: Accept: - '*/*' @@ -9,7 +10,7 @@ interactions: Connection: - keep-alive Content-Length: - - '82' + - '94' Content-Type: - application/json authorization: @@ -17,19 +18,19 @@ interactions: user-agent: - method: POST - uri: https://api.easypost.com/v2/ups_oauth_registrations + uri: https://api.easypost.com/v2/carrier_accounts/register_oauth response: body: - string: '{"id": "ca_56b369117cb24365bab1014b845793d3", "object": "CarrierAccount", - "type": "UpsAccount", "clone": false, "created_at": "2025-03-06T19:47:55Z", - "updated_at": "2025-03-06T19:47:55Z", "description": null, "reference": null, + string: '{"id": "ca_6e690e7623ba4354b29d209fc19a725f", "object": "CarrierAccount", + "type": "UpsAccount", "clone": false, "created_at": "2025-05-23T19:13:53Z", + "updated_at": "2025-05-23T19:13:53Z", "description": null, "reference": null, "billing_type": "carrier", "readable": "UPS", "logo": null, "fields": [], "credentials": {}, "test_credentials": {}}' headers: cache-control: - private, no-cache, no-store content-length: - - '1384' + - '1404' content-type: - application/json; charset=utf-8 expires: @@ -49,7 +50,7 @@ interactions: x-download-options: - noopen x-ep-request-uuid: - - 8e8eb62a67c9fbebe2b97a900018723c + - 6be4a8f66830c8f1e787301d003e93e1 x-frame-options: - SAMEORIGIN x-node: @@ -57,84 +58,19 @@ interactions: x-permitted-cross-domain-policies: - none x-proxied: - - intlb3nuq 51d74985a2 + - intlb4nuq 668d3fc830 - extlb1nuq 99aac35317 x-runtime: - - '0.075599' + - '0.097712' x-version-label: - - easypost-202503061913-8f39069a2d-master + - easypost-202505231841-d89645a184-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_56b369117cb24365bab1014b845793d3 - response: - body: - string: '{"id": "ca_56b369117cb24365bab1014b845793d3", "object": "CarrierAccount", - "type": "UpsAccount", "clone": false, "created_at": "2025-03-06T19:47:55Z", - "updated_at": "2025-03-06T19:47:55Z", "description": null, "reference": null, - "billing_type": "carrier", "readable": "UPS", "logo": null, "fields": [], - "credentials": {}, "test_credentials": {}}' - headers: - cache-control: - - private, no-cache, no-store - content-length: - - '1384' - 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: - - 8e8eb62a67c9fbebe2b97a900018726a - x-frame-options: - - SAMEORIGIN - x-node: - - bigweb55nuq - x-permitted-cross-domain-policies: - - none - x-proxied: - - intlb3nuq 51d74985a2 - - extlb1nuq 99aac35317 - x-runtime: - - '0.181601' - x-version-label: - - easypost-202503061913-8f39069a2d-master - x-xss-protection: - - 1; mode=block - status: - code: 200 - message: OK -- request: - body: '{"ups_oauth_registrations": {"account_number": "987654321"}}' + body: '{"carrier_account": {"account_number": "987654321"}}' headers: Accept: - '*/*' @@ -143,7 +79,7 @@ interactions: Connection: - keep-alive Content-Length: - - '60' + - '52' Content-Type: - application/json authorization: @@ -151,19 +87,19 @@ interactions: user-agent: - method: PATCH - uri: https://api.easypost.com/v2/ups_oauth_registrations/ca_56b369117cb24365bab1014b845793d3 + uri: https://api.easypost.com/v2/carrier_accounts/ca_6e690e7623ba4354b29d209fc19a725f response: body: - string: '{"id": "ca_56b369117cb24365bab1014b845793d3", "object": "CarrierAccount", - "type": "UpsAccount", "clone": false, "created_at": "2025-03-06T19:47:55Z", - "updated_at": "2025-03-06T19:47:56Z", "description": null, "reference": null, + string: '{"id": "ca_6e690e7623ba4354b29d209fc19a725f", "object": "CarrierAccount", + "type": "UpsAccount", "clone": false, "created_at": "2025-05-23T19:13:53Z", + "updated_at": "2025-05-23T19:13:54Z", "description": null, "reference": null, "billing_type": "carrier", "readable": "UPS", "logo": null, "fields": [], "credentials": {}, "test_credentials": {}}' headers: cache-control: - private, no-cache, no-store content-length: - - '1388' + - '1404' content-type: - application/json; charset=utf-8 expires: @@ -183,20 +119,20 @@ interactions: x-download-options: - noopen x-ep-request-uuid: - - 8e8eb62a67c9fbece2b97a90001872b1 + - 6be4a8f66830c8f1e787301d003e9403 x-frame-options: - SAMEORIGIN x-node: - - bigweb54nuq + - bigweb53nuq x-permitted-cross-domain-policies: - none x-proxied: - - intlb3nuq 51d74985a2 + - intlb4nuq 668d3fc830 - extlb1nuq 99aac35317 x-runtime: - - '0.064679' + - '0.073912' x-version-label: - - easypost-202503061913-8f39069a2d-master + - easypost-202505231841-d89645a184-master x-xss-protection: - 1; mode=block status: @@ -218,7 +154,7 @@ interactions: user-agent: - method: DELETE - uri: https://api.easypost.com/v2/carrier_accounts/ca_56b369117cb24365bab1014b845793d3 + uri: https://api.easypost.com/v2/carrier_accounts/ca_6e690e7623ba4354b29d209fc19a725f response: body: string: '{}' @@ -246,20 +182,20 @@ interactions: x-download-options: - noopen x-ep-request-uuid: - - 8e8eb62a67c9fbece2b97a90001872d2 + - 6be4a8f66830c8f2e787301d003e941e x-frame-options: - SAMEORIGIN x-node: - - bigweb41nuq + - bigweb38nuq x-permitted-cross-domain-policies: - none x-proxied: - - intlb3nuq 51d74985a2 + - intlb4nuq 668d3fc830 - extlb1nuq 99aac35317 x-runtime: - - '0.070166' + - '0.067810' x-version-label: - - easypost-202503061913-8f39069a2d-master + - easypost-202505231841-d89645a184-master x-xss-protection: - 1; mode=block status: diff --git a/tests/test_billing.py b/tests/test_billing.py index 578f14d4..fa6adcd2 100644 --- a/tests/test_billing.py +++ b/tests/test_billing.py @@ -117,7 +117,7 @@ def test_billing_retrieve_payment_methods_no_billing_setup(mock_request, prod_cl "secondary_payment_method": {"id": "pm_456", "object": "BankAccount"}, }, ) -def test_billing__get_payment_method_info_by_object_type(mock_request, prod_client, billing): +def test_billing_get_payment_method_info_by_object_type(mock_request, prod_client, billing): """Tests we can determine the payment method type/endpoint by object type.""" endpoint, payment_method_id = prod_client.billing._get_payment_method_info( priority=billing["priority"], From cd3d914665e1d6381ed528bc7dbaaee5aeb0895a Mon Sep 17 00:00:00 2001 From: Justintime50 <39606064+Justintime50@users.noreply.github.com> Date: Fri, 23 May 2025 13:19:12 -0600 Subject: [PATCH 2/2] fix: formatting --- easypost/constant.py | 24 ++++++------------------ setup.py | 1 + 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/easypost/constant.py b/easypost/constant.py index a45f2b17..8fc2eb34 100644 --- a/easypost/constant.py +++ b/easypost/constant.py @@ -13,33 +13,21 @@ # Error messages COMMUNICATION_ERROR = "Unexpected error communicating with EasyPost. If this problem persists please let us know at {}. Original error: {}" INVALID_DELIVER_ACCURACY_ERROR = "Invalid delivery_accuracy value, must be one of: {}" -INVALID_PAYMENT_METHOD_ERROR = ( - "The chosen payment method is not valid. Please try again." -) -INVALID_REQUEST_LIB_ERROR = ( - "Bug discovered: invalid request_lib: {}. Please report to {}." -) -INVALID_REQUEST_METHOD_ERROR = ( - "Bug discovered: invalid request method: {}. Please report to {}." -) +INVALID_PAYMENT_METHOD_ERROR = "The chosen payment method is not valid. Please try again." +INVALID_REQUEST_LIB_ERROR = "Bug discovered: invalid request_lib: {}. Please report to {}." +INVALID_REQUEST_METHOD_ERROR = "Bug discovered: invalid request method: {}. Please report to {}." INVALID_REQUEST_PARAMETERS_ERROR = "Only GET and DELETE requests support parameters." INVALID_REQUESTS_VERSION_ERROR = 'EasyPost requires an up to date requests library. Update requests via "pip install -U requests" or contact us at {}.' INVALID_RESPONSE_BODY_ERROR = "Invalid response from API: ({}) {}" INVALID_SIGNATURE_ERROR = "Webhook received does not contain an HMAC signature." -INVALID_WEBHOOK_VALIDATION_ERROR = ( - "Webhook received did not originate from EasyPost or had a webhook secret mismatch." -) +INVALID_WEBHOOK_VALIDATION_ERROR = "Webhook received did not originate from EasyPost or had a webhook secret mismatch." MISSING_PARAMETER_ERROR = "Missing required parameter: {}" NO_ATTRIBUTE_ERROR = "{} object has no attribute {}" -NO_BILLING_ERROR = ( - "Billing has not been setup for this user. Please add a payment method." -) +NO_BILLING_ERROR = "Billing has not been setup for this user. Please add a payment method." NO_MORE_PAGES_ERROR = "There are no more pages to retrieve." NO_RATES_ERROR = "No rates found." NO_USER_FOUND = "No user found with the given id." -SEND_STRIPE_DETAILS_ERROR = ( - "Could not send card details to Stripe, please try again later." -) +SEND_STRIPE_DETAILS_ERROR = "Could not send card details to Stripe, please try again later." TIMEOUT_ERROR = "Request timed out." # Internal constants (user's should not use these) diff --git a/setup.py b/setup.py index 4b9d0132..016e9508 100644 --- a/setup.py +++ b/setup.py @@ -3,6 +3,7 @@ setup, ) + REQUIREMENTS = [ "requests >= 2.4.3", ]