karrio-teleship 2025.5__py3-none-any.whl → 2025.5rc35__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- karrio/mappers/teleship/__init__.py +1 -2
- karrio/mappers/teleship/mapper.py +0 -60
- karrio/mappers/teleship/proxy.py +38 -191
- karrio/plugins/teleship/__init__.py +1 -4
- karrio/providers/teleship/__init__.py +0 -25
- karrio/providers/teleship/rate.py +247 -210
- karrio/providers/teleship/shipment/cancel.py +58 -15
- karrio/providers/teleship/shipment/create.py +266 -238
- karrio/providers/teleship/tracking.py +50 -35
- karrio/providers/teleship/units.py +67 -67
- karrio/providers/teleship/utils.py +132 -16
- karrio/schemas/teleship/error_response.py +0 -1
- karrio/schemas/teleship/rate_request.py +34 -16
- karrio/schemas/teleship/rate_response.py +3 -20
- karrio/schemas/teleship/shipment_request.py +34 -16
- karrio/schemas/teleship/shipment_response.py +29 -188
- karrio/schemas/teleship/tracking_response.py +5 -15
- {karrio_teleship-2025.5.dist-info → karrio_teleship-2025.5rc35.dist-info}/METADATA +2 -2
- karrio_teleship-2025.5rc35.dist-info/RECORD +29 -0
- karrio_teleship-2025.5rc35.dist-info/entry_points.txt +2 -0
- karrio/mappers/teleship/hooks.py +0 -27
- karrio/providers/teleship/duties.py +0 -115
- karrio/providers/teleship/hooks/__init__.py +0 -5
- karrio/providers/teleship/hooks/event.py +0 -163
- karrio/providers/teleship/hooks/oauth.py +0 -103
- karrio/providers/teleship/manifest.py +0 -68
- karrio/providers/teleship/pickup/__init__.py +0 -8
- karrio/providers/teleship/pickup/cancel.py +0 -43
- karrio/providers/teleship/pickup/schedule.py +0 -66
- karrio/providers/teleship/webhook/__init__.py +0 -8
- karrio/providers/teleship/webhook/deregister.py +0 -47
- karrio/providers/teleship/webhook/register.py +0 -48
- karrio/schemas/teleship/duties_taxes_request.py +0 -82
- karrio/schemas/teleship/duties_taxes_response.py +0 -28
- karrio/schemas/teleship/manifest_request.py +0 -39
- karrio/schemas/teleship/manifest_response.py +0 -31
- karrio/schemas/teleship/pickup_request.py +0 -31
- karrio/schemas/teleship/pickup_response.py +0 -48
- karrio/schemas/teleship/webhook_request.py +0 -18
- karrio/schemas/teleship/webhook_response.py +0 -20
- karrio_teleship-2025.5.dist-info/RECORD +0 -49
- karrio_teleship-2025.5.dist-info/entry_points.txt +0 -2
- {karrio_teleship-2025.5.dist-info → karrio_teleship-2025.5rc35.dist-info}/WHEEL +0 -0
- {karrio_teleship-2025.5.dist-info → karrio_teleship-2025.5rc35.dist-info}/top_level.txt +0 -0
|
@@ -51,64 +51,4 @@ class Mapper(mapper.Mapper):
|
|
|
51
51
|
self, response: lib.Deserializable[str]
|
|
52
52
|
) -> typing.Tuple[typing.List[models.TrackingDetails], typing.List[models.Message]]:
|
|
53
53
|
return provider.parse_tracking_response(response, self.settings)
|
|
54
|
-
|
|
55
|
-
def create_pickup_request(
|
|
56
|
-
self, payload: models.PickupRequest
|
|
57
|
-
) -> lib.Serializable:
|
|
58
|
-
return provider.pickup_request(payload, self.settings)
|
|
59
|
-
|
|
60
|
-
def create_cancel_pickup_request(
|
|
61
|
-
self, payload: models.PickupCancelRequest
|
|
62
|
-
) -> lib.Serializable:
|
|
63
|
-
return provider.cancel_pickup_request(payload, self.settings)
|
|
64
|
-
|
|
65
|
-
def parse_pickup_response(
|
|
66
|
-
self, response: lib.Deserializable[str]
|
|
67
|
-
) -> typing.Tuple[models.PickupDetails, typing.List[models.Message]]:
|
|
68
|
-
return provider.parse_pickup_response(response, self.settings)
|
|
69
|
-
|
|
70
|
-
def parse_cancel_pickup_response(
|
|
71
|
-
self, response: lib.Deserializable[str]
|
|
72
|
-
) -> typing.Tuple[models.ConfirmationDetails, typing.List[models.Message]]:
|
|
73
|
-
return provider.parse_cancel_pickup_response(response, self.settings)
|
|
74
|
-
|
|
75
|
-
def create_manifest_request(
|
|
76
|
-
self, payload: models.ManifestRequest
|
|
77
|
-
) -> lib.Serializable:
|
|
78
|
-
return provider.manifest_request(payload, self.settings)
|
|
79
|
-
|
|
80
|
-
def parse_manifest_response(
|
|
81
|
-
self, response: lib.Deserializable[str]
|
|
82
|
-
) -> typing.Tuple[models.ManifestDetails, typing.List[models.Message]]:
|
|
83
|
-
return provider.parse_manifest_response(response, self.settings)
|
|
84
|
-
|
|
85
|
-
def create_duties_calculation_request(
|
|
86
|
-
self, payload: models.DutiesCalculationRequest
|
|
87
|
-
) -> lib.Serializable:
|
|
88
|
-
return provider.duties_calculation_request(payload, self.settings)
|
|
89
|
-
|
|
90
|
-
def parse_duties_calculation_response(
|
|
91
|
-
self, response: lib.Deserializable[str]
|
|
92
|
-
) -> typing.Tuple[models.DutiesCalculationDetails, typing.List[models.Message]]:
|
|
93
|
-
return provider.parse_duties_calculation_response(response, self.settings)
|
|
94
|
-
|
|
95
|
-
def create_webhook_registration_request(
|
|
96
|
-
self, payload: models.WebhookRegistrationRequest
|
|
97
|
-
) -> lib.Serializable:
|
|
98
|
-
return provider.webhook_registration_request(payload, self.settings)
|
|
99
|
-
|
|
100
|
-
def parse_webhook_registration_response(
|
|
101
|
-
self, response: lib.Deserializable[str]
|
|
102
|
-
) -> typing.Tuple[models.WebhookRegistrationDetails, typing.List[models.Message]]:
|
|
103
|
-
return provider.parse_webhook_registration_response(response, self.settings)
|
|
104
|
-
|
|
105
|
-
def create_webhook_deregistration_request(
|
|
106
|
-
self, payload: models.WebhookDeregistrationRequest
|
|
107
|
-
) -> lib.Serializable:
|
|
108
|
-
return provider.webhook_deregistration_request(payload, self.settings)
|
|
109
|
-
|
|
110
|
-
def parse_webhook_deregistration_response(
|
|
111
|
-
self, response: lib.Deserializable[str]
|
|
112
|
-
) -> typing.Tuple[models.ConfirmationDetails, typing.List[models.Message]]:
|
|
113
|
-
return provider.parse_webhook_deregistration_response(response, self.settings)
|
|
114
54
|
|
karrio/mappers/teleship/proxy.py
CHANGED
|
@@ -1,131 +1,77 @@
|
|
|
1
1
|
"""Karrio Teleship client proxy."""
|
|
2
2
|
|
|
3
|
-
import datetime
|
|
4
3
|
import karrio.lib as lib
|
|
5
4
|
import karrio.api.proxy as proxy
|
|
6
|
-
import karrio.core.errors as errors
|
|
7
|
-
import karrio.core.models as models
|
|
8
|
-
import karrio.providers.teleship.error as provider_error
|
|
9
5
|
import karrio.mappers.teleship.settings as provider_settings
|
|
10
6
|
|
|
11
7
|
|
|
12
8
|
class Proxy(proxy.Proxy):
|
|
13
9
|
settings: provider_settings.Settings
|
|
14
10
|
|
|
15
|
-
def authenticate(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
16
|
-
"""Retrieve access token using thread-safe token manager.
|
|
17
|
-
|
|
18
|
-
Returns the cached token if available and not expired,
|
|
19
|
-
otherwise fetches a new token from the OAuth endpoint.
|
|
20
|
-
"""
|
|
21
|
-
cache_key = f"{self.settings.carrier_name}|{self.settings.client_id}|{self.settings.client_secret}"
|
|
22
|
-
|
|
23
|
-
def get_token():
|
|
24
|
-
response = lib.request(
|
|
25
|
-
url=f"{self.settings.server_url}/oauth/token",
|
|
26
|
-
method="POST",
|
|
27
|
-
headers={"content-Type": "application/x-www-form-urlencoded"},
|
|
28
|
-
data=lib.to_query_string(
|
|
29
|
-
dict(
|
|
30
|
-
grant_type="client_credentials",
|
|
31
|
-
clientId=self.settings.client_id,
|
|
32
|
-
clientSecret=self.settings.client_secret,
|
|
33
|
-
)
|
|
34
|
-
),
|
|
35
|
-
decoder=lib.to_dict,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
messages = provider_error.parse_error_response(response, self.settings)
|
|
39
|
-
|
|
40
|
-
if any(messages):
|
|
41
|
-
raise errors.ParsedMessagesError(messages)
|
|
42
|
-
|
|
43
|
-
expiry = datetime.datetime.now() + datetime.timedelta(
|
|
44
|
-
seconds=float(response.get("expiresIn", 0))
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
return {**response, "expiry": lib.fdatetime(expiry)}
|
|
48
|
-
|
|
49
|
-
token = self.settings.connection_cache.thread_safe(
|
|
50
|
-
refresh_func=get_token,
|
|
51
|
-
cache_key=cache_key,
|
|
52
|
-
buffer_minutes=30,
|
|
53
|
-
token_field="accessToken",
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
return lib.Deserializable(token.get_state())
|
|
57
|
-
|
|
58
11
|
def get_rates(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
),
|
|
72
|
-
request.serialize(),
|
|
12
|
+
response = lib.request(
|
|
13
|
+
url=f"{self.settings.server_url}/api/rates/quotes",
|
|
14
|
+
data=lib.to_json(request.serialize()),
|
|
15
|
+
trace=self.trace_as("json"),
|
|
16
|
+
method="POST",
|
|
17
|
+
headers={
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
"Authorization": f"Bearer {self.settings.access_token}",
|
|
20
|
+
**({
|
|
21
|
+
"x-account-id": self.settings.connection_config.account_id.state
|
|
22
|
+
} if self.settings.connection_config.account_id.state else {}),
|
|
23
|
+
},
|
|
73
24
|
)
|
|
74
25
|
|
|
75
|
-
return lib.Deserializable(
|
|
76
|
-
responses,
|
|
77
|
-
lambda __: [lib.to_dict(_) for _ in __],
|
|
78
|
-
)
|
|
26
|
+
return lib.Deserializable(response, lib.to_dict)
|
|
79
27
|
|
|
80
28
|
def create_shipment(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
),
|
|
94
|
-
request.serialize(),
|
|
29
|
+
response = lib.request(
|
|
30
|
+
url=f"{self.settings.server_url}/api/shipments/labels",
|
|
31
|
+
data=lib.to_json(request.serialize()),
|
|
32
|
+
trace=self.trace_as("json"),
|
|
33
|
+
method="POST",
|
|
34
|
+
headers={
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
"Authorization": f"Bearer {self.settings.access_token}",
|
|
37
|
+
**({
|
|
38
|
+
"x-account-id": self.settings.connection_config.account_id.state
|
|
39
|
+
} if self.settings.connection_config.account_id.state else {}),
|
|
40
|
+
},
|
|
95
41
|
)
|
|
96
42
|
|
|
97
|
-
return lib.Deserializable(
|
|
98
|
-
responses,
|
|
99
|
-
lambda __: [lib.to_dict(_) for _ in __],
|
|
100
|
-
)
|
|
43
|
+
return lib.Deserializable(response, lib.to_dict)
|
|
101
44
|
|
|
102
|
-
def cancel_shipment(
|
|
103
|
-
|
|
45
|
+
def cancel_shipment(
|
|
46
|
+
self, request: lib.Serializable
|
|
47
|
+
) -> lib.Deserializable[str]:
|
|
104
48
|
shipment_id = request.serialize().get("shipmentId")
|
|
105
49
|
|
|
106
50
|
response = lib.request(
|
|
107
51
|
url=f"{self.settings.server_url}/api/shipments/labels/{shipment_id}/void",
|
|
108
52
|
trace=self.trace_as("json"),
|
|
109
|
-
method="
|
|
53
|
+
method="DELETE",
|
|
110
54
|
headers={
|
|
111
|
-
"
|
|
112
|
-
|
|
55
|
+
"Authorization": f"Bearer {self.settings.access_token}",
|
|
56
|
+
**({
|
|
57
|
+
"x-account-id": self.settings.connection_config.account_id.state
|
|
58
|
+
} if self.settings.connection_config.account_id.state else {}),
|
|
113
59
|
},
|
|
114
60
|
)
|
|
115
61
|
|
|
116
62
|
return lib.Deserializable(response, lib.to_dict)
|
|
117
63
|
|
|
118
64
|
def get_tracking(self, request: lib.Serializable) -> lib.Deserializable:
|
|
119
|
-
access_token = self.authenticate(request).deserialize()
|
|
120
|
-
|
|
121
65
|
def _get_tracking(tracking_number: str):
|
|
122
66
|
return tracking_number, lib.request(
|
|
123
67
|
url=f"{self.settings.server_url}/api/tracking/{tracking_number}",
|
|
124
68
|
trace=self.trace_as("json"),
|
|
125
69
|
method="GET",
|
|
126
70
|
headers={
|
|
127
|
-
"
|
|
128
|
-
|
|
71
|
+
"Authorization": f"Bearer {self.settings.access_token}",
|
|
72
|
+
**({
|
|
73
|
+
"x-account-id": self.settings.connection_config.account_id.state
|
|
74
|
+
} if self.settings.connection_config.account_id.state else {}),
|
|
129
75
|
},
|
|
130
76
|
)
|
|
131
77
|
|
|
@@ -138,102 +84,3 @@ class Proxy(proxy.Proxy):
|
|
|
138
84
|
(num, lib.to_dict(track)) for num, track in res if any(track.strip())
|
|
139
85
|
],
|
|
140
86
|
)
|
|
141
|
-
|
|
142
|
-
def schedule_pickup(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
143
|
-
access_token = self.authenticate(request).deserialize()
|
|
144
|
-
|
|
145
|
-
response = lib.request(
|
|
146
|
-
url=f"{self.settings.server_url}/api/pickups",
|
|
147
|
-
data=lib.to_json(request.serialize()),
|
|
148
|
-
trace=self.trace_as("json"),
|
|
149
|
-
method="POST",
|
|
150
|
-
headers={
|
|
151
|
-
"Content-Type": "application/json",
|
|
152
|
-
"Authorization": f"Bearer {access_token}",
|
|
153
|
-
},
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
return lib.Deserializable(response, lib.to_dict)
|
|
157
|
-
|
|
158
|
-
def cancel_pickup(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
159
|
-
access_token = self.authenticate(request).deserialize()
|
|
160
|
-
pickup_id = request.serialize().get("pickupId")
|
|
161
|
-
|
|
162
|
-
response = lib.request(
|
|
163
|
-
url=f"{self.settings.server_url}/api/pickups/{pickup_id}/cancel",
|
|
164
|
-
trace=self.trace_as("json"),
|
|
165
|
-
method="POST",
|
|
166
|
-
headers={
|
|
167
|
-
"Content-Type": "application/json",
|
|
168
|
-
"Authorization": f"Bearer {access_token}",
|
|
169
|
-
},
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
return lib.Deserializable(response, lib.to_dict)
|
|
173
|
-
|
|
174
|
-
def create_manifest(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
175
|
-
access_token = self.authenticate(request).deserialize()
|
|
176
|
-
|
|
177
|
-
response = lib.request(
|
|
178
|
-
url=f"{self.settings.server_url}/api/manifests",
|
|
179
|
-
data=lib.to_json(request.serialize()),
|
|
180
|
-
trace=self.trace_as("json"),
|
|
181
|
-
method="POST",
|
|
182
|
-
headers={
|
|
183
|
-
"Content-Type": "application/json",
|
|
184
|
-
"Authorization": f"Bearer {access_token}",
|
|
185
|
-
},
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
return lib.Deserializable(response, lib.to_dict)
|
|
189
|
-
|
|
190
|
-
def calculate_duties(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
191
|
-
access_token = self.authenticate(request).deserialize()
|
|
192
|
-
|
|
193
|
-
response = lib.request(
|
|
194
|
-
url=f"{self.settings.server_url}/api/trade-engine/duties-taxes",
|
|
195
|
-
data=lib.to_json(request.serialize()),
|
|
196
|
-
trace=self.trace_as("json"),
|
|
197
|
-
method="POST",
|
|
198
|
-
headers={
|
|
199
|
-
"Content-Type": "application/json",
|
|
200
|
-
"Authorization": f"Bearer {access_token}",
|
|
201
|
-
},
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
return lib.Deserializable(response, lib.to_dict)
|
|
205
|
-
|
|
206
|
-
def register_webhook(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
207
|
-
access_token = self.authenticate(request).deserialize()
|
|
208
|
-
|
|
209
|
-
response = lib.request(
|
|
210
|
-
url=f"{self.settings.server_url}/api/webhooks",
|
|
211
|
-
data=lib.to_json(request.serialize()),
|
|
212
|
-
trace=self.trace_as("json"),
|
|
213
|
-
method="POST",
|
|
214
|
-
headers={
|
|
215
|
-
"Content-Type": "application/json",
|
|
216
|
-
"Authorization": f"Bearer {access_token}",
|
|
217
|
-
},
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
return lib.Deserializable(response, lib.to_dict)
|
|
221
|
-
|
|
222
|
-
def deregister_webhook(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
|
223
|
-
access_token = self.authenticate(request).deserialize()
|
|
224
|
-
webhook_id = request.serialize().get("webhookId")
|
|
225
|
-
|
|
226
|
-
response = lib.request(
|
|
227
|
-
url=f"{self.settings.server_url}/api/webhooks/{webhook_id}",
|
|
228
|
-
trace=self.trace_as("json"),
|
|
229
|
-
method="DELETE",
|
|
230
|
-
headers={
|
|
231
|
-
"Authorization": f"Bearer {access_token}",
|
|
232
|
-
},
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
# DELETE returns 204 No Content on success - handle empty response
|
|
236
|
-
return lib.Deserializable(
|
|
237
|
-
response,
|
|
238
|
-
lambda r: lib.to_dict(r) if r and r.strip() else {},
|
|
239
|
-
)
|
|
@@ -3,7 +3,6 @@ from karrio.core.metadata import PluginMetadata
|
|
|
3
3
|
from karrio.mappers.teleship.mapper import Mapper
|
|
4
4
|
from karrio.mappers.teleship.proxy import Proxy
|
|
5
5
|
from karrio.mappers.teleship.settings import Settings
|
|
6
|
-
from karrio.mappers.teleship.hooks import Hooks
|
|
7
6
|
import karrio.providers.teleship.units as units
|
|
8
7
|
import karrio.providers.teleship.utils as utils
|
|
9
8
|
|
|
@@ -19,13 +18,11 @@ METADATA = PluginMetadata(
|
|
|
19
18
|
Mapper=Mapper,
|
|
20
19
|
Proxy=Proxy,
|
|
21
20
|
Settings=Settings,
|
|
22
|
-
Hooks=Hooks,
|
|
23
21
|
# Data Units
|
|
24
22
|
is_hub=False,
|
|
25
23
|
options=units.ShippingOption,
|
|
26
24
|
services=units.ShippingService,
|
|
27
|
-
connection_configs=
|
|
28
|
-
system_config=units.SYSTEM_CONFIG,
|
|
25
|
+
connection_configs=utils.ConnectionConfig,
|
|
29
26
|
# Extra info
|
|
30
27
|
website="https://www.teleship.com",
|
|
31
28
|
documentation="https://developers.teleship.com",
|
|
@@ -13,29 +13,4 @@ from karrio.providers.teleship.shipment import (
|
|
|
13
13
|
from karrio.providers.teleship.tracking import (
|
|
14
14
|
parse_tracking_response,
|
|
15
15
|
tracking_request,
|
|
16
|
-
)
|
|
17
|
-
from karrio.providers.teleship.pickup import (
|
|
18
|
-
pickup_request,
|
|
19
|
-
parse_pickup_response,
|
|
20
|
-
cancel_pickup_request,
|
|
21
|
-
parse_cancel_pickup_response,
|
|
22
|
-
)
|
|
23
|
-
from karrio.providers.teleship.manifest import (
|
|
24
|
-
manifest_request,
|
|
25
|
-
parse_manifest_response,
|
|
26
|
-
)
|
|
27
|
-
from karrio.providers.teleship.duties import (
|
|
28
|
-
duties_calculation_request,
|
|
29
|
-
parse_duties_calculation_response,
|
|
30
|
-
)
|
|
31
|
-
from karrio.providers.teleship.webhook import (
|
|
32
|
-
webhook_registration_request,
|
|
33
|
-
parse_webhook_registration_response,
|
|
34
|
-
webhook_deregistration_request,
|
|
35
|
-
parse_webhook_deregistration_response,
|
|
36
|
-
)
|
|
37
|
-
from karrio.providers.teleship.hooks import (
|
|
38
|
-
on_webhook_event,
|
|
39
|
-
on_oauth_authorize,
|
|
40
|
-
on_oauth_callback,
|
|
41
16
|
)
|