karrio-server-core 2025.5rc10__py3-none-any.whl → 2025.5rc12__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/server/core/gateway.py +24 -8
- karrio/server/core/models/entity.py +3 -1
- karrio/server/core/serializers.py +12 -11
- karrio/server/core/validators.py +15 -11
- karrio/server/serializers/abstract.py +1 -0
- {karrio_server_core-2025.5rc10.dist-info → karrio_server_core-2025.5rc12.dist-info}/METADATA +1 -1
- {karrio_server_core-2025.5rc10.dist-info → karrio_server_core-2025.5rc12.dist-info}/RECORD +9 -9
- {karrio_server_core-2025.5rc10.dist-info → karrio_server_core-2025.5rc12.dist-info}/WHEEL +0 -0
- {karrio_server_core-2025.5rc10.dist-info → karrio_server_core-2025.5rc12.dist-info}/top_level.txt +0 -0
karrio/server/core/gateway.py
CHANGED
|
@@ -174,9 +174,7 @@ class Shipments:
|
|
|
174
174
|
|
|
175
175
|
# The request is wrapped in utils.identity to simplify mocking in tests.
|
|
176
176
|
shipment, messages = utils.identity(
|
|
177
|
-
lambda: karrio.Shipment.create(request)
|
|
178
|
-
.from_(carrier.gateway)
|
|
179
|
-
.parse()
|
|
177
|
+
lambda: karrio.Shipment.create(request).from_(carrier.gateway).parse()
|
|
180
178
|
)
|
|
181
179
|
|
|
182
180
|
if shipment is None:
|
|
@@ -202,19 +200,35 @@ class Shipments:
|
|
|
202
200
|
}
|
|
203
201
|
|
|
204
202
|
def process_selected_rate() -> dict:
|
|
203
|
+
estimated_delivery = lib.failsafe(
|
|
204
|
+
lambda: (
|
|
205
|
+
getattr(shipment.selected_rate, "estimated_delivery", None)
|
|
206
|
+
or getattr(selected_rate, "estimated_delivery", None)
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
transit_days = lib.failsafe(
|
|
210
|
+
lambda: (
|
|
211
|
+
getattr(shipment.selected_rate, "transit_days", None)
|
|
212
|
+
or getattr(selected_rate, "transit_days", None)
|
|
213
|
+
)
|
|
214
|
+
)
|
|
205
215
|
rate = lib.identity(
|
|
206
216
|
{
|
|
207
217
|
**lib.to_dict(shipment.selected_rate),
|
|
208
218
|
"id": f"rat_{uuid.uuid4().hex}",
|
|
209
219
|
"test_mode": carrier.test_mode,
|
|
220
|
+
"estimated_delivery": estimated_delivery,
|
|
221
|
+
"transit_days": transit_days,
|
|
210
222
|
}
|
|
211
223
|
if shipment.selected_rate is not None
|
|
212
224
|
else lib.to_dict(selected_rate)
|
|
213
225
|
)
|
|
214
|
-
return lib.to_dict(
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
226
|
+
return lib.to_dict(
|
|
227
|
+
{
|
|
228
|
+
**rate,
|
|
229
|
+
"meta": process_meta(shipment.selected_rate or selected_rate),
|
|
230
|
+
}
|
|
231
|
+
)
|
|
218
232
|
|
|
219
233
|
def process_tracking_url(rate: datatypes.Rate) -> str:
|
|
220
234
|
rate_provider = (rate.get("meta") or {}).get("rate_provider")
|
|
@@ -263,7 +277,9 @@ class Shipments:
|
|
|
263
277
|
"parcels": process_parcel_refs(payload["parcels"]),
|
|
264
278
|
"tracking_url": process_tracking_url(shipment_rate),
|
|
265
279
|
"status": serializers.ShipmentStatus.purchased.value,
|
|
266
|
-
"created_at": datetime.datetime.now().strftime(
|
|
280
|
+
"created_at": datetime.datetime.now().strftime(
|
|
281
|
+
"%Y-%m-%d %H:%M:%S.%f%z"
|
|
282
|
+
),
|
|
267
283
|
"meta": process_meta(shipment),
|
|
268
284
|
"messages": messages,
|
|
269
285
|
},
|
|
@@ -12,7 +12,9 @@ class Entity(models.Model):
|
|
|
12
12
|
updated_at = models.DateTimeField(auto_now=True)
|
|
13
13
|
|
|
14
14
|
def __str__(self):
|
|
15
|
-
return
|
|
15
|
+
return (
|
|
16
|
+
str(self.id) if self.id is not None else f"{self.__class__.__name__}(None)"
|
|
17
|
+
)
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
class OwnedEntity(ControlledAccessModel, Entity):
|
|
@@ -88,6 +88,7 @@ class CarrierDetails(serializers.Serializer):
|
|
|
88
88
|
help_text="The carrier shipping options.",
|
|
89
89
|
)
|
|
90
90
|
|
|
91
|
+
|
|
91
92
|
class CarrierSettings(serializers.Serializer):
|
|
92
93
|
id = serializers.CharField(required=True, help_text="A unique address identifier")
|
|
93
94
|
object_type = serializers.CharField(
|
|
@@ -161,7 +162,7 @@ class AddressData(validators.AugmentedAddressSerializer):
|
|
|
161
162
|
required=False,
|
|
162
163
|
allow_blank=True,
|
|
163
164
|
allow_null=True,
|
|
164
|
-
max_length=
|
|
165
|
+
max_length=50,
|
|
165
166
|
help_text="""The address city.
|
|
166
167
|
**(required for shipment purchase)**
|
|
167
168
|
""",
|
|
@@ -170,21 +171,21 @@ class AddressData(validators.AugmentedAddressSerializer):
|
|
|
170
171
|
required=False,
|
|
171
172
|
allow_blank=True,
|
|
172
173
|
allow_null=True,
|
|
173
|
-
max_length=
|
|
174
|
+
max_length=50,
|
|
174
175
|
help_text="The party frederal tax id",
|
|
175
176
|
)
|
|
176
177
|
state_tax_id = serializers.CharField(
|
|
177
178
|
required=False,
|
|
178
179
|
allow_blank=True,
|
|
179
180
|
allow_null=True,
|
|
180
|
-
max_length=
|
|
181
|
+
max_length=50,
|
|
181
182
|
help_text="The party state id",
|
|
182
183
|
)
|
|
183
184
|
person_name = serializers.CharField(
|
|
184
185
|
required=False,
|
|
185
186
|
allow_blank=True,
|
|
186
187
|
allow_null=True,
|
|
187
|
-
max_length=
|
|
188
|
+
max_length=100,
|
|
188
189
|
help_text="""Attention to
|
|
189
190
|
**(required for shipment purchase)**
|
|
190
191
|
""",
|
|
@@ -193,7 +194,7 @@ class AddressData(validators.AugmentedAddressSerializer):
|
|
|
193
194
|
required=False,
|
|
194
195
|
allow_blank=True,
|
|
195
196
|
allow_null=True,
|
|
196
|
-
max_length=
|
|
197
|
+
max_length=100,
|
|
197
198
|
help_text="The company name if the party is a company",
|
|
198
199
|
)
|
|
199
200
|
country_code = serializers.ChoiceField(
|
|
@@ -208,14 +209,14 @@ class AddressData(validators.AugmentedAddressSerializer):
|
|
|
208
209
|
required=False,
|
|
209
210
|
allow_blank=True,
|
|
210
211
|
allow_null=True,
|
|
211
|
-
max_length=
|
|
212
|
+
max_length=50,
|
|
212
213
|
help_text="The party phone number.",
|
|
213
214
|
)
|
|
214
215
|
state_code = serializers.CharField(
|
|
215
216
|
required=False,
|
|
216
217
|
allow_blank=True,
|
|
217
218
|
allow_null=True,
|
|
218
|
-
max_length=
|
|
219
|
+
max_length=50,
|
|
219
220
|
help_text="The address state code",
|
|
220
221
|
)
|
|
221
222
|
residential = serializers.BooleanField(
|
|
@@ -229,14 +230,14 @@ class AddressData(validators.AugmentedAddressSerializer):
|
|
|
229
230
|
required=False,
|
|
230
231
|
allow_blank=True,
|
|
231
232
|
allow_null=True,
|
|
232
|
-
max_length=
|
|
233
|
+
max_length=100,
|
|
233
234
|
help_text="""The address street number""",
|
|
234
235
|
)
|
|
235
236
|
address_line1 = serializers.CharField(
|
|
236
237
|
required=False,
|
|
237
238
|
allow_blank=True,
|
|
238
239
|
allow_null=True,
|
|
239
|
-
max_length=
|
|
240
|
+
max_length=100,
|
|
240
241
|
help_text="""The address line with street number <br/>
|
|
241
242
|
**(required for shipment purchase)**
|
|
242
243
|
""",
|
|
@@ -245,7 +246,7 @@ class AddressData(validators.AugmentedAddressSerializer):
|
|
|
245
246
|
required=False,
|
|
246
247
|
allow_blank=True,
|
|
247
248
|
allow_null=True,
|
|
248
|
-
max_length=
|
|
249
|
+
max_length=100,
|
|
249
250
|
help_text="The address line with suite number",
|
|
250
251
|
)
|
|
251
252
|
validate_location = serializers.BooleanField(
|
|
@@ -915,7 +916,7 @@ class PickupUpdateRequest(serializers.Serializer):
|
|
|
915
916
|
)
|
|
916
917
|
ready_time = serializers.CharField(
|
|
917
918
|
required=True,
|
|
918
|
-
validators=[
|
|
919
|
+
validators=[validators.valid_time_format("ready_time")],
|
|
919
920
|
help_text="""The ready time for pickup.
|
|
920
921
|
Time Format: `HH:MM`
|
|
921
922
|
""",
|
karrio/server/core/validators.py
CHANGED
|
@@ -313,6 +313,7 @@ class Address:
|
|
|
313
313
|
try:
|
|
314
314
|
# Import the validator module dynamically
|
|
315
315
|
import importlib
|
|
316
|
+
|
|
316
317
|
module = importlib.import_module(f"karrio.validators.{validator_name}")
|
|
317
318
|
if hasattr(module, "METADATA"):
|
|
318
319
|
validator_class = module.METADATA.Validator
|
|
@@ -355,9 +356,11 @@ class Address:
|
|
|
355
356
|
# For backwards compatibility, check if Google or Canada Post is configured
|
|
356
357
|
if any(config.GOOGLE_CLOUD_API_KEY or ""):
|
|
357
358
|
from karrio.validators.googlegeocoding import Validator as GoogleGeocode
|
|
359
|
+
|
|
358
360
|
return GoogleGeocode
|
|
359
361
|
elif any(config.CANADAPOST_ADDRESS_COMPLETE_API_KEY or ""):
|
|
360
362
|
from karrio.validators.addresscomplete import Validator as AddressComplete
|
|
363
|
+
|
|
361
364
|
return AddressComplete
|
|
362
365
|
|
|
363
366
|
raise Exception("No address validation service provider configured")
|
|
@@ -380,17 +383,18 @@ class Address:
|
|
|
380
383
|
refs = references.REFERENCES
|
|
381
384
|
if len(refs.get("address_validators", {})) > 0:
|
|
382
385
|
# Get the first available validator
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
386
|
+
validator_name = next(iter(refs["address_validators"].keys()))
|
|
387
|
+
|
|
388
|
+
# Try to get the validator class from the references
|
|
389
|
+
try:
|
|
390
|
+
# Import the validator module dynamically
|
|
391
|
+
import importlib
|
|
392
|
+
|
|
393
|
+
module = importlib.import_module(f"karrio.validators.{validator_name}")
|
|
394
|
+
if hasattr(module, "METADATA"):
|
|
395
|
+
return module.METADATA.Validator
|
|
396
|
+
except (ImportError, AttributeError) as e:
|
|
397
|
+
logger.warning(f"Could not import validator {validator_name}: {e}")
|
|
394
398
|
|
|
395
399
|
# Fall back to legacy validator
|
|
396
400
|
return Address._get_legacy_validator()
|
|
@@ -223,6 +223,7 @@ def link_org(entity: ModelSerializer, context: Context):
|
|
|
223
223
|
update_fields=(["created_at"] if hasattr(entity, "created_at") else [])
|
|
224
224
|
)
|
|
225
225
|
|
|
226
|
+
|
|
226
227
|
def bulk_link_org(entities: typing.List[models.Model], context: Context):
|
|
227
228
|
if len(entities) == 0 or settings.MULTI_ORGANIZATIONS is False:
|
|
228
229
|
return
|
|
@@ -11,18 +11,18 @@ karrio/server/core/dataunits.py,sha256=Mbmh6Bi9CwlxdAYLIfLlQjxCSZd_uWN0Dux-GIYTr
|
|
|
11
11
|
karrio/server/core/exceptions.py,sha256=AR4FNT_1wkMkuv_ZELB9pVRL3RRWsSJ7hrNgBP7H3EU,6038
|
|
12
12
|
karrio/server/core/fields.py,sha256=5i5eetbxFkIQ9uoFk8k2xPl1mXXnaVKlPV4xwlF3inY,345
|
|
13
13
|
karrio/server/core/filters.py,sha256=nHj742vPWE3Xs_tpwRRVUh00OwxnF22xKfIK7rx-sw4,27434
|
|
14
|
-
karrio/server/core/gateway.py,sha256=
|
|
14
|
+
karrio/server/core/gateway.py,sha256=TH3-RIxZ2BUrteyDAXWxH_GvY4pC4A_l7t-pRbLDO-M,25747
|
|
15
15
|
karrio/server/core/middleware.py,sha256=euRkeIvNv3G-b_U3fKDO6po-2dbYF0LiXUYg2nyeCI0,3017
|
|
16
16
|
karrio/server/core/oauth_validators.py,sha256=5JxDkXB_HX4a4xJltZcFGukO7o2cUl9h2t9O8Gp87Zc,6673
|
|
17
17
|
karrio/server/core/permissions.py,sha256=JY3_hTEnyDTWG-weAWPx8xMoaRZwpNL2HaSssBzjH7Y,1189
|
|
18
18
|
karrio/server/core/renderers.py,sha256=IUEUhvvrk_CeqnmnYQgWKHiH3uQhNc0eqDxyO9CuUS4,290
|
|
19
19
|
karrio/server/core/router.py,sha256=IBUR7rfBkdEHQzWxYOPcVSM8NBp3fte9G6Q5BVTUNNw,95
|
|
20
|
-
karrio/server/core/serializers.py,sha256
|
|
20
|
+
karrio/server/core/serializers.py,sha256=-wm4uQjtbR5z7qtAxJ7O2ApwzXmfFEdJkspQiVXeCj4,60074
|
|
21
21
|
karrio/server/core/signals.py,sha256=thHh4K4uP3smWuy9kWavFfdOAttH9xN3og_j4lDWdKM,1742
|
|
22
22
|
karrio/server/core/tests.py,sha256=rmZoZfPBRoMO-U3HtDxeKofnzsfijYeDVQrnw5Mb_dU,3164
|
|
23
23
|
karrio/server/core/urls.py,sha256=JQrN6dI7A7c_M498EcDKdjDqlp_d64Ov-RS4HHmssRk,337
|
|
24
24
|
karrio/server/core/utils.py,sha256=xY8aklHPtbaJsCPiKonk5HoY0FrSNseS859RZEQJ9mU,14022
|
|
25
|
-
karrio/server/core/validators.py,sha256=
|
|
25
|
+
karrio/server/core/validators.py,sha256=3XwjJurJJM6jKwNcZRUyr7j1k8DuOnhct1_1N9ildFg,13934
|
|
26
26
|
karrio/server/core/management/commands/cli.py,sha256=EEIbFHZTroJoUxSOKnebsXtXTbsc408t5b9qSc0QRqk,720
|
|
27
27
|
karrio/server/core/management/commands/create_oauth_client.py,sha256=wdxCeHuUtGpwgV0WItJkW8Di65y9krnFYNEmcgh9x2k,1718
|
|
28
28
|
karrio/server/core/migrations/0001_initial.py,sha256=8c-JMkt84Z5C1Zgm2jw4NiI6tYSK4OLcB-uhxiEDN98,701
|
|
@@ -33,7 +33,7 @@ karrio/server/core/migrations/0005_alter_metafield_type_alter_metafield_value.py
|
|
|
33
33
|
karrio/server/core/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
karrio/server/core/models/__init__.py,sha256=iw1pwHhXpWru5AnLimWzH3mouad9-GTrYTWsmZOC6hU,1176
|
|
35
35
|
karrio/server/core/models/base.py,sha256=pRdm0GIOdGZCrxj-U6cZGTFp4KJuOQhCGtiZNJF1qiE,1785
|
|
36
|
-
karrio/server/core/models/entity.py,sha256=
|
|
36
|
+
karrio/server/core/models/entity.py,sha256=cUSIzv84RIPif2DdNSScY7RHuHgXufwIF8YNZ8BYC1g,722
|
|
37
37
|
karrio/server/core/models/metafield.py,sha256=etzJ1BS98Ipe3mxJuDOK3-c36Z2oZKgnPaHQmYta2Dw,5048
|
|
38
38
|
karrio/server/core/models/third_party.py,sha256=iNXvcq0pJN2gFu5Bu03k6FMdQNxEhzoijIhl4lc7JmU,552
|
|
39
39
|
karrio/server/core/views/__init__.py,sha256=jvhomX2_aiPcfdUjq7_kzp5rOerLwScnbRNDqs751Zo,88
|
|
@@ -201,7 +201,7 @@ karrio/server/providers/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
201
201
|
karrio/server/providers/views/carriers.py,sha256=_uD_soDZDmMxzfu8mQqeLLcDd4ixnE7f8HjoUlybym8,8808
|
|
202
202
|
karrio/server/providers/views/connections.py,sha256=3Y1rfNsZxkn4YBA03WRQiI-y-AC4EYaOGaMjLmCcz1g,6038
|
|
203
203
|
karrio/server/serializers/__init__.py,sha256=TzD3Lt8Gf7VV5ibGITGg5-ki-M8CR0hzZFulcI2ASJM,90
|
|
204
|
-
karrio/server/serializers/abstract.py,sha256=
|
|
204
|
+
karrio/server/serializers/abstract.py,sha256=WS4ey0W_NIMGl-5a2rpaZPdU9bKJmfDSpyHNs81PsGo,15583
|
|
205
205
|
karrio/server/tracing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
206
206
|
karrio/server/tracing/admin.py,sha256=6BZCJiBhJVg3vt8cYx9HF_FgcjanMD42la6bBORlSL8,1904
|
|
207
207
|
karrio/server/tracing/apps.py,sha256=6BfIomUwBV8k7yaypl6kYYAkLSG1aceUmuxvbhw04fI,247
|
|
@@ -235,7 +235,7 @@ karrio/server/user/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
235
235
|
karrio/server/user/templates/registration/login.html,sha256=3_tj-0rKfwkCk-fp_GT8xFQhLqjGcJs3uZzOAaI40Sw,3690
|
|
236
236
|
karrio/server/user/templates/registration/registration_confirm_email.html,sha256=zFDkNN_BHMQyrBv_mU8aoqXxYxG91TGuf6pKwRa5jxE,247
|
|
237
237
|
karrio/server/user/templates/registration/registration_confirm_email.txt,sha256=I_zN_pJTRigfyiYbyQK0wFfrI5Zq1JG8lf0TyLA9fN0,94
|
|
238
|
-
karrio_server_core-2025.
|
|
239
|
-
karrio_server_core-2025.
|
|
240
|
-
karrio_server_core-2025.
|
|
241
|
-
karrio_server_core-2025.
|
|
238
|
+
karrio_server_core-2025.5rc12.dist-info/METADATA,sha256=mUiD-2FjXZNzxvJy-7eXCtYoIWjUCN2ra_z07f5E7Uc,797
|
|
239
|
+
karrio_server_core-2025.5rc12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
240
|
+
karrio_server_core-2025.5rc12.dist-info/top_level.txt,sha256=D1D7x8R3cTfjF_15mfiO7wCQ5QMtuM4x8GaPr7z5i78,12
|
|
241
|
+
karrio_server_core-2025.5rc12.dist-info/RECORD,,
|
|
File without changes
|
{karrio_server_core-2025.5rc10.dist-info → karrio_server_core-2025.5rc12.dist-info}/top_level.txt
RENAMED
|
File without changes
|