Skip to content

[feat] Add claims API service #342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## Next Release

- Adds new `Claim` service for filing claims on EasyPost shipments and insurances

## v9.3.0 (2024-07-12)

- Adds new `shipment.recommend_ship_date`, `smartrate.recommend_ship_date`, and `smartrate.estimate_delivery_date` functions
Expand Down
2 changes: 2 additions & 0 deletions easypost/easypost_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
BillingService,
CarrierAccountService,
CarrierMetadataService,
ClaimService,
CustomsInfoService,
CustomsItemService,
EndShipperService,
Expand Down Expand Up @@ -62,6 +63,7 @@ def __init__(
self.billing = BillingService(self)
self.carrier_account = CarrierAccountService(self)
self.carrier_metadata = CarrierMetadataService(self)
self.claim = ClaimService(self)
self.customs_info = CustomsInfoService(self)
self.customs_item = CustomsItemService(self)
self.end_shipper = EndShipperService(self)
Expand Down
1 change: 1 addition & 0 deletions easypost/easypost_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"brd": "Brand",
"ca": "CarrierAccount",
"cfrep": "Report",
"clm": "Claim",
"cstinfo": "CustomsInfo",
"cstitem": "CustomsItem",
"es": "EndShipper",
Expand Down
1 change: 1 addition & 0 deletions easypost/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from easypost.models.billing import Billing
from easypost.models.brand import Brand
from easypost.models.carrier_account import CarrierAccount
from easypost.models.claim import Claim
from easypost.models.customs_info import CustomsInfo
from easypost.models.customs_item import CustomsItem
from easypost.models.end_shipper import EndShipper
Expand Down
5 changes: 5 additions & 0 deletions easypost/models/claim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from easypost.easypost_object import EasyPostObject


class Claim(EasyPostObject):
pass
1 change: 1 addition & 0 deletions easypost/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from easypost.services.billing_service import BillingService
from easypost.services.carrier_account_service import CarrierAccountService
from easypost.services.carrier_metadata_service import CarrierMetadataService
from easypost.services.claim_service import ClaimService
from easypost.services.customs_info_service import CustomsInfoService
from easypost.services.customs_item_service import CustomsItemService
from easypost.services.end_shipper_service import EndShipperService
Expand Down
24 changes: 14 additions & 10 deletions easypost/services/base_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,47 +42,51 @@ def _instance_url(self, class_name: str, id: str) -> str:
"""Generate an instance URL based on a class name and ID."""
return f"{self._class_url(class_name)}/{id}"

def _create_resource(self, class_name: str, **params) -> Any:
def _create_resource(self, class_name: str, beta: bool = False, **params) -> Any:
"""Create an EasyPost object via the EasyPost API."""
url = self._class_url(class_name)
wrapped_params = {self._snakecase_name(class_name): params}

response = Requestor(self._client).request(method=RequestMethod.POST, url=url, params=wrapped_params)
response = Requestor(self._client).request(method=RequestMethod.POST, url=url, params=wrapped_params, beta=beta)

return convert_to_easypost_object(response=response)

def _all_resources(self, class_name: str, filters: Optional[Dict[str, Any]] = None, **params) -> Any:
def _all_resources(
self, class_name: str, filters: Optional[Dict[str, Any]] = None, beta: bool = False, **params
) -> Any:
"""Retrieve a list of EasyPostObjects from the EasyPost API."""
url = self._class_url(class_name)
response = Requestor(self._client).request(method=RequestMethod.GET, url=url, params=params)
response = Requestor(self._client).request(method=RequestMethod.GET, url=url, params=params, beta=beta)

if filters: # presence of filters indicates we are dealing with a paginated response
response[_FILTERS_KEY] = filters # Save the filters used to reference in potential get_next_page call

return convert_to_easypost_object(response=response)

def _retrieve_resource(self, class_name: str, id: str) -> Any:
def _retrieve_resource(self, class_name: str, id: str, beta: bool = False) -> Any:
"""Retrieve an object from the EasyPost API."""
url = self._instance_url(class_name, id)

response = Requestor(self._client).request(method=RequestMethod.GET, url=url)
response = Requestor(self._client).request(method=RequestMethod.GET, url=url, beta=beta)

return convert_to_easypost_object(response=response)

def _update_resource(self, class_name: str, id: str, method: RequestMethod = RequestMethod.PATCH, **params) -> Any:
def _update_resource(
self, class_name: str, id: str, method: RequestMethod = RequestMethod.PATCH, beta: bool = False, **params
) -> Any:
"""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)
response = Requestor(self._client).request(method=method, url=url, params=wrapped_params, beta=beta)

return convert_to_easypost_object(response=response)

def _delete_resource(self, class_name: str, id: str) -> Any:
def _delete_resource(self, class_name: str, id: str, beta: bool = False) -> Any:
"""Delete an EasyPost object via the EasyPost API."""
url = self._instance_url(class_name, id)

response = Requestor(self._client).request(method=RequestMethod.DELETE, url=url)
response = Requestor(self._client).request(method=RequestMethod.DELETE, url=url, beta=beta)

return convert_to_easypost_object(response=response)

Expand Down
70 changes: 70 additions & 0 deletions easypost/services/claim_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from typing import (
Any,
Dict,
Optional,
)

from easypost.easypost_object import convert_to_easypost_object
from easypost.models import Claim
from easypost.requestor import (
RequestMethod,
Requestor,
)
from easypost.services.base_service import BaseService


class ClaimService(BaseService):
def __init__(self, client):
self._client = client
self._model_class = Claim.__name__

def create(self, **params) -> Claim:
"""Create a Claim."""
url = "/claims"

response = Requestor(self._client).request(method=RequestMethod.POST, url=url, params=params, beta=False)

return convert_to_easypost_object(response=response)

def all(self, **params) -> Dict[str, Any]:
"""Retrieve a list of Claims."""
filters = {
"key": "claims",
}

return self._all_resources(class_name=self._model_class, filters=filters, beta=False, **params)

def retrieve(self, id: str) -> Claim:
"""Retrieve a Claim."""
return self._retrieve_resource(class_name=self._model_class, id=id, beta=False)

def get_next_page(
self,
claims: Dict[str, Any],
page_size: int,
optional_params: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
"""Retrieve the next page of the list Claim response."""
self._check_has_next_page(collection=claims)

params = {
"before_id": claims["claims"][-1].id,
"page_size": page_size,
}

if optional_params:
params.update(optional_params)

return self.all(**params)

def cancel(self, id: str) -> Claim:
"""Cancel a Claim."""
url = f"/claims/{id}/cancel"

response = Requestor(self._client).request(
method=RequestMethod.POST,
url=url,
beta=False,
)

return convert_to_easypost_object(response=response)
2 changes: 1 addition & 1 deletion examples
Submodule examples updated 223 files
128 changes: 128 additions & 0 deletions tests/cassettes/test_claim_all.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading