karrio-server-core 2025.5rc12__py3-none-any.whl → 2026.1.1__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/authentication.py +59 -25
- karrio/server/core/config.py +31 -0
- karrio/server/core/datatypes.py +30 -4
- karrio/server/core/dataunits.py +53 -22
- karrio/server/core/exceptions.py +287 -17
- karrio/server/core/filters.py +14 -0
- karrio/server/core/gateway.py +285 -10
- karrio/server/core/logging.py +403 -0
- karrio/server/core/management/commands/runserver.py +5 -0
- karrio/server/core/middleware.py +104 -2
- karrio/server/core/migrations/0006_add_api_log_requested_at_index.py +22 -0
- karrio/server/core/models/base.py +34 -1
- karrio/server/core/oauth_validators.py +2 -3
- karrio/server/core/permissions.py +1 -2
- karrio/server/core/serializers.py +183 -10
- karrio/server/core/signals.py +22 -28
- karrio/server/core/telemetry.py +573 -0
- karrio/server/core/tests/__init__.py +27 -0
- karrio/server/core/{tests.py → tests/base.py} +6 -7
- karrio/server/core/tests/test_exception_level.py +159 -0
- karrio/server/core/tests/test_resource_token.py +593 -0
- karrio/server/core/utils.py +688 -38
- karrio/server/core/validators.py +144 -222
- karrio/server/core/views/oauth.py +13 -12
- karrio/server/core/views/references.py +2 -2
- karrio/server/iam/apps.py +1 -4
- karrio/server/iam/migrations/0002_setup_carrier_permission_groups.py +103 -0
- karrio/server/iam/migrations/0003_remove_permission_groups.py +91 -0
- karrio/server/iam/permissions.py +7 -134
- karrio/server/iam/serializers.py +17 -2
- karrio/server/iam/signals.py +2 -4
- karrio/server/providers/admin.py +1 -1
- karrio/server/providers/management/commands/migrate_rate_sheets.py +101 -0
- karrio/server/providers/migrations/0082_add_zone_identifiers.py +50 -0
- karrio/server/providers/migrations/0083_add_optimized_rate_sheet_structure.py +33 -0
- karrio/server/providers/migrations/0084_alter_servicelevel_currency.py +168 -0
- karrio/server/providers/migrations/0085_populate_dhl_parcel_de_oauth_credentials.py +82 -0
- karrio/server/providers/migrations/0086_rename_dhl_parcel_de_customer_number_to_billing_number.py +71 -0
- karrio/server/providers/migrations/0087_alter_carrier_capabilities.py +38 -0
- karrio/server/providers/migrations/0088_servicelevel_surcharges.py +24 -0
- karrio/server/providers/migrations/0089_servicelevel_cost_max_volume.py +31 -0
- karrio/server/providers/migrations/0090_ratesheet_surcharges_servicelevel_zone_surcharge_ids.py +47 -0
- karrio/server/providers/migrations/0091_migrate_legacy_zones_surcharges.py +154 -0
- karrio/server/providers/models/__init__.py +1 -2
- karrio/server/providers/models/carrier.py +103 -18
- karrio/server/providers/models/service.py +188 -1
- karrio/server/providers/models/sheet.py +371 -0
- karrio/server/providers/serializers/base.py +263 -2
- karrio/server/providers/signals.py +2 -4
- karrio/server/providers/templates/providers/oauth_callback.html +105 -0
- karrio/server/providers/tests/__init__.py +5 -0
- karrio/server/providers/tests/test_connections.py +895 -0
- karrio/server/providers/views/carriers.py +1 -3
- karrio/server/providers/views/connections.py +322 -2
- karrio/server/samples.py +1 -1
- karrio/server/serializers/abstract.py +116 -21
- karrio/server/tracing/migrations/0007_tracingrecord_tracing_created_at_idx.py +19 -0
- karrio/server/tracing/models.py +2 -0
- karrio/server/tracing/utils.py +5 -8
- karrio/server/user/migrations/0007_user_metadata.py +25 -0
- karrio/server/user/models.py +38 -23
- karrio/server/user/serializers.py +1 -0
- karrio/server/user/templates/registration/registration_confirm_email.html +1 -1
- {karrio_server_core-2025.5rc12.dist-info → karrio_server_core-2026.1.1.dist-info}/METADATA +2 -2
- {karrio_server_core-2025.5rc12.dist-info → karrio_server_core-2026.1.1.dist-info}/RECORD +67 -86
- karrio/server/providers/extension/__init__.py +0 -1
- karrio/server/providers/extension/models/__init__.py +0 -1
- karrio/server/providers/extension/models/allied_express.py +0 -22
- karrio/server/providers/extension/models/allied_express_local.py +0 -22
- karrio/server/providers/extension/models/amazon_shipping.py +0 -27
- karrio/server/providers/extension/models/aramex.py +0 -25
- karrio/server/providers/extension/models/asendia_us.py +0 -21
- karrio/server/providers/extension/models/australiapost.py +0 -20
- karrio/server/providers/extension/models/boxknight.py +0 -19
- karrio/server/providers/extension/models/bpost.py +0 -21
- karrio/server/providers/extension/models/canadapost.py +0 -21
- karrio/server/providers/extension/models/canpar.py +0 -19
- karrio/server/providers/extension/models/chronopost.py +0 -22
- karrio/server/providers/extension/models/colissimo.py +0 -22
- karrio/server/providers/extension/models/dhl_express.py +0 -23
- karrio/server/providers/extension/models/dhl_parcel_de.py +0 -25
- karrio/server/providers/extension/models/dhl_poland.py +0 -22
- karrio/server/providers/extension/models/dhl_universal.py +0 -19
- karrio/server/providers/extension/models/dicom.py +0 -20
- karrio/server/providers/extension/models/dpd.py +0 -37
- karrio/server/providers/extension/models/dpdhl.py +0 -26
- karrio/server/providers/extension/models/easypost.py +0 -20
- karrio/server/providers/extension/models/eshipper.py +0 -21
- karrio/server/providers/extension/models/fedex.py +0 -25
- karrio/server/providers/extension/models/fedex_ws.py +0 -24
- karrio/server/providers/extension/models/freightcom.py +0 -21
- karrio/server/providers/extension/models/generic.py +0 -35
- karrio/server/providers/extension/models/geodis.py +0 -22
- karrio/server/providers/extension/models/hay_post.py +0 -22
- karrio/server/providers/extension/models/laposte.py +0 -19
- karrio/server/providers/extension/models/locate2u.py +0 -22
- karrio/server/providers/extension/models/nationex.py +0 -22
- karrio/server/providers/extension/models/purolator.py +0 -21
- karrio/server/providers/extension/models/roadie.py +0 -18
- karrio/server/providers/extension/models/royalmail.py +0 -19
- karrio/server/providers/extension/models/sendle.py +0 -22
- karrio/server/providers/extension/models/tge.py +0 -63
- karrio/server/providers/extension/models/tnt.py +0 -23
- karrio/server/providers/extension/models/ups.py +0 -23
- karrio/server/providers/extension/models/usps.py +0 -23
- karrio/server/providers/extension/models/usps_international.py +0 -23
- karrio/server/providers/extension/models/usps_wt.py +0 -24
- karrio/server/providers/extension/models/usps_wt_international.py +0 -24
- karrio/server/providers/extension/models/zoom2u.py +0 -23
- karrio/server/providers/tests.py +0 -3
- {karrio_server_core-2025.5rc12.dist-info → karrio_server_core-2026.1.1.dist-info}/WHEEL +0 -0
- {karrio_server_core-2025.5rc12.dist-info → karrio_server_core-2026.1.1.dist-info}/top_level.txt +0 -0
karrio/server/core/gateway.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
import typing
|
|
3
|
-
import logging
|
|
4
3
|
import datetime
|
|
5
4
|
|
|
6
5
|
from django.db.models import Q
|
|
7
6
|
from django.conf import settings
|
|
8
7
|
from rest_framework import status
|
|
9
8
|
from rest_framework.exceptions import NotFound
|
|
9
|
+
from karrio.server.core.logging import logger
|
|
10
10
|
|
|
11
11
|
import karrio.lib as lib
|
|
12
12
|
import karrio.sdk as karrio
|
|
@@ -14,14 +14,11 @@ import karrio.server.core.utils as utils
|
|
|
14
14
|
import karrio.server.core.models as core
|
|
15
15
|
import karrio.server.core.datatypes as datatypes
|
|
16
16
|
import karrio.server.core.dataunits as dataunits
|
|
17
|
-
import karrio.server.core.validators as validators
|
|
18
17
|
import karrio.server.core.exceptions as exceptions
|
|
19
18
|
import karrio.server.providers.models as providers
|
|
20
19
|
import karrio.server.serializers as base_serializers
|
|
21
20
|
import karrio.server.core.serializers as serializers
|
|
22
21
|
|
|
23
|
-
logger = logging.getLogger(__name__)
|
|
24
|
-
|
|
25
22
|
|
|
26
23
|
class Carriers:
|
|
27
24
|
@staticmethod
|
|
@@ -133,17 +130,36 @@ class Carriers:
|
|
|
133
130
|
|
|
134
131
|
class Address:
|
|
135
132
|
@staticmethod
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
@utils.with_telemetry("address_validate")
|
|
134
|
+
def validate(
|
|
135
|
+
payload: dict,
|
|
136
|
+
provider: providers.Carrier = None,
|
|
137
|
+
**carrier_filters,
|
|
138
|
+
) -> datatypes.AddressValidation:
|
|
139
|
+
provider = provider or Carriers.first(
|
|
140
|
+
**{
|
|
141
|
+
**dict(active=True, raise_not_found=True),
|
|
142
|
+
**carrier_filters,
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
if "validate_address" not in provider.gateway.proxy_methods:
|
|
147
|
+
raise exceptions.APIException(
|
|
148
|
+
detail=f"address validation is not supported by carrier: '{provider.carrier_id}'",
|
|
149
|
+
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
|
150
|
+
)
|
|
138
151
|
|
|
139
|
-
|
|
140
|
-
|
|
152
|
+
request = karrio.Address.validate(
|
|
153
|
+
lib.to_object(datatypes.AddressValidationRequest, payload)
|
|
154
|
+
)
|
|
141
155
|
|
|
142
|
-
|
|
156
|
+
# The request is wrapped in utils.identity to simplify mocking in tests.
|
|
157
|
+
return utils.identity(lambda: request.from_(provider.gateway).parse())
|
|
143
158
|
|
|
144
159
|
|
|
145
160
|
class Shipments:
|
|
146
161
|
@staticmethod
|
|
162
|
+
@utils.with_telemetry("shipment_create")
|
|
147
163
|
@utils.require_selected_rate
|
|
148
164
|
def create(
|
|
149
165
|
payload: dict,
|
|
@@ -167,9 +183,19 @@ class Shipments:
|
|
|
167
183
|
if carrier is None:
|
|
168
184
|
raise NotFound("No active carrier connection found to process the request")
|
|
169
185
|
|
|
186
|
+
payload = {
|
|
187
|
+
**lib.to_dict(payload),
|
|
188
|
+
"options": {
|
|
189
|
+
**(selected_rate.meta or {}),
|
|
190
|
+
**(payload.get("options") or {}),
|
|
191
|
+
},
|
|
192
|
+
}
|
|
170
193
|
request = lib.to_object(
|
|
171
194
|
datatypes.ShipmentRequest,
|
|
172
|
-
{
|
|
195
|
+
{
|
|
196
|
+
**lib.to_dict(payload),
|
|
197
|
+
"service": selected_rate.service,
|
|
198
|
+
},
|
|
173
199
|
)
|
|
174
200
|
|
|
175
201
|
# The request is wrapped in utils.identity to simplify mocking in tests.
|
|
@@ -190,6 +216,7 @@ class Shipments:
|
|
|
190
216
|
rate_provider = (
|
|
191
217
|
(parent.meta or {}).get("rate_provider") or carrier.carrier_name
|
|
192
218
|
).lower()
|
|
219
|
+
custom_carrier_name = carrier.credentials.get("custom_carrier_name")
|
|
193
220
|
|
|
194
221
|
return {
|
|
195
222
|
**(parent.meta or {}),
|
|
@@ -197,6 +224,11 @@ class Shipments:
|
|
|
197
224
|
"carrier": rate_provider,
|
|
198
225
|
"service_name": service_name,
|
|
199
226
|
"rate_provider": rate_provider, # TODO: deprecate 'rate_provider' in favor of 'carrier'
|
|
227
|
+
**(
|
|
228
|
+
{"custom_carrier_name": custom_carrier_name}
|
|
229
|
+
if custom_carrier_name
|
|
230
|
+
else {}
|
|
231
|
+
),
|
|
200
232
|
}
|
|
201
233
|
|
|
202
234
|
def process_selected_rate() -> dict:
|
|
@@ -286,6 +318,7 @@ class Shipments:
|
|
|
286
318
|
)
|
|
287
319
|
|
|
288
320
|
@staticmethod
|
|
321
|
+
@utils.with_telemetry("shipment_cancel")
|
|
289
322
|
def cancel(
|
|
290
323
|
payload: dict, carrier: providers.Carrier = None, **carrier_filters
|
|
291
324
|
) -> datatypes.ConfirmationResponse:
|
|
@@ -336,6 +369,7 @@ class Shipments:
|
|
|
336
369
|
)
|
|
337
370
|
|
|
338
371
|
@staticmethod
|
|
372
|
+
@utils.with_telemetry("tracking_fetch")
|
|
339
373
|
def track(
|
|
340
374
|
payload: dict,
|
|
341
375
|
carrier: providers.Carrier = None,
|
|
@@ -425,6 +459,7 @@ class Shipments:
|
|
|
425
459
|
|
|
426
460
|
class Pickups:
|
|
427
461
|
@staticmethod
|
|
462
|
+
@utils.with_telemetry("pickup_schedule")
|
|
428
463
|
def schedule(
|
|
429
464
|
payload: dict, carrier: providers.Carrier = None, **carrier_filters
|
|
430
465
|
) -> datatypes.PickupResponse:
|
|
@@ -474,6 +509,7 @@ class Pickups:
|
|
|
474
509
|
)
|
|
475
510
|
|
|
476
511
|
@staticmethod
|
|
512
|
+
@utils.with_telemetry("pickup_update")
|
|
477
513
|
def update(
|
|
478
514
|
payload: dict, carrier: providers.Carrier = None, **carrier_filters
|
|
479
515
|
) -> datatypes.PickupResponse:
|
|
@@ -514,6 +550,7 @@ class Pickups:
|
|
|
514
550
|
)
|
|
515
551
|
|
|
516
552
|
@staticmethod
|
|
553
|
+
@utils.with_telemetry("pickup_cancel")
|
|
517
554
|
def cancel(
|
|
518
555
|
payload: dict, carrier: providers.Carrier = None, **carrier_filters
|
|
519
556
|
) -> datatypes.ConfirmationResponse:
|
|
@@ -562,6 +599,7 @@ class Rates:
|
|
|
562
599
|
post_process_functions: typing.List[typing.Callable] = []
|
|
563
600
|
|
|
564
601
|
@staticmethod
|
|
602
|
+
@utils.with_telemetry("rates_fetch")
|
|
565
603
|
def fetch(
|
|
566
604
|
payload: dict,
|
|
567
605
|
carriers: typing.List[providers.Carrier] = None,
|
|
@@ -640,6 +678,7 @@ class Rates:
|
|
|
640
678
|
|
|
641
679
|
class Documents:
|
|
642
680
|
@staticmethod
|
|
681
|
+
@utils.with_telemetry("document_upload")
|
|
643
682
|
def upload(
|
|
644
683
|
payload: dict,
|
|
645
684
|
carrier: providers.Carrier = None,
|
|
@@ -687,6 +726,7 @@ class Documents:
|
|
|
687
726
|
|
|
688
727
|
class Manifests:
|
|
689
728
|
@staticmethod
|
|
729
|
+
@utils.with_telemetry("manifest_create")
|
|
690
730
|
def create(
|
|
691
731
|
payload: dict, carrier: providers.Carrier = None, **carrier_filters
|
|
692
732
|
) -> datatypes.ManifestResponse:
|
|
@@ -734,3 +774,238 @@ class Manifests:
|
|
|
734
774
|
),
|
|
735
775
|
messages=messages,
|
|
736
776
|
)
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
class Insurance:
|
|
780
|
+
@staticmethod
|
|
781
|
+
@utils.with_telemetry("insurance_apply")
|
|
782
|
+
def apply(
|
|
783
|
+
payload: dict, provider: providers.Carrier = None, **provider_filters
|
|
784
|
+
) -> datatypes.InsuranceDetails:
|
|
785
|
+
provider = provider or Carriers.first(
|
|
786
|
+
**{
|
|
787
|
+
**dict(active=True, raise_not_found=True),
|
|
788
|
+
**provider_filters,
|
|
789
|
+
}
|
|
790
|
+
)
|
|
791
|
+
|
|
792
|
+
if "apply_insurance" not in provider.gateway.proxy_methods:
|
|
793
|
+
raise exceptions.APIException(
|
|
794
|
+
detail=f"insurance application is not supported by carrier: '{provider.carrier_id}'",
|
|
795
|
+
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
request = karrio.Insurance.apply(
|
|
799
|
+
lib.to_object(datatypes.InsuranceRequest, payload)
|
|
800
|
+
)
|
|
801
|
+
|
|
802
|
+
# The request call is wrapped in utils.identity to simplify mocking in tests
|
|
803
|
+
insurance, messages = utils.identity(
|
|
804
|
+
lambda: request.from_(provider.gateway).parse()
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
if insurance is None:
|
|
808
|
+
raise exceptions.APIException(
|
|
809
|
+
detail=messages,
|
|
810
|
+
status_code=status.HTTP_424_FAILED_DEPENDENCY,
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
def process_meta(parent) -> dict:
|
|
814
|
+
return {
|
|
815
|
+
**(parent.meta or {}),
|
|
816
|
+
"ext": provider.ext,
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
return datatypes.InsuranceResponse(
|
|
820
|
+
insurance=datatypes.Insurance(
|
|
821
|
+
**{
|
|
822
|
+
**payload,
|
|
823
|
+
**lib.to_dict(insurance),
|
|
824
|
+
"id": f"ins_{uuid.uuid4().hex}",
|
|
825
|
+
"test_mode": provider.test_mode,
|
|
826
|
+
"meta": process_meta(insurance),
|
|
827
|
+
"messages": messages,
|
|
828
|
+
}
|
|
829
|
+
),
|
|
830
|
+
messages=messages,
|
|
831
|
+
)
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
class Duties:
|
|
835
|
+
@staticmethod
|
|
836
|
+
@utils.with_telemetry("duties_calculate")
|
|
837
|
+
def calculate(
|
|
838
|
+
payload: dict,
|
|
839
|
+
provider: providers.Carrier = None,
|
|
840
|
+
**provider_filters,
|
|
841
|
+
) -> datatypes.DutiesResponse:
|
|
842
|
+
provider = provider or Carriers.first(
|
|
843
|
+
**{
|
|
844
|
+
**dict(active=True, raise_not_found=True),
|
|
845
|
+
**provider_filters,
|
|
846
|
+
}
|
|
847
|
+
)
|
|
848
|
+
|
|
849
|
+
if "calculate_duties" not in provider.gateway.proxy_methods:
|
|
850
|
+
raise exceptions.APIException(
|
|
851
|
+
detail=f"duties calculation is not supported by carrier: '{provider.carrier_id}'",
|
|
852
|
+
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
|
853
|
+
)
|
|
854
|
+
|
|
855
|
+
request = karrio.Duty.calculate(
|
|
856
|
+
lib.to_object(datatypes.DutiesCalculationRequest, payload)
|
|
857
|
+
)
|
|
858
|
+
|
|
859
|
+
# The request is wrapped in utils.identity to simplify mocking in tests.
|
|
860
|
+
duties, messages = utils.identity(
|
|
861
|
+
lambda: request.from_(provider.gateway).parse()
|
|
862
|
+
)
|
|
863
|
+
|
|
864
|
+
if duties is None:
|
|
865
|
+
raise exceptions.APIException(
|
|
866
|
+
detail=messages,
|
|
867
|
+
status_code=status.HTTP_424_FAILED_DEPENDENCY,
|
|
868
|
+
)
|
|
869
|
+
|
|
870
|
+
return datatypes.DutiesResponse(duties=duties, messages=messages)
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
class Webhooks:
|
|
874
|
+
@staticmethod
|
|
875
|
+
@utils.with_telemetry("webhook_register")
|
|
876
|
+
def register(
|
|
877
|
+
payload: dict,
|
|
878
|
+
carrier: providers.Carrier = None,
|
|
879
|
+
**carrier_filters,
|
|
880
|
+
) -> datatypes.DocumentUploadResponse:
|
|
881
|
+
carrier = carrier or Carriers.first(
|
|
882
|
+
**{
|
|
883
|
+
**dict(active=True, raise_not_found=True),
|
|
884
|
+
**carrier_filters,
|
|
885
|
+
}
|
|
886
|
+
)
|
|
887
|
+
|
|
888
|
+
if "register_webhook" not in carrier.gateway.proxy_methods:
|
|
889
|
+
raise exceptions.APIException(
|
|
890
|
+
detail=f"webhook registration is not supported by carrier: '{carrier.carrier_id}'",
|
|
891
|
+
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
|
892
|
+
)
|
|
893
|
+
|
|
894
|
+
request = karrio.Webhook.register(
|
|
895
|
+
lib.to_object(datatypes.WebhookRegistrationRequest, payload)
|
|
896
|
+
)
|
|
897
|
+
|
|
898
|
+
# The request is wrapped in utils.identity to simplify mocking in tests.
|
|
899
|
+
return utils.identity(lambda: request.from_(carrier.gateway).parse())
|
|
900
|
+
|
|
901
|
+
@staticmethod
|
|
902
|
+
@utils.with_telemetry("webhook_unregister")
|
|
903
|
+
def unregister(
|
|
904
|
+
payload: dict,
|
|
905
|
+
carrier: providers.Carrier = None,
|
|
906
|
+
**carrier_filters,
|
|
907
|
+
) -> datatypes.ConfirmationResponse:
|
|
908
|
+
carrier = carrier or Carriers.first(
|
|
909
|
+
**{
|
|
910
|
+
**dict(active=True, raise_not_found=True),
|
|
911
|
+
**carrier_filters,
|
|
912
|
+
}
|
|
913
|
+
)
|
|
914
|
+
|
|
915
|
+
if "deregister_webhook" not in carrier.gateway.proxy_methods:
|
|
916
|
+
raise exceptions.APIException(
|
|
917
|
+
detail=f"webhook deregistration is not supported by carrier: '{carrier.carrier_id}'",
|
|
918
|
+
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
|
919
|
+
)
|
|
920
|
+
|
|
921
|
+
request = karrio.Webhook.deregister(
|
|
922
|
+
lib.to_object(datatypes.WebhookDeregistrationRequest, payload)
|
|
923
|
+
)
|
|
924
|
+
|
|
925
|
+
# The request is wrapped in utils.identity to simplify mocking in tests.
|
|
926
|
+
return utils.identity(lambda: request.from_(carrier.gateway).parse())
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
class Hooks:
|
|
930
|
+
|
|
931
|
+
@staticmethod
|
|
932
|
+
def create_stub_gateway(
|
|
933
|
+
carrier_name: str, test_mode: bool = False
|
|
934
|
+
) -> karrio.Gateway:
|
|
935
|
+
import karrio.server.core.middleware as middleware
|
|
936
|
+
import karrio.server.core.config as system_config
|
|
937
|
+
import django.core.cache as caching
|
|
938
|
+
|
|
939
|
+
_context = middleware.SessionContext.get_current_request()
|
|
940
|
+
_tracer = getattr(_context, "tracer", lib.Tracer())
|
|
941
|
+
_cache = lib.Cache(caching.cache)
|
|
942
|
+
_config = lib.SystemConfig(system_config.config)
|
|
943
|
+
|
|
944
|
+
return karrio.gateway[carrier_name].create(
|
|
945
|
+
dict(
|
|
946
|
+
carrier_id=carrier_name,
|
|
947
|
+
test_mode=test_mode,
|
|
948
|
+
),
|
|
949
|
+
_tracer,
|
|
950
|
+
_cache,
|
|
951
|
+
_config,
|
|
952
|
+
is_stub=True,
|
|
953
|
+
)
|
|
954
|
+
|
|
955
|
+
@staticmethod
|
|
956
|
+
@utils.with_telemetry("hook_webhook_event")
|
|
957
|
+
def on_webhook_event(
|
|
958
|
+
payload: dict, carrier: providers.Carrier = None, **carrier_filters
|
|
959
|
+
) -> typing.Tuple[datatypes.WebhookEventDetails, typing.List[datatypes.Message]]:
|
|
960
|
+
carrier = carrier or Carriers.first(
|
|
961
|
+
**{
|
|
962
|
+
**dict(active=True, raise_not_found=True),
|
|
963
|
+
**carrier_filters,
|
|
964
|
+
}
|
|
965
|
+
)
|
|
966
|
+
|
|
967
|
+
if carrier is None:
|
|
968
|
+
raise NotFound("No active carrier connection found to process the request")
|
|
969
|
+
|
|
970
|
+
request = karrio.Hooks.on_webhook_event(
|
|
971
|
+
lib.to_object(datatypes.RequestPayload, lib.to_dict(payload))
|
|
972
|
+
)
|
|
973
|
+
|
|
974
|
+
# The request call is wrapped in utils.identity to simplify mocking in tests
|
|
975
|
+
return utils.identity(lambda: request.from_(carrier.gateway).parse())
|
|
976
|
+
|
|
977
|
+
@staticmethod
|
|
978
|
+
@utils.with_telemetry("hook_oauth_authorize")
|
|
979
|
+
def on_oauth_authorize(
|
|
980
|
+
payload: dict,
|
|
981
|
+
carrier: providers.Carrier = None,
|
|
982
|
+
carrier_name: str = None,
|
|
983
|
+
test_mode: bool = False,
|
|
984
|
+
**kwargs,
|
|
985
|
+
) -> typing.Tuple[datatypes.OAuthAuthorizeRequest, typing.List[datatypes.Message]]:
|
|
986
|
+
gateway = lib.identity(
|
|
987
|
+
getattr(carrier, "gateway", None)
|
|
988
|
+
or Hooks.create_stub_gateway(carrier_name, test_mode)
|
|
989
|
+
)
|
|
990
|
+
|
|
991
|
+
return utils.identity(
|
|
992
|
+
lambda: karrio.Hooks.on_oauth_authorize(payload).from_(gateway).parse()
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
@staticmethod
|
|
996
|
+
@utils.with_telemetry("hook_oauth_callback")
|
|
997
|
+
def on_oauth_callback(
|
|
998
|
+
payload: dict,
|
|
999
|
+
carrier_name: str = None,
|
|
1000
|
+
test_mode: bool = False,
|
|
1001
|
+
carrier: providers.Carrier = None,
|
|
1002
|
+
**kwargs,
|
|
1003
|
+
) -> typing.Tuple[typing.List[typing.Dict], typing.List[datatypes.Message]]:
|
|
1004
|
+
gateway = lib.identity(
|
|
1005
|
+
getattr(carrier, "gateway", None)
|
|
1006
|
+
or Hooks.create_stub_gateway(carrier_name, test_mode)
|
|
1007
|
+
)
|
|
1008
|
+
|
|
1009
|
+
return utils.identity(
|
|
1010
|
+
lambda: karrio.Hooks.on_oauth_callback(payload).from_(gateway).parse()
|
|
1011
|
+
)
|