diff --git a/README.md b/README.md index da6ca37..24a1122 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ Before you begin to integrate: ### API and SDK Version -- SDK Version: 9.0.0 -- API Version: 2026-01 +- SDK Version: 10.0.0 +- API Version: 2026-07 ## Quick Start @@ -98,6 +98,27 @@ except exceptions.RateLimitExceedError: See the [Rate Limit](https://www.aftership.com/docs/tracking/quickstart/rate-limit) to understand the AfterShip rate limit policy. +The API returns its current rate limit status in the headers of every response, and the SDK exposes these headers on both successful responses and rate-limited errors, so you can monitor your consumption proactively instead of waiting for `429` errors. + +| Header | Description | +| ----------------------- | ---------------------------------------------------------- | +| `X-RateLimit-Limit` | The rate limit ceiling for the current endpoint per second | +| `X-RateLimit-Remaining` | The number of requests left for the 1-second window | +| `X-RateLimit-Reset` | The Unix timestamp when the rate limit will be reset | + +Every successful response exposes a `response_header` dict alongside `data` (header names are lower-cased, each value is a list of strings). Taking the Quick Start example above: + +```python +remaining = int(result.response_header["x-ratelimit-remaining"][0]) +reset_at = int(result.response_header["x-ratelimit-reset"][0]) + +if remaining <= 1: + # Throttle or defer lower-priority requests until reset_at + pass +``` + +When the rate limit is exceeded, the request fails with a `429` error that carries the same headers — see [Error Handling](#error-handling). + ## Error Handling The SDK will return an error object when there is any error during the request, with the following specification: diff --git a/pyproject.toml b/pyproject.toml index f48a8bd..28a18e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aftership-tracking-sdk" -version = "9.0.0" +version = "10.0.0" description = "The official AfterShip Tracking Python API library" authors = ["AfterShip "] license = "MIT" diff --git a/tracking/__init__.py b/tracking/__init__.py index b0cedd6..22e9965 100644 --- a/tracking/__init__.py +++ b/tracking/__init__.py @@ -11,4 +11,4 @@ from . import exceptions from .models import * -__version__ = "9.0.0" +__version__ = "10.0.0" diff --git a/tracking/api/courier.py b/tracking/api/courier.py index f502503..b2560ed 100644 --- a/tracking/api/courier.py +++ b/tracking/api/courier.py @@ -33,7 +33,7 @@ def get_couriers(self, **kwargs) -> GetCouriersResponse: **active**: bool. get user activated couriers **slug**: str. Unique courier code Use comma for multiple values. (Example: dhl,ups,usps) """ - url = "/tracking/2026-01/couriers" + url = "/tracking/2026-07/couriers" params_keys = { "active", @@ -59,7 +59,7 @@ def detect_courier( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = "/tracking/2026-01/couriers/detect" + url = "/tracking/2026-07/couriers/detect" body = detect_courier_request if not isinstance(body, dict): diff --git a/tracking/api/courier_connection.py b/tracking/api/courier_connection.py index d0fc59a..5d1587d 100644 --- a/tracking/api/courier_connection.py +++ b/tracking/api/courier_connection.py @@ -39,7 +39,7 @@ def get_courier_connections(self, **kwargs) -> GetCourierConnectionsResponse: **cursor**: str. A string representing the cursor value for the current page of results. **limit**: str. Number of courier connections each page contain. (Default: 100, Max: 200) """ - url = "/tracking/2026-01/courier-connections" + url = "/tracking/2026-07/courier-connections" params_keys = { "courier_slug", @@ -66,7 +66,7 @@ def post_courier_connections( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = "/tracking/2026-01/courier-connections" + url = "/tracking/2026-07/courier-connections" body = post_courier_connections_request if not isinstance(body, dict): @@ -91,7 +91,7 @@ def get_courier_connections_by_id( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = f"/tracking/2026-01/courier-connections/{id}" + url = f"/tracking/2026-07/courier-connections/{id}" result = self._request("GET", url=url, **kwargs) return GetCourierConnectionsByIdResponse.model_validate(result) @@ -115,7 +115,7 @@ def put_courier_connections_by_id( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = f"/tracking/2026-01/courier-connections/{id}" + url = f"/tracking/2026-07/courier-connections/{id}" body = put_courier_connections_by_id_request if not isinstance(body, dict): @@ -140,7 +140,7 @@ def delete_courier_connections_by_id( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = f"/tracking/2026-01/courier-connections/{id}" + url = f"/tracking/2026-07/courier-connections/{id}" result = self._request("DELETE", url=url, **kwargs) return DeleteCourierConnectionsByIdResponse.model_validate(result) diff --git a/tracking/api/estimated_delivery_date.py b/tracking/api/estimated_delivery_date.py index cb55cfc..5c1ba1f 100644 --- a/tracking/api/estimated_delivery_date.py +++ b/tracking/api/estimated_delivery_date.py @@ -34,7 +34,7 @@ def predict( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = "/tracking/2026-01/estimated-delivery-date/predict" + url = "/tracking/2026-07/estimated-delivery-date/predict" body = predict_request if not isinstance(body, dict): @@ -59,7 +59,7 @@ def predict_batch( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = "/tracking/2026-01/estimated-delivery-date/predict-batch" + url = "/tracking/2026-07/estimated-delivery-date/predict-batch" body = predict_batch_request if not isinstance(body, dict): diff --git a/tracking/api/tracking.py b/tracking/api/tracking.py index 306a06e..4568139 100644 --- a/tracking/api/tracking.py +++ b/tracking/api/tracking.py @@ -57,7 +57,7 @@ def get_trackings(self, **kwargs) -> GetTrackingsResponse: **shipment_tags**: str. Tags you added to your shipments to help categorize and filter them easily. Use a comma to separate multiple values (Example: a,b) **order_id**: str. A globally-unique identifier for the order. Use comma for multiple values.(Example: 6845a095a27a4caeb27487806f058add,4845a095a27a4caeb27487806f058abc) """ - url = "/tracking/2026-01/trackings" + url = "/tracking/2026-07/trackings" params_keys = { "cursor", @@ -99,7 +99,7 @@ def create_tracking( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = "/tracking/2026-01/trackings" + url = "/tracking/2026-07/trackings" body = create_tracking_request if not isinstance(body, dict): @@ -127,7 +127,7 @@ def get_tracking_by_id( **fields**: str. List of fields to include in the response. Use comma for multiple values. Fields to include: `destination_postal_code`, `tracking_ship_date`, `tracking_account_number`, `tracking_key`, `origin_country_region`, `destination_country_region`, `destination_state`, `title`, `order_id`, `tag`, `checkpoints` **lang**: str. Translate checkpoint messages from the carrier’s provided language to the target language. Supported target languages include:</br>&nbsp;&nbsp;&nbsp;&nbsp;- English (en)</br>&nbsp;&nbsp;&nbsp;&nbsp;- French (fr)</br>&nbsp;&nbsp;&nbsp;&nbsp;- French Canadian (fr-CA)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Arabic (ar)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Bulgarian (bg)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Catalan (ca)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Croatian (hr)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Czech (cs)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Danish (da)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Dutch (nl)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Estonian (et)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Filipino (tl)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Finnish (fi)</br>&nbsp;&nbsp;&nbsp;&nbsp;- German (de)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Greek (el)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Hebrew (he)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Hindi (hi)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Hungarian (hu)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Indonesian (id)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Italian (it)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Japanese (ja)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Korean (ko)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Latvian (lv)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Lithuanian (lt)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Malay (ms)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Polish (pl)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Portuguese (pt)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Romanian (ro)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Russian (ru)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Serbian (sr)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Slovak (sk)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Slovenian (sl)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Spanish (es)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Swedish (sv)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Thai (th)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Turkish (tr)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Ukrainian (uk)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Vietnamese (vi)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Simplified Chinese (zh-Hans)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Traditional Chinese (zh-Hant)</br>&nbsp;&nbsp;&nbsp;&nbsp;- Norwegian (nb)</br> """ - url = f"/tracking/2026-01/trackings/{id}" + url = f"/tracking/2026-07/trackings/{id}" params_keys = { "fields", @@ -157,7 +157,7 @@ def update_tracking_by_id( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = f"/tracking/2026-01/trackings/{id}" + url = f"/tracking/2026-07/trackings/{id}" body = update_tracking_by_id_request if not isinstance(body, dict): @@ -182,7 +182,7 @@ def delete_tracking_by_id( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = f"/tracking/2026-01/trackings/{id}" + url = f"/tracking/2026-07/trackings/{id}" result = self._request("DELETE", url=url, **kwargs) return DeleteTrackingByIdResponse.model_validate(result) @@ -202,7 +202,7 @@ def retrack_tracking_by_id( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = f"/tracking/2026-01/trackings/{id}/retrack" + url = f"/tracking/2026-07/trackings/{id}/retrack" result = self._request("POST", url=url, **kwargs) return RetrackTrackingByIdResponse.model_validate(result) @@ -226,7 +226,7 @@ def mark_tracking_completed_by_id( a path to an SSL certificate file, an `ssl.SSLContext`, or `False` (which will disable verification). """ - url = f"/tracking/2026-01/trackings/{id}/mark-as-completed" + url = f"/tracking/2026-07/trackings/{id}/mark-as-completed" body = mark_tracking_completed_by_id_request if not isinstance(body, dict): diff --git a/tracking/models/__init__.py b/tracking/models/__init__.py index 16bc9c0..b05eff9 100644 --- a/tracking/models/__init__.py +++ b/tracking/models/__init__.py @@ -11,6 +11,7 @@ "Meta", "TrackingCourierEstimatedDeliveryDate", "TrackingShipmentWeight", + "TrackingShipmentDimensions", "TrackingOrderPromisedDeliveryDate", "TrackingAftershipEstimatedDeliveryDate", "TrackingCustomEstimatedDeliveryDateType", @@ -27,6 +28,14 @@ "TrackingLastMileSource", "TrackingLastMile", "TrackingCustomers", + "TrackingProofOfDelivery", + "TrackingMultiPieceInfoType", + "TrackingMultiPieceInfoPiecesType", + "TrackingMultiPieceInfoPieces", + "TrackingMultiPieceInfo", + "TrackingShipmentDirection", + "TrackingReturnShipment", + "TrackingForwardShipment", "Tracking", "Tag", "CheckpointCoordinate", @@ -64,12 +73,14 @@ "CreateTrackingRequestDeliveryType", "CreateTrackingRequestLastMile", "CreateTrackingRequestCustomers", + "CreateTrackingRequestShipmentDirection", "CreateTrackingRequest", "CreateTrackingResponse", "GetTrackingByIdResponse", "UpdateTrackingByIdRequestOrderPromisedDeliveryDate", "UpdateTrackingByIdRequestDeliveryType", "UpdateTrackingByIdRequestCustomers", + "UpdateTrackingByIdRequestShipmentDirection", "UpdateTrackingByIdRequest", "UpdateTrackingByIdResponse", "DeleteTrackingByIdResponse", @@ -106,6 +117,7 @@ from .meta import Meta from .tracking_courier_estimated_delivery_date import TrackingCourierEstimatedDeliveryDate from .tracking_shipment_weight import TrackingShipmentWeight +from .tracking_shipment_dimensions import TrackingShipmentDimensions from .tracking_order_promised_delivery_date import TrackingOrderPromisedDeliveryDate from .tracking_aftership_estimated_delivery_date import TrackingAftershipEstimatedDeliveryDate from .tracking_custom_estimated_delivery_date_type import TrackingCustomEstimatedDeliveryDateType @@ -122,6 +134,14 @@ from .tracking_last_mile_source import TrackingLastMileSource from .tracking_last_mile import TrackingLastMile from .tracking_customers import TrackingCustomers +from .tracking_proof_of_delivery import TrackingProofOfDelivery +from .tracking_multi_piece_info_type import TrackingMultiPieceInfoType +from .tracking_multi_piece_info_pieces_type import TrackingMultiPieceInfoPiecesType +from .tracking_multi_piece_info_pieces import TrackingMultiPieceInfoPieces +from .tracking_multi_piece_info import TrackingMultiPieceInfo +from .tracking_shipment_direction import TrackingShipmentDirection +from .tracking_return_shipment import TrackingReturnShipment +from .tracking_forward_shipment import TrackingForwardShipment from .tracking import Tracking from .tag import Tag from .checkpoint_coordinate import CheckpointCoordinate @@ -183,6 +203,7 @@ from .create_tracking_request_delivery_type import CreateTrackingRequestDeliveryType from .create_tracking_request_last_mile import CreateTrackingRequestLastMile from .create_tracking_request_customers import CreateTrackingRequestCustomers +from .create_tracking_request_shipment_direction import CreateTrackingRequestShipmentDirection from .create_tracking_request import CreateTrackingRequest from .create_tracking_response import CreateTrackingResponse from .get_tracking_by_id_response import GetTrackingByIdResponse @@ -191,6 +212,9 @@ ) from .update_tracking_by_id_request_delivery_type import UpdateTrackingByIdRequestDeliveryType from .update_tracking_by_id_request_customers import UpdateTrackingByIdRequestCustomers +from .update_tracking_by_id_request_shipment_direction import ( + UpdateTrackingByIdRequestShipmentDirection, +) from .update_tracking_by_id_request import UpdateTrackingByIdRequest from .update_tracking_by_id_response import UpdateTrackingByIdResponse from .delete_tracking_by_id_response import DeleteTrackingByIdResponse diff --git a/tracking/models/checkpoint.py b/tracking/models/checkpoint.py index a95dcff..a6d2a26 100644 --- a/tracking/models/checkpoint.py +++ b/tracking/models/checkpoint.py @@ -38,6 +38,7 @@ class Checkpoint(BaseModel): raw_tag: Optional[str] = None events: Optional[List[CheckpointEvents]] = None source: Optional[CheckpointSource] = None + hash: Optional[str] = None def to_str(self, **kwargs) -> str: return pprint.pformat(self.model_dump(**kwargs)) diff --git a/tracking/models/create_tracking_request.py b/tracking/models/create_tracking_request.py index 780134d..ea00f9b 100644 --- a/tracking/models/create_tracking_request.py +++ b/tracking/models/create_tracking_request.py @@ -16,6 +16,9 @@ from tracking.models.create_tracking_request_delivery_type import CreateTrackingRequestDeliveryType from tracking.models.create_tracking_request_last_mile import CreateTrackingRequestLastMile from tracking.models.create_tracking_request_customers import CreateTrackingRequestCustomers +from tracking.models.create_tracking_request_shipment_direction import ( + CreateTrackingRequestShipmentDirection, +) class CreateTrackingRequest(BaseModel): @@ -59,6 +62,7 @@ class CreateTrackingRequest(BaseModel): shipping_method: Optional[str] = None last_mile: Optional[CreateTrackingRequestLastMile] = None customers: Optional[List[CreateTrackingRequestCustomers]] = None + shipment_direction: Optional[CreateTrackingRequestShipmentDirection] = None def to_str(self, **kwargs) -> str: return pprint.pformat(self.model_dump(**kwargs)) diff --git a/tracking/models/create_tracking_request_customers.py b/tracking/models/create_tracking_request_customers.py index de6affa..c77c535 100644 --- a/tracking/models/create_tracking_request_customers.py +++ b/tracking/models/create_tracking_request_customers.py @@ -21,6 +21,7 @@ class CreateTrackingRequestCustomers(BaseModel): phone_number: Optional[str] = None email: Optional[str] = None language: Optional[str] = None + id: Optional[str] = None def to_str(self, **kwargs) -> str: return pprint.pformat(self.model_dump(**kwargs)) diff --git a/tracking/models/create_tracking_request_shipment_direction.py b/tracking/models/create_tracking_request_shipment_direction.py new file mode 100644 index 0000000..30d7251 --- /dev/null +++ b/tracking/models/create_tracking_request_shipment_direction.py @@ -0,0 +1,18 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from enum import Enum, unique + + +@unique +class CreateTrackingRequestShipmentDirection(Enum): + """ + Indicates the business direction of the shipment in the e-commerce fulfillment lifecycle.Possible values:- `forward`: A forward (outbound-to-customer) shipment created for order fulfillment.- `return`: A return (customer-to-merchant) shipment created for after-sales return or exchange.When provided, this field gives AfterShip additional context about the shipment's intent, enabling more accurate status identification. + + allowed enum values + """ + + FORWARD = "forward" + RETURN = "return" diff --git a/tracking/models/create_tracking_response.py b/tracking/models/create_tracking_response.py index 67fdb39..18350cd 100644 --- a/tracking/models/create_tracking_response.py +++ b/tracking/models/create_tracking_response.py @@ -15,7 +15,7 @@ class CreateTrackingResponse(BaseModel): """ - Object describes the tracking information.<div style="display:none; height: 0"></div> + Object describes the tracking information.<div style="visibility:hidden; height: 0"></div> """ response_header: Dict[str, List[str]] = {} diff --git a/tracking/models/delete_tracking_by_id_response.py b/tracking/models/delete_tracking_by_id_response.py index 635485a..01d47ad 100644 --- a/tracking/models/delete_tracking_by_id_response.py +++ b/tracking/models/delete_tracking_by_id_response.py @@ -15,7 +15,7 @@ class DeleteTrackingByIdResponse(BaseModel): """ - Object describes the tracking information.<div style="display:none; height: 0"></div> + Object describes the tracking information.<div style="visibility:hidden; height: 0"></div> """ response_header: Dict[str, List[str]] = {} diff --git a/tracking/models/get_tracking_by_id_response.py b/tracking/models/get_tracking_by_id_response.py index 3764a98..5d4fbbe 100644 --- a/tracking/models/get_tracking_by_id_response.py +++ b/tracking/models/get_tracking_by_id_response.py @@ -15,7 +15,7 @@ class GetTrackingByIdResponse(BaseModel): """ - Object describes the tracking information.<div style="display:none; height: 0"></div> + Object describes the tracking information.<div style="visibility:hidden; height: 0"></div> """ response_header: Dict[str, List[str]] = {} diff --git a/tracking/models/mark_tracking_completed_by_id_response.py b/tracking/models/mark_tracking_completed_by_id_response.py index bcf64ea..14adcdd 100644 --- a/tracking/models/mark_tracking_completed_by_id_response.py +++ b/tracking/models/mark_tracking_completed_by_id_response.py @@ -15,7 +15,7 @@ class MarkTrackingCompletedByIdResponse(BaseModel): """ - Object describes the tracking information.<div style="display:none; height: 0"></div> + Object describes the tracking information.<div style="visibility:hidden; height: 0"></div> """ response_header: Dict[str, List[str]] = {} diff --git a/tracking/models/retrack_tracking_by_id_response.py b/tracking/models/retrack_tracking_by_id_response.py index e05f678..38fb7a2 100644 --- a/tracking/models/retrack_tracking_by_id_response.py +++ b/tracking/models/retrack_tracking_by_id_response.py @@ -15,7 +15,7 @@ class RetrackTrackingByIdResponse(BaseModel): """ - Object describes the tracking information.<div style="display:none; height: 0"></div> + Object describes the tracking information.<div style="visibility:hidden; height: 0"></div> """ response_header: Dict[str, List[str]] = {} diff --git a/tracking/models/tracking.py b/tracking/models/tracking.py index 98b5d1b..33793c9 100644 --- a/tracking/models/tracking.py +++ b/tracking/models/tracking.py @@ -14,6 +14,7 @@ TrackingCourierEstimatedDeliveryDate, ) from tracking.models.tracking_shipment_weight import TrackingShipmentWeight +from tracking.models.tracking_shipment_dimensions import TrackingShipmentDimensions from tracking.models.tag import Tag from tracking.models.checkpoint import Checkpoint from tracking.models.tracking_order_promised_delivery_date import TrackingOrderPromisedDeliveryDate @@ -30,11 +31,16 @@ from tracking.models.tracking_first_mile import TrackingFirstMile from tracking.models.tracking_last_mile import TrackingLastMile from tracking.models.tracking_customers import TrackingCustomers +from tracking.models.tracking_proof_of_delivery import TrackingProofOfDelivery +from tracking.models.tracking_multi_piece_info import TrackingMultiPieceInfo +from tracking.models.tracking_shipment_direction import TrackingShipmentDirection +from tracking.models.tracking_return_shipment import TrackingReturnShipment +from tracking.models.tracking_forward_shipment import TrackingForwardShipment class Tracking(BaseModel): """ - Object describes the tracking information.
+ Object describes the tracking information.
""" # noqa: E501 id: Optional[str] = None @@ -67,6 +73,7 @@ class Tracking(BaseModel): shipment_delivery_date: Optional[str] = None shipment_type: Optional[str] = None shipment_weight: Optional[TrackingShipmentWeight] = None + shipment_dimensions: Optional[TrackingShipmentDimensions] = None signed_by: Optional[str] = None source: Optional[str] = None tag: Optional[Tag] = None @@ -111,6 +118,11 @@ class Tracking(BaseModel): first_mile: Optional[TrackingFirstMile] = None last_mile: Optional[TrackingLastMile] = None customers: Optional[List[TrackingCustomers]] = None + proof_of_delivery: Optional[List[TrackingProofOfDelivery]] = None + multi_piece_info: Optional[TrackingMultiPieceInfo] = None + shipment_direction: Optional[TrackingShipmentDirection] = None + return_shipment: Optional[TrackingReturnShipment] = None + forward_shipment: Optional[TrackingForwardShipment] = None def to_str(self, **kwargs) -> str: return pprint.pformat(self.model_dump(**kwargs)) diff --git a/tracking/models/tracking_customers.py b/tracking/models/tracking_customers.py index a975fed..f24cf00 100644 --- a/tracking/models/tracking_customers.py +++ b/tracking/models/tracking_customers.py @@ -21,6 +21,7 @@ class TrackingCustomers(BaseModel): phone_number: Optional[str] = None email: Optional[str] = None language: Optional[str] = None + id: Optional[str] = None def to_str(self, **kwargs) -> str: return pprint.pformat(self.model_dump(**kwargs)) diff --git a/tracking/models/tracking_forward_shipment.py b/tracking/models/tracking_forward_shipment.py new file mode 100644 index 0000000..ba26313 --- /dev/null +++ b/tracking/models/tracking_forward_shipment.py @@ -0,0 +1,36 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from __future__ import annotations +import pprint + +from pydantic import BaseModel +from typing import Any, Dict, Optional +from typing_extensions import Self + + +class TrackingForwardShipment(BaseModel): + """ + The original outbound shipment linked to this return. Use this to trace a return back to its source delivery.This field is only present when `shipment_direction = "return"` and AfterShip has detected a linked forward shipment. + """ # noqa: E501 + + id: Optional[str] = None + + def to_str(self, **kwargs) -> str: + return pprint.pformat(self.model_dump(**kwargs)) + + def to_json(self, **kwargs) -> str: + return self.model_dump_json(**kwargs) + + def to_dict(self, **kwargs) -> Dict[str, Any]: + return self.model_dump(**kwargs) + + @classmethod + def from_json(cls, json_str: str, **kwargs) -> Optional[Self]: + return cls.model_validate_json(json_str, **kwargs) + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]], **kwargs) -> Optional[Self]: + return cls.model_validate(obj, **kwargs) if isinstance(obj, Dict) else None diff --git a/tracking/models/tracking_multi_piece_info.py b/tracking/models/tracking_multi_piece_info.py new file mode 100644 index 0000000..b066d8a --- /dev/null +++ b/tracking/models/tracking_multi_piece_info.py @@ -0,0 +1,40 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from __future__ import annotations +import pprint + +from pydantic import BaseModel +from typing import Any, Dict, List, Optional +from typing_extensions import Self + +from tracking.models.tracking_multi_piece_info_type import TrackingMultiPieceInfoType +from tracking.models.tracking_multi_piece_info_pieces import TrackingMultiPieceInfoPieces + + +class TrackingMultiPieceInfo(BaseModel): + """ + Multi-piece shipment refers to a scenario where a single shipment order is fulfilled by multiple physical packages. Each piece has its own carrier-assigned tracking number, but all pieces belong to the same shipment. This commonly occurs when an order is too large to fit in one box, or when items are packed separately for handling reasons.This field contains multi-piece shipment metadata describing a group of packages that belong to the same shipment.This field returns a value only when your subscription plan includes a multi-piece feature. To enable, go to . + """ # noqa: E501 + + type: Optional[TrackingMultiPieceInfoType] = None + pieces: Optional[List[TrackingMultiPieceInfoPieces]] = None + + def to_str(self, **kwargs) -> str: + return pprint.pformat(self.model_dump(**kwargs)) + + def to_json(self, **kwargs) -> str: + return self.model_dump_json(**kwargs) + + def to_dict(self, **kwargs) -> Dict[str, Any]: + return self.model_dump(**kwargs) + + @classmethod + def from_json(cls, json_str: str, **kwargs) -> Optional[Self]: + return cls.model_validate_json(json_str, **kwargs) + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]], **kwargs) -> Optional[Self]: + return cls.model_validate(obj, **kwargs) if isinstance(obj, Dict) else None diff --git a/tracking/models/tracking_multi_piece_info_pieces.py b/tracking/models/tracking_multi_piece_info_pieces.py new file mode 100644 index 0000000..3ad1755 --- /dev/null +++ b/tracking/models/tracking_multi_piece_info_pieces.py @@ -0,0 +1,41 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from __future__ import annotations +import pprint + +from pydantic import BaseModel +from typing import Any, Dict, Optional +from typing_extensions import Self + +from tracking.models.tracking_multi_piece_info_pieces_type import TrackingMultiPieceInfoPiecesType + + +class TrackingMultiPieceInfoPieces(BaseModel): + """ + TrackingMultiPieceInfoPieces + """ # noqa: E501 + + tracking_id: Optional[str] = None + tracking_number: Optional[str] = None + type: Optional[TrackingMultiPieceInfoPiecesType] = None + trackable: Optional[bool] = None + + def to_str(self, **kwargs) -> str: + return pprint.pformat(self.model_dump(**kwargs)) + + def to_json(self, **kwargs) -> str: + return self.model_dump_json(**kwargs) + + def to_dict(self, **kwargs) -> Dict[str, Any]: + return self.model_dump(**kwargs) + + @classmethod + def from_json(cls, json_str: str, **kwargs) -> Optional[Self]: + return cls.model_validate_json(json_str, **kwargs) + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]], **kwargs) -> Optional[Self]: + return cls.model_validate(obj, **kwargs) if isinstance(obj, Dict) else None diff --git a/tracking/models/tracking_multi_piece_info_pieces_type.py b/tracking/models/tracking_multi_piece_info_pieces_type.py new file mode 100644 index 0000000..57b35c7 --- /dev/null +++ b/tracking/models/tracking_multi_piece_info_pieces_type.py @@ -0,0 +1,18 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from enum import Enum, unique + + +@unique +class TrackingMultiPieceInfoPiecesType(Enum): + """ + Type of the piece within the MPS: `master` or `child`. + + allowed enum values + """ + + MASTER = "master" + CHILD = "child" diff --git a/tracking/models/tracking_multi_piece_info_type.py b/tracking/models/tracking_multi_piece_info_type.py new file mode 100644 index 0000000..4725cba --- /dev/null +++ b/tracking/models/tracking_multi_piece_info_type.py @@ -0,0 +1,18 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from enum import Enum, unique + + +@unique +class TrackingMultiPieceInfoType(Enum): + """ + Indicates the role of the current tracking object within the multi-piece shipment.Possible values:- `master`: The main tracking number representing the entire shipment. It may not always exist.- `child`: A sub-tracking number belonging to one of the pieces in the shipment. + + allowed enum values + """ + + MASTER = "master" + CHILD = "child" diff --git a/tracking/models/tracking_proof_of_delivery.py b/tracking/models/tracking_proof_of_delivery.py new file mode 100644 index 0000000..932d2a7 --- /dev/null +++ b/tracking/models/tracking_proof_of_delivery.py @@ -0,0 +1,37 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from __future__ import annotations +import pprint + +from pydantic import BaseModel +from typing import Any, Dict, Optional +from typing_extensions import Self + + +class TrackingProofOfDelivery(BaseModel): + """ + TrackingProofOfDelivery + """ # noqa: E501 + + type: Optional[str] = None + url: Optional[str] = None + + def to_str(self, **kwargs) -> str: + return pprint.pformat(self.model_dump(**kwargs)) + + def to_json(self, **kwargs) -> str: + return self.model_dump_json(**kwargs) + + def to_dict(self, **kwargs) -> Dict[str, Any]: + return self.model_dump(**kwargs) + + @classmethod + def from_json(cls, json_str: str, **kwargs) -> Optional[Self]: + return cls.model_validate_json(json_str, **kwargs) + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]], **kwargs) -> Optional[Self]: + return cls.model_validate(obj, **kwargs) if isinstance(obj, Dict) else None diff --git a/tracking/models/tracking_return_shipment.py b/tracking/models/tracking_return_shipment.py new file mode 100644 index 0000000..3a2dfbd --- /dev/null +++ b/tracking/models/tracking_return_shipment.py @@ -0,0 +1,38 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from __future__ import annotations +import pprint + +from pydantic import BaseModel +from typing import Any, Dict, Optional +from typing_extensions import Self + + +class TrackingReturnShipment(BaseModel): + """ + The associated return shipment linked to the current outbound shipment.This field is only present when `shipment_direction = "forward"` and AfterShip has detected a linked return shipment. + """ # noqa: E501 + + id: Optional[str] = None + tracking_number: Optional[str] = None + slug: Optional[str] = None + + def to_str(self, **kwargs) -> str: + return pprint.pformat(self.model_dump(**kwargs)) + + def to_json(self, **kwargs) -> str: + return self.model_dump_json(**kwargs) + + def to_dict(self, **kwargs) -> Dict[str, Any]: + return self.model_dump(**kwargs) + + @classmethod + def from_json(cls, json_str: str, **kwargs) -> Optional[Self]: + return cls.model_validate_json(json_str, **kwargs) + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]], **kwargs) -> Optional[Self]: + return cls.model_validate(obj, **kwargs) if isinstance(obj, Dict) else None diff --git a/tracking/models/tracking_shipment_dimensions.py b/tracking/models/tracking_shipment_dimensions.py new file mode 100644 index 0000000..a6f9b34 --- /dev/null +++ b/tracking/models/tracking_shipment_dimensions.py @@ -0,0 +1,39 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from __future__ import annotations +import pprint + +from pydantic import BaseModel +from typing import Any, Dict, Optional +from typing_extensions import Self + + +class TrackingShipmentDimensions(BaseModel): + """ + Physical dimensions of the package (length, width and height). + """ # noqa: E501 + + unit: Optional[str] = None + length: Optional[float] = None + width: Optional[float] = None + height: Optional[float] = None + + def to_str(self, **kwargs) -> str: + return pprint.pformat(self.model_dump(**kwargs)) + + def to_json(self, **kwargs) -> str: + return self.model_dump_json(**kwargs) + + def to_dict(self, **kwargs) -> Dict[str, Any]: + return self.model_dump(**kwargs) + + @classmethod + def from_json(cls, json_str: str, **kwargs) -> Optional[Self]: + return cls.model_validate_json(json_str, **kwargs) + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]], **kwargs) -> Optional[Self]: + return cls.model_validate(obj, **kwargs) if isinstance(obj, Dict) else None diff --git a/tracking/models/tracking_shipment_direction.py b/tracking/models/tracking_shipment_direction.py new file mode 100644 index 0000000..e89e521 --- /dev/null +++ b/tracking/models/tracking_shipment_direction.py @@ -0,0 +1,19 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from enum import Enum, unique + + +@unique +class TrackingShipmentDirection(Enum): + """ + Indicates the business direction of the shipment in the e-commerce fulfillment lifecycle.Possible values:- `forward`: A forward (outbound-to-customer) shipment created for order fulfillment.- `return`: A return (customer-to-merchant) shipment created for after-sales return or exchange.This field is populated in either of the following cases:1. You explicitly provided it when creating the tracking.2. AfterShip automatically detected a linked forward or return shipment.It also determines which related shipment object (`forward_shipment` or `return_shipment`) may appear in the response. + + allowed enum values + """ + + FORWARD = "forward" + RETURN = "return" + NULL = "null" diff --git a/tracking/models/update_tracking_by_id_request.py b/tracking/models/update_tracking_by_id_request.py index c902a6c..8bb9839 100644 --- a/tracking/models/update_tracking_by_id_request.py +++ b/tracking/models/update_tracking_by_id_request.py @@ -19,6 +19,9 @@ from tracking.models.update_tracking_by_id_request_customers import ( UpdateTrackingByIdRequestCustomers, ) +from tracking.models.update_tracking_by_id_request_shipment_direction import ( + UpdateTrackingByIdRequestShipmentDirection, +) class UpdateTrackingByIdRequest(BaseModel): @@ -58,6 +61,7 @@ class UpdateTrackingByIdRequest(BaseModel): location_id: Optional[str] = None shipping_method: Optional[str] = None customers: Optional[List[UpdateTrackingByIdRequestCustomers]] = None + shipment_direction: Optional[UpdateTrackingByIdRequestShipmentDirection] = None def to_str(self, **kwargs) -> str: return pprint.pformat(self.model_dump(**kwargs)) diff --git a/tracking/models/update_tracking_by_id_request_customers.py b/tracking/models/update_tracking_by_id_request_customers.py index 3f10c06..dcdac90 100644 --- a/tracking/models/update_tracking_by_id_request_customers.py +++ b/tracking/models/update_tracking_by_id_request_customers.py @@ -21,6 +21,7 @@ class UpdateTrackingByIdRequestCustomers(BaseModel): phone_number: Optional[str] = None email: Optional[str] = None language: Optional[str] = None + id: Optional[str] = None def to_str(self, **kwargs) -> str: return pprint.pformat(self.model_dump(**kwargs)) diff --git a/tracking/models/update_tracking_by_id_request_shipment_direction.py b/tracking/models/update_tracking_by_id_request_shipment_direction.py new file mode 100644 index 0000000..0884c88 --- /dev/null +++ b/tracking/models/update_tracking_by_id_request_shipment_direction.py @@ -0,0 +1,18 @@ +# coding: utf-8 +# +# This code was auto generated by AfterShip SDK Generator. +# Do not edit the class manually. + +from enum import Enum, unique + + +@unique +class UpdateTrackingByIdRequestShipmentDirection(Enum): + """ + Indicates the business direction of the shipment in the e-commerce fulfillment lifecycle.Possible values:- `forward`: A forward (outbound-to-customer) shipment created for order fulfillment.- `return`: A return (customer-to-merchant) shipment created for after-sales return or exchange.When provided, this field gives AfterShip additional context about the shipment's intent, enabling more accurate status identification. + + allowed enum values + """ + + FORWARD = "forward" + RETURN = "return" diff --git a/tracking/models/update_tracking_by_id_response.py b/tracking/models/update_tracking_by_id_response.py index ccd442b..ab6b8cf 100644 --- a/tracking/models/update_tracking_by_id_response.py +++ b/tracking/models/update_tracking_by_id_response.py @@ -15,7 +15,7 @@ class UpdateTrackingByIdResponse(BaseModel): """ - Object describes the tracking information.<div style="display:none; height: 0"></div> + Object describes the tracking information.<div style="visibility:hidden; height: 0"></div> """ response_header: Dict[str, List[str]] = {} diff --git a/tracking/request.py b/tracking/request.py index 35aa57b..eb34516 100644 --- a/tracking/request.py +++ b/tracking/request.py @@ -17,7 +17,7 @@ from tracking.response import parse_response from tracking.exceptions import ApiException, TimedOutError, BadRequestError, ErrorCodeEnum -_default_user_agent = "tracking-sdk-python/9.0.0 (https://www.aftership.com) httpx/0.19.0" +_default_user_agent = "tracking-sdk-python/10.0.0 (https://www.aftership.com) httpx/0.19.0" def validate_params(func):