Skip to content

Commit 7ca0f6d

Browse files
authored
Merge pull request #23 from 1415003719/2025-07
update structure
2 parents 26500c3 + c45d00c commit 7ca0f6d

File tree

171 files changed

+1531
-4697
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+1531
-4697
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
3838

3939
- name: Upload artifact
40-
uses: actions/upload-artifact@v4
40+
uses: actions/upload-artifact@v3
4141
with:
4242
name: ${{ steps.get_version.outputs.VERSION }}
4343
path: dist

README.md

Lines changed: 225 additions & 116 deletions
Large diffs are not rendered by default.

poetry.lock

Lines changed: 206 additions & 209 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
[tool.poetry]
22
name = "aftership-tracking-sdk"
3-
version = "7.1.0"
3+
version = "8.0.0"
44
description = "The official AfterShip Tracking Python API library"
55
authors = ["AfterShip <[email protected]>"]
66
license = "MIT"
77
readme = "README.md"
8-
keywords = ["aftership", "tracking", "track", "fedex", "ups", "usps", "dhl", "shipping", "fulfillment", "couriers", "carriers", "logistics"]
8+
keywords = ["aftership", "tracking", "dhl"]
99

1010
classifiers = [
11-
"Development Status :: 5 - Production/Stable",
12-
"Intended Audience :: Developers",
13-
"License :: OSI Approved :: MIT License",
14-
"Topic :: Software Development",
15-
"Programming Language :: Python :: 3.8",
16-
"Programming Language :: Python :: 3.9",
17-
"Programming Language :: Python :: 3.10",
18-
"Programming Language :: Python :: 3.11",
11+
"Development Status :: 5 - Production/Stable",
12+
"Intended Audience :: Developers",
13+
"License :: OSI Approved :: MIT License",
14+
"Topic :: Software Development",
15+
"Programming Language :: Python :: 3.8",
16+
"Programming Language :: Python :: 3.9",
17+
"Programming Language :: Python :: 3.10",
18+
"Programming Language :: Python :: 3.11",
1919
]
2020

2121
packages = [
22-
{ include = "tracking" },
23-
{ include = "*.md" },
24-
{ include = "LICENSE" },
22+
{ include = "tracking" },
23+
{ include = "*.md" },
24+
{ include = "LICENSE" },
2525
]
2626

2727
[tool.poetry.dependencies]
2828
python = "^3.8"
2929
pycryptodome = ">= 3.9.0"
3030
pydantic = ">=2"
31+
httpx = ">=0.27.0"
3132
retrying = "^1.3.4"
3233
typing_extensions = ">=4.7.1"
3334
urllib3 = "^2.2.2"
3435
socksio = "^1.0.0"
35-
httpx = "^0.28.1"
3636

3737
[tool.poetry.group.dev.dependencies]
3838
ruff = "^0.4.8"

tracking/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
from . import exceptions
1212
from .models import *
1313

14-
__version__ = "7.1.0"
14+
__version__ = "8.0.0"

tracking/api/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
# Do not edit the class manually.
55

66
__all__ = [
7-
"CourierApi",
87
"CourierConnectionApi",
98
"EstimatedDeliveryDateApi",
109
"TrackingApi",
10+
"CourierApi",
1111
]
1212

13-
from .courier import CourierApi
1413
from .courier_connection import CourierConnectionApi
1514
from .estimated_delivery_date import EstimatedDeliveryDateApi
1615
from .tracking import TrackingApi
16+
from .courier import CourierApi

tracking/api/courier.py

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99

1010
from tracking.models import (
11+
GetCouriersResponse,
1112
DetectCourierRequest,
1213
DetectCourierResponse,
13-
GetCouriersResponse,
1414
)
1515
from tracking.request import ApiClient, validate_params
1616

@@ -19,51 +19,52 @@ class CourierApi(ApiClient):
1919
"""CourierApi api implements"""
2020

2121
@validate_params
22-
def detect_courier(
23-
self, detect_courier_request: Union[DetectCourierRequest, dict], **kwargs
24-
) -> DetectCourierResponse:
22+
def get_couriers(self, **kwargs) -> GetCouriersResponse:
2523
"""
26-
Return a list of matched couriers based on tracking number format and or a list of couriers.
27-
:param detect_courier_request:
24+
Return a list of couriers.
2825
:param kwargs:
2926
request options:
3027
**headers** (dict): support custom headers.
3128
**verify** bool|str|SSLContext: SSL certificates (a.k.a CA bundle) used to
3229
verify the identity of requested hosts. Either `True` (default CA bundle),
3330
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
3431
(which will disable verification).
32+
query params:
33+
**active**: bool. get user activated couriers
34+
**slug**: str. Unique courier code Use comma for multiple values. (Example: dhl,ups,usps)
3535
"""
36-
url = "/tracking/2025-07/couriers/detect"
36+
url = "/tracking/2025-07/couriers"
3737

38-
body = detect_courier_request
39-
if not isinstance(body, dict):
40-
body = detect_courier_request.model_dump(exclude_none=True)
41-
body = json.dumps(body)
38+
params_keys = {
39+
"active",
40+
"slug",
41+
}
42+
params = {key: kwargs.pop(key) for key in params_keys if key in kwargs}
4243

43-
result = self._request("POST", url=url, body=body, **kwargs)
44-
return DetectCourierResponse().from_dict(result)
44+
result = self._request("GET", url=url, params=params, **kwargs)
45+
return GetCouriersResponse.model_validate(result)
4546

4647
@validate_params
47-
def get_couriers(self, **kwargs) -> GetCouriersResponse:
48+
def detect_courier(
49+
self, detect_courier_request: Union[DetectCourierRequest, dict], **kwargs
50+
) -> DetectCourierResponse:
4851
"""
49-
Return a list of couriers.
52+
Return a list of matched couriers based on tracking number format and or a list of couriers.
53+
:param detect_courier_request:
5054
:param kwargs:
5155
request options:
5256
**headers** (dict): support custom headers.
5357
**verify** bool|str|SSLContext: SSL certificates (a.k.a CA bundle) used to
5458
verify the identity of requested hosts. Either `True` (default CA bundle),
5559
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
5660
(which will disable verification).
57-
query params:
58-
**active**: bool. get user activated couriers
59-
**slug**: str. Unique courier code Use comma for multiple values. (Example: dhl,ups,usps)
6061
"""
61-
url = "/tracking/2025-07/couriers"
62-
params_keys = {
63-
"active",
64-
"slug",
65-
}
66-
params = {key: kwargs.pop(key) for key in params_keys if key in kwargs}
62+
url = "/tracking/2025-07/couriers/detect"
6763

68-
result = self._request("GET", url=url, params=params, **kwargs)
69-
return GetCouriersResponse().from_dict(result)
64+
body = detect_courier_request
65+
if not isinstance(body, dict):
66+
body = detect_courier_request.model_dump(exclude_none=True, mode="json")
67+
body = json.dumps(body)
68+
69+
result = self._request("POST", url=url, body=body, **kwargs)
70+
return DetectCourierResponse.model_validate(result)

tracking/api/courier_connection.py

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,20 @@
99
from pydantic import Field
1010

1111
from tracking.models import (
12-
DeleteCourierConnectionsByIdResponse,
1312
GetCourierConnectionsResponse,
14-
GetCourierConnectionsByIdResponse,
1513
PostCourierConnectionsRequest,
1614
PostCourierConnectionsResponse,
15+
GetCourierConnectionsByIdResponse,
1716
PutCourierConnectionsByIdRequest,
1817
PutCourierConnectionsByIdResponse,
18+
DeleteCourierConnectionsByIdResponse,
1919
)
2020
from tracking.request import ApiClient, validate_params
2121

2222

2323
class CourierConnectionApi(ApiClient):
2424
"""CourierConnectionApi api implements"""
2525

26-
@validate_params
27-
def delete_courier_connections_by_id(
28-
self, courier_connection_id: Annotated[str, Field(min_length=1)], **kwargs
29-
) -> DeleteCourierConnectionsByIdResponse:
30-
"""
31-
Delete a courier connection.
32-
:param courier_connection_id: str.
33-
:param kwargs:
34-
request options:
35-
**headers** (dict): support custom headers.
36-
**verify** bool|str|SSLContext: SSL certificates (a.k.a CA bundle) used to
37-
verify the identity of requested hosts. Either `True` (default CA bundle),
38-
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
39-
(which will disable verification).
40-
"""
41-
url = f"/tracking/2025-07/courier-connections/{courier_connection_id}"
42-
43-
result = self._request("DELETE", url=url, **kwargs)
44-
return DeleteCourierConnectionsByIdResponse().from_dict(result)
45-
4626
@validate_params
4727
def get_courier_connections(self, **kwargs) -> GetCourierConnectionsResponse:
4828
"""
@@ -60,6 +40,7 @@ def get_courier_connections(self, **kwargs) -> GetCourierConnectionsResponse:
6040
**limit**: str. Number of courier connections each page contain. (Default: 100, Max: 200)
6141
"""
6242
url = "/tracking/2025-07/courier-connections"
43+
6344
params_keys = {
6445
"courier_slug",
6546
"cursor",
@@ -68,20 +49,15 @@ def get_courier_connections(self, **kwargs) -> GetCourierConnectionsResponse:
6849
params = {key: kwargs.pop(key) for key in params_keys if key in kwargs}
6950

7051
result = self._request("GET", url=url, params=params, **kwargs)
71-
return GetCourierConnectionsResponse().from_dict(
72-
{
73-
"pagination": result.get("pagination"),
74-
"courier_connections": result.get("courier_connections"),
75-
}
76-
)
52+
return GetCourierConnectionsResponse.model_validate(result)
7753

7854
@validate_params
79-
def get_courier_connections_by_id(
80-
self, courier_connection_id: Annotated[str, Field(min_length=1)], **kwargs
81-
) -> GetCourierConnectionsByIdResponse:
55+
def post_courier_connections(
56+
self, post_courier_connections_request: Union[PostCourierConnectionsRequest, dict], **kwargs
57+
) -> PostCourierConnectionsResponse:
8258
"""
83-
Get courier connection results of a single courier connection.
84-
:param courier_connection_id: str.
59+
60+
:param post_courier_connections_request:
8561
:param kwargs:
8662
request options:
8763
**headers** (dict): support custom headers.
@@ -90,18 +66,23 @@ def get_courier_connections_by_id(
9066
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
9167
(which will disable verification).
9268
"""
93-
url = f"/tracking/2025-07/courier-connections/{courier_connection_id}"
69+
url = "/tracking/2025-07/courier-connections"
9470

95-
result = self._request("GET", url=url, **kwargs)
96-
return GetCourierConnectionsByIdResponse().from_dict(result)
71+
body = post_courier_connections_request
72+
if not isinstance(body, dict):
73+
body = post_courier_connections_request.model_dump(exclude_none=True, mode="json")
74+
body = json.dumps(body)
75+
76+
result = self._request("POST", url=url, body=body, **kwargs)
77+
return PostCourierConnectionsResponse.model_validate(result)
9778

9879
@validate_params
99-
def post_courier_connections(
100-
self, post_courier_connections_request: Union[PostCourierConnectionsRequest, dict], **kwargs
101-
) -> PostCourierConnectionsResponse:
80+
def get_courier_connections_by_id(
81+
self, id: Annotated[str, Field(min_length=1)], **kwargs
82+
) -> GetCourierConnectionsByIdResponse:
10283
"""
103-
104-
:param post_courier_connections_request:
84+
Get courier connection results of a single courier connection.
85+
:param id: str.
10586
:param kwargs:
10687
request options:
10788
**headers** (dict): support custom headers.
@@ -110,26 +91,21 @@ def post_courier_connections(
11091
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
11192
(which will disable verification).
11293
"""
113-
url = "/tracking/2025-07/courier-connections"
114-
115-
body = post_courier_connections_request
116-
if not isinstance(body, dict):
117-
body = post_courier_connections_request.model_dump(exclude_none=True)
118-
body = json.dumps(body)
94+
url = f"/tracking/2025-07/courier-connections/{id}"
11995

120-
result = self._request("POST", url=url, body=body, **kwargs)
121-
return PostCourierConnectionsResponse().from_dict(result)
96+
result = self._request("GET", url=url, **kwargs)
97+
return GetCourierConnectionsByIdResponse.model_validate(result)
12298

12399
@validate_params
124100
def put_courier_connections_by_id(
125101
self,
126-
courier_connection_id: Annotated[str, Field(min_length=1)],
102+
id: Annotated[str, Field(min_length=1)],
127103
put_courier_connections_by_id_request: Union[PutCourierConnectionsByIdRequest, dict],
128104
**kwargs,
129105
) -> PutCourierConnectionsByIdResponse:
130106
"""
131107
Update a courier connection.
132-
:param courier_connection_id: str.
108+
:param id: str.
133109
:param put_courier_connections_by_id_request:
134110
:param kwargs:
135111
request options:
@@ -139,12 +115,32 @@ def put_courier_connections_by_id(
139115
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
140116
(which will disable verification).
141117
"""
142-
url = f"/tracking/2025-07/courier-connections/{courier_connection_id}"
118+
url = f"/tracking/2025-07/courier-connections/{id}"
143119

144120
body = put_courier_connections_by_id_request
145121
if not isinstance(body, dict):
146-
body = put_courier_connections_by_id_request.model_dump(exclude_none=True)
122+
body = put_courier_connections_by_id_request.model_dump(exclude_none=True, mode="json")
147123
body = json.dumps(body)
148124

149125
result = self._request("PATCH", url=url, body=body, **kwargs)
150-
return PutCourierConnectionsByIdResponse().from_dict(result)
126+
return PutCourierConnectionsByIdResponse.model_validate(result)
127+
128+
@validate_params
129+
def delete_courier_connections_by_id(
130+
self, id: Annotated[str, Field(min_length=1)], **kwargs
131+
) -> DeleteCourierConnectionsByIdResponse:
132+
"""
133+
Delete a courier connection.
134+
:param id: str.
135+
:param kwargs:
136+
request options:
137+
**headers** (dict): support custom headers.
138+
**verify** bool|str|SSLContext: SSL certificates (a.k.a CA bundle) used to
139+
verify the identity of requested hosts. Either `True` (default CA bundle),
140+
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
141+
(which will disable verification).
142+
"""
143+
url = f"/tracking/2025-07/courier-connections/{id}"
144+
145+
result = self._request("DELETE", url=url, **kwargs)
146+
return DeleteCourierConnectionsByIdResponse.model_validate(result)

tracking/api/estimated_delivery_date.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
from tracking.models import (
11-
PredictRequest,
11+
EstimatedDeliveryDateRequest,
1212
PredictResponse,
1313
PredictBatchRequest,
1414
PredictBatchResponse,
@@ -20,7 +20,9 @@ class EstimatedDeliveryDateApi(ApiClient):
2020
"""EstimatedDeliveryDateApi api implements"""
2121

2222
@validate_params
23-
def predict(self, predict_request: Union[PredictRequest, dict], **kwargs) -> PredictResponse:
23+
def predict(
24+
self, predict_request: Union[EstimatedDeliveryDateRequest, dict], **kwargs
25+
) -> PredictResponse:
2426
"""
2527
> The estimated delivery date is provided by AfterShip, based on its AI-predictive model. You can display the EDD on the product page, cart, and order checkout page. It indicates when a customer will receive the order.You can use to activate this feature.
2628
:param predict_request:
@@ -36,11 +38,11 @@ def predict(self, predict_request: Union[PredictRequest, dict], **kwargs) -> Pre
3638

3739
body = predict_request
3840
if not isinstance(body, dict):
39-
body = predict_request.model_dump(exclude_none=True)
41+
body = predict_request.model_dump(exclude_none=True, mode="json")
4042
body = json.dumps(body)
4143

4244
result = self._request("POST", url=url, body=body, **kwargs)
43-
return PredictResponse().from_dict(result)
45+
return PredictResponse.model_validate(result)
4446

4547
@validate_params
4648
def predict_batch(
@@ -61,8 +63,8 @@ def predict_batch(
6163

6264
body = predict_batch_request
6365
if not isinstance(body, dict):
64-
body = predict_batch_request.model_dump(exclude_none=True)
66+
body = predict_batch_request.model_dump(exclude_none=True, mode="json")
6567
body = json.dumps(body)
6668

6769
result = self._request("POST", url=url, body=body, **kwargs)
68-
return PredictBatchResponse().from_dict(result)
70+
return PredictBatchResponse.model_validate(result)

0 commit comments

Comments
 (0)