karrio-server-core 2025.5__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.
Files changed (213) hide show
  1. karrio/server/conf.py +54 -0
  2. karrio/server/core/__init__.py +3 -0
  3. karrio/server/core/admin.py +1 -0
  4. karrio/server/core/apps.py +10 -0
  5. karrio/server/core/authentication.py +347 -0
  6. karrio/server/core/config.py +31 -0
  7. karrio/server/core/context_processors.py +12 -0
  8. karrio/server/core/datatypes.py +394 -0
  9. karrio/server/core/dataunits.py +187 -0
  10. karrio/server/core/exceptions.py +404 -0
  11. karrio/server/core/fields.py +12 -0
  12. karrio/server/core/filters.py +837 -0
  13. karrio/server/core/gateway.py +1011 -0
  14. karrio/server/core/logging.py +403 -0
  15. karrio/server/core/management/commands/cli.py +19 -0
  16. karrio/server/core/management/commands/create_oauth_client.py +41 -0
  17. karrio/server/core/management/commands/runserver.py +5 -0
  18. karrio/server/core/middleware.py +197 -0
  19. karrio/server/core/migrations/0001_initial.py +28 -0
  20. karrio/server/core/migrations/0002_apilogindex.py +69 -0
  21. karrio/server/core/migrations/0003_apilogindex_test_mode.py +62 -0
  22. karrio/server/core/migrations/0004_metafield.py +74 -0
  23. karrio/server/core/migrations/0005_alter_metafield_type_alter_metafield_value.py +23 -0
  24. karrio/server/core/migrations/0006_add_api_log_requested_at_index.py +22 -0
  25. karrio/server/core/migrations/__init__.py +0 -0
  26. karrio/server/core/models/__init__.py +48 -0
  27. karrio/server/core/models/base.py +103 -0
  28. karrio/server/core/models/entity.py +24 -0
  29. karrio/server/core/models/metafield.py +144 -0
  30. karrio/server/core/models/third_party.py +21 -0
  31. karrio/server/core/oauth_validators.py +170 -0
  32. karrio/server/core/permissions.py +36 -0
  33. karrio/server/core/renderers.py +11 -0
  34. karrio/server/core/router.py +3 -0
  35. karrio/server/core/serializers.py +1971 -0
  36. karrio/server/core/signals.py +55 -0
  37. karrio/server/core/telemetry.py +573 -0
  38. karrio/server/core/tests.py +99 -0
  39. karrio/server/core/tests_resource_token.py +411 -0
  40. karrio/server/core/urls.py +12 -0
  41. karrio/server/core/utils.py +1025 -0
  42. karrio/server/core/validators.py +264 -0
  43. karrio/server/core/views/__init__.py +2 -0
  44. karrio/server/core/views/api.py +133 -0
  45. karrio/server/core/views/metadata.py +44 -0
  46. karrio/server/core/views/oauth.py +75 -0
  47. karrio/server/core/views/references.py +82 -0
  48. karrio/server/core/views/schema.py +310 -0
  49. karrio/server/filters/__init__.py +2 -0
  50. karrio/server/filters/abstract.py +26 -0
  51. karrio/server/iam/__init__.py +0 -0
  52. karrio/server/iam/admin.py +3 -0
  53. karrio/server/iam/apps.py +21 -0
  54. karrio/server/iam/migrations/0001_initial.py +33 -0
  55. karrio/server/iam/migrations/__init__.py +0 -0
  56. karrio/server/iam/models.py +48 -0
  57. karrio/server/iam/permissions.py +155 -0
  58. karrio/server/iam/serializers.py +54 -0
  59. karrio/server/iam/signals.py +18 -0
  60. karrio/server/iam/tests.py +3 -0
  61. karrio/server/iam/views.py +3 -0
  62. karrio/server/openapi.py +75 -0
  63. karrio/server/providers/__init__.py +1 -0
  64. karrio/server/providers/admin.py +364 -0
  65. karrio/server/providers/apps.py +10 -0
  66. karrio/server/providers/management/commands/migrate_rate_sheets.py +101 -0
  67. karrio/server/providers/migrations/0001_initial.py +140 -0
  68. karrio/server/providers/migrations/0002_carrier_active.py +18 -0
  69. karrio/server/providers/migrations/0003_auto_20201230_0820.py +24 -0
  70. karrio/server/providers/migrations/0004_auto_20210212_0554.py +178 -0
  71. karrio/server/providers/migrations/0005_auto_20210212_0555.py +18 -0
  72. karrio/server/providers/migrations/0006_australiapostsettings.py +29 -0
  73. karrio/server/providers/migrations/0007_auto_20210213_0206.py +21 -0
  74. karrio/server/providers/migrations/0008_auto_20210214_0409.py +30 -0
  75. karrio/server/providers/migrations/0009_auto_20210308_0302.py +18 -0
  76. karrio/server/providers/migrations/0010_auto_20210409_0852.py +32 -0
  77. karrio/server/providers/migrations/0011_auto_20210409_0853.py +21 -0
  78. karrio/server/providers/migrations/0012_alter_carrier_options.py +17 -0
  79. karrio/server/providers/migrations/0013_tntsettings.py +30 -0
  80. karrio/server/providers/migrations/0014_auto_20210612_1608.py +46 -0
  81. karrio/server/providers/migrations/0015_auto_20210615_1601.py +28 -0
  82. karrio/server/providers/migrations/0016_alter_purolatorsettings_user_token.py +18 -0
  83. karrio/server/providers/migrations/0017_auto_20210805_0359.py +1293 -0
  84. karrio/server/providers/migrations/0018_alter_fedexsettings_user_key.py +18 -0
  85. karrio/server/providers/migrations/0019_dhlpolandsettings_servicelevel.py +65 -0
  86. karrio/server/providers/migrations/0020_genericsettings_labeltemplate.py +52 -0
  87. karrio/server/providers/migrations/0021_auto_20211231_2353.py +40 -0
  88. karrio/server/providers/migrations/0022_carrier_metadata.py +18 -0
  89. karrio/server/providers/migrations/0023_auto_20220124_1916.py +27 -0
  90. karrio/server/providers/migrations/0024_alter_genericsettings_custom_carrier_name.py +19 -0
  91. karrio/server/providers/migrations/0025_alter_servicelevel_service_code.py +19 -0
  92. karrio/server/providers/migrations/0026_auto_20220208_0132.py +59 -0
  93. karrio/server/providers/migrations/0027_auto_20220304_1340.py +29 -0
  94. karrio/server/providers/migrations/0028_auto_20220323_1500.py +33 -0
  95. karrio/server/providers/migrations/0029_easypostsettings.py +27 -0
  96. karrio/server/providers/migrations/0030_amazonmwssettings.py +29 -0
  97. karrio/server/providers/migrations/0031_delete_amazonmwssettings.py +18 -0
  98. karrio/server/providers/migrations/0032_alter_carrier_test.py +18 -0
  99. karrio/server/providers/migrations/0033_auto_20220708_1350.py +22 -0
  100. karrio/server/providers/migrations/0034_amazonmwssettings_dpdhlsettings.py +47 -0
  101. karrio/server/providers/migrations/0035_alter_carrier_capabilities.py +43 -0
  102. karrio/server/providers/migrations/0036_upsfreightsettings.py +31 -0
  103. karrio/server/providers/migrations/0037_chronopostsettings.py +29 -0
  104. karrio/server/providers/migrations/0038_alter_genericsettings_label_template.py +19 -0
  105. karrio/server/providers/migrations/0039_auto_20220906_0612.py +23 -0
  106. karrio/server/providers/migrations/0040_dpdhlsettings_services.py +18 -0
  107. karrio/server/providers/migrations/0041_auto_20221105_0705.py +38 -0
  108. karrio/server/providers/migrations/0042_auto_20221215_1642.py +23 -0
  109. karrio/server/providers/migrations/0043_alter_genericsettings_account_number_and_more.py +39 -0
  110. karrio/server/providers/migrations/0044_carrier_carrier_capabilities.py +64 -0
  111. karrio/server/providers/migrations/0045_alter_carrier_active_alter_carrier_carrier_id.py +31 -0
  112. karrio/server/providers/migrations/0046_remove_dpdhlsettings_signature_and_more.py +41 -0
  113. karrio/server/providers/migrations/0047_dpdsettings.py +286 -0
  114. karrio/server/providers/migrations/0048_servicelevel_min_weight_servicelevel_transit_days_and_more.py +64 -0
  115. karrio/server/providers/migrations/0049_boxknightsettings_geodissettings_lapostesettings_and_more.py +156 -0
  116. karrio/server/providers/migrations/0050_carrier_is_system_alter_carrier_metadata_and_more.py +106 -0
  117. karrio/server/providers/migrations/0051_rename_username_upssettings_client_id_and_more.py +31 -0
  118. karrio/server/providers/migrations/0052_alter_upssettings_account_number_and_more.py +20 -0
  119. karrio/server/providers/migrations/0053_locate2usettings.py +281 -0
  120. karrio/server/providers/migrations/0054_zoom2usettings.py +280 -0
  121. karrio/server/providers/migrations/0055_rename_amazonmwssettings_amazonshippingsettings_and_more.py +44 -0
  122. karrio/server/providers/migrations/0056_asendiaussettings_geodissettings_code_client_and_more.py +75 -0
  123. karrio/server/providers/migrations/0057_alter_servicelevel_weight_unit_belgianpostsettings.py +51 -0
  124. karrio/server/providers/migrations/0058_alliedexpresssettings.py +38 -0
  125. karrio/server/providers/migrations/0059_ratesheet.py +81 -0
  126. karrio/server/providers/migrations/0060_belgianpostsettings_rate_sheet_and_more.py +73 -0
  127. karrio/server/providers/migrations/0061_alliedexpresssettings_service_type.py +17 -0
  128. karrio/server/providers/migrations/0062_sendlesettings_account_country_code.py +257 -0
  129. karrio/server/providers/migrations/0063_servicelevel_metadata.py +25 -0
  130. karrio/server/providers/migrations/0064_alliedexpresslocalsettings.py +43 -0
  131. karrio/server/providers/migrations/0065_servicelevel_carrier_service_code_and_more.py +66 -0
  132. karrio/server/providers/migrations/0066_rename_fedexsettings_fedexwssettings_and_more.py +28 -0
  133. karrio/server/providers/migrations/0067_fedexsettings.py +283 -0
  134. karrio/server/providers/migrations/0068_fedexsettings_track_api_key_and_more.py +38 -0
  135. karrio/server/providers/migrations/0069_alter_canadapostsettings_contract_id_and_more.py +23 -0
  136. karrio/server/providers/migrations/0070_tgesettings_alter_carrier_capabilities.py +65 -0
  137. karrio/server/providers/migrations/0071_alter_tgesettings_my_toll_token.py +18 -0
  138. karrio/server/providers/migrations/0072_rename_eshippersettings_eshipperxmlsettings_and_more.py +28 -0
  139. karrio/server/providers/migrations/0073_delete_eshipperxmlsettings.py +41 -0
  140. karrio/server/providers/migrations/0074_eshippersettings.py +38 -0
  141. karrio/server/providers/migrations/0075_haypostsettings.py +40 -0
  142. karrio/server/providers/migrations/0076_rename_customer_registration_id_uspsinternationalsettings_account_number_and_more.py +125 -0
  143. karrio/server/providers/migrations/0077_uspswtinternationalsettings_uspswtsettings_and_more.py +165 -0
  144. karrio/server/providers/migrations/0078_auto_20240813_1552.py +120 -0
  145. karrio/server/providers/migrations/0079_alter_carrier_options_alter_ratesheet_created_by.py +31 -0
  146. karrio/server/providers/migrations/0080_alter_aramexsettings_account_country_code_and_more.py +3025 -0
  147. karrio/server/providers/migrations/0081_remove_alliedexpresssettings_carrier_ptr_and_more.py +338 -0
  148. karrio/server/providers/migrations/0082_add_zone_identifiers.py +50 -0
  149. karrio/server/providers/migrations/0083_add_optimized_rate_sheet_structure.py +33 -0
  150. karrio/server/providers/migrations/0084_alter_servicelevel_currency.py +168 -0
  151. karrio/server/providers/migrations/0085_populate_dhl_parcel_de_oauth_credentials.py +82 -0
  152. karrio/server/providers/migrations/0086_rename_dhl_parcel_de_customer_number_to_billing_number.py +71 -0
  153. karrio/server/providers/migrations/__init__.py +0 -0
  154. karrio/server/providers/models/__init__.py +16 -0
  155. karrio/server/providers/models/carrier.py +387 -0
  156. karrio/server/providers/models/config.py +30 -0
  157. karrio/server/providers/models/service.py +192 -0
  158. karrio/server/providers/models/sheet.py +287 -0
  159. karrio/server/providers/models/template.py +39 -0
  160. karrio/server/providers/models/utils.py +58 -0
  161. karrio/server/providers/router.py +3 -0
  162. karrio/server/providers/serializers/__init__.py +3 -0
  163. karrio/server/providers/serializers/base.py +538 -0
  164. karrio/server/providers/signals.py +25 -0
  165. karrio/server/providers/templates/providers/oauth_callback.html +105 -0
  166. karrio/server/providers/tests/__init__.py +5 -0
  167. karrio/server/providers/tests/test_connections.py +895 -0
  168. karrio/server/providers/urls.py +11 -0
  169. karrio/server/providers/views/__init__.py +0 -0
  170. karrio/server/providers/views/carriers.py +267 -0
  171. karrio/server/providers/views/connections.py +496 -0
  172. karrio/server/samples.py +352 -0
  173. karrio/server/serializers/__init__.py +2 -0
  174. karrio/server/serializers/abstract.py +602 -0
  175. karrio/server/tracing/__init__.py +0 -0
  176. karrio/server/tracing/admin.py +63 -0
  177. karrio/server/tracing/apps.py +8 -0
  178. karrio/server/tracing/migrations/0001_initial.py +41 -0
  179. karrio/server/tracing/migrations/0002_auto_20220710_1307.py +22 -0
  180. karrio/server/tracing/migrations/0003_auto_20221105_0317.py +43 -0
  181. karrio/server/tracing/migrations/0004_tracingrecord_carrier_account_idx.py +24 -0
  182. karrio/server/tracing/migrations/0005_optimise_tracingrecord_request_log_idx.py +25 -0
  183. karrio/server/tracing/migrations/0006_alter_tracingrecord_options_and_more.py +49 -0
  184. karrio/server/tracing/migrations/0007_tracingrecord_tracing_created_at_idx.py +19 -0
  185. karrio/server/tracing/migrations/__init__.py +0 -0
  186. karrio/server/tracing/models.py +82 -0
  187. karrio/server/tracing/tests.py +3 -0
  188. karrio/server/tracing/utils.py +109 -0
  189. karrio/server/user/__init__.py +0 -0
  190. karrio/server/user/admin.py +96 -0
  191. karrio/server/user/apps.py +7 -0
  192. karrio/server/user/forms.py +35 -0
  193. karrio/server/user/migrations/0001_initial.py +41 -0
  194. karrio/server/user/migrations/0002_token.py +29 -0
  195. karrio/server/user/migrations/0003_token_test_mode.py +20 -0
  196. karrio/server/user/migrations/0004_group.py +26 -0
  197. karrio/server/user/migrations/0005_token_label.py +21 -0
  198. karrio/server/user/migrations/0006_workspaceconfig.py +63 -0
  199. karrio/server/user/migrations/0007_user_metadata.py +25 -0
  200. karrio/server/user/migrations/__init__.py +0 -0
  201. karrio/server/user/models.py +218 -0
  202. karrio/server/user/serializers.py +47 -0
  203. karrio/server/user/templates/registration/login.html +108 -0
  204. karrio/server/user/templates/registration/registration_confirm_email.html +10 -0
  205. karrio/server/user/templates/registration/registration_confirm_email.txt +3 -0
  206. karrio/server/user/tests.py +3 -0
  207. karrio/server/user/urls.py +10 -0
  208. karrio/server/user/utils.py +60 -0
  209. karrio/server/user/views.py +9 -0
  210. karrio_server_core-2025.5.dist-info/METADATA +32 -0
  211. karrio_server_core-2025.5.dist-info/RECORD +213 -0
  212. karrio_server_core-2025.5.dist-info/WHEEL +5 -0
  213. karrio_server_core-2025.5.dist-info/top_level.txt +2 -0
@@ -0,0 +1,11 @@
1
+ """
2
+ karrio server providers module urls
3
+ """
4
+
5
+ from django.urls import include, path
6
+
7
+ app_name = "karrio.server.providers"
8
+ urlpatterns = [
9
+ path("v1/", include("karrio.server.providers.views.carriers")),
10
+ path("v1/", include("karrio.server.providers.views.connections")),
11
+ ]
File without changes
@@ -0,0 +1,267 @@
1
+ import io
2
+ import base64
3
+ import re
4
+ from django.http import JsonResponse
5
+ from django.urls import path, re_path
6
+ from rest_framework import status, views
7
+ from rest_framework.request import Request
8
+ from rest_framework.response import Response
9
+ from django.core.files.base import ContentFile
10
+ from django_downloadview import VirtualDownloadView
11
+
12
+ import karrio.lib as lib
13
+ import karrio.server.openapi as openapi
14
+ import karrio.server.samples as samples
15
+ import karrio.server.core.views.api as api
16
+ import karrio.server.providers.models as models
17
+ from karrio.server.core.logging import logger
18
+ from karrio.server.core import datatypes, dataunits, serializers
19
+ ENDPOINT_ID = "&&" # This endpoint id is used to make operation ids unique make sure not to duplicate
20
+
21
+
22
+ class CarrierList(views.APIView):
23
+ permission_classes = []
24
+
25
+ @openapi.extend_schema(
26
+ auth=[],
27
+ tags=["Carriers"],
28
+ operation_id=f"{ENDPOINT_ID}list",
29
+ extensions={"x-operationId": "listCarriers"},
30
+ summary="List all carriers",
31
+ responses={
32
+ 200: serializers.CarrierDetails(many=True),
33
+ 500: serializers.ErrorResponse(),
34
+ },
35
+ examples=[
36
+ openapi.OpenApiExample(
37
+ name="Carrier List",
38
+ value=lib.to_dict(samples.CARRIER_DETAILS_SAMPLE),
39
+ )
40
+ ],
41
+ )
42
+ def get(self, request: Request):
43
+ """Returns the list of configured carriers"""
44
+ references = dataunits.contextual_reference(reduced=False)
45
+ carriers = [
46
+ dataunits.get_carrier_details(
47
+ carrier_name,
48
+ contextual_reference=references,
49
+ )
50
+ for carrier_name in references["carriers"].keys()
51
+ ]
52
+
53
+ return Response(carriers, status=status.HTTP_200_OK)
54
+
55
+
56
+ class CarrierDetails(api.APIView):
57
+ permission_classes = []
58
+
59
+ @openapi.extend_schema(
60
+ auth=[],
61
+ tags=["Carriers"],
62
+ operation_id=f"{ENDPOINT_ID}get_details",
63
+ extensions={"x-operationId": "getDetails"},
64
+ summary="Get carrier details",
65
+ parameters=[
66
+ openapi.OpenApiParameter(
67
+ "carrier_name",
68
+ location=openapi.OpenApiParameter.PATH,
69
+ type=openapi.OpenApiTypes.STR,
70
+ description=(
71
+ "The unique carrier slug. <br/>"
72
+ f"Values: {', '.join([f'`{c}`' for c in dataunits.CARRIER_NAMES])}"
73
+ ),
74
+ )
75
+ ],
76
+ responses={
77
+ 200: serializers.CarrierDetails(),
78
+ 404: serializers.ErrorResponse(),
79
+ 500: serializers.ErrorResponse(),
80
+ },
81
+ )
82
+ def get(self, request: Request, carrier_name: str):
83
+ """
84
+ Retrieve a carrier's details
85
+ """
86
+ references = dataunits.contextual_reference(reduced=False)
87
+
88
+ if carrier_name not in references["carriers"]:
89
+ raise Exception(f"Unknown carrier: {carrier_name}")
90
+
91
+ carrier_details = dataunits.get_carrier_details(
92
+ carrier_name,
93
+ contextual_reference=references,
94
+ )
95
+
96
+ return Response(carrier_details, status=status.HTTP_200_OK)
97
+
98
+
99
+ class CarrierServices(api.APIView):
100
+ permission_classes = []
101
+
102
+ @openapi.extend_schema(
103
+ auth=[],
104
+ tags=["Carriers"],
105
+ operation_id=f"{ENDPOINT_ID}get_services",
106
+ extensions={"x-operationId": "getServices"},
107
+ summary="Get carrier services",
108
+ parameters=[
109
+ openapi.OpenApiParameter(
110
+ "carrier_name",
111
+ location=openapi.OpenApiParameter.PATH,
112
+ type=openapi.OpenApiTypes.STR,
113
+ description=(
114
+ "The unique carrier slug. <br/>"
115
+ f"Values: {', '.join([f'`{c}`' for c in dataunits.CARRIER_NAMES])}"
116
+ ),
117
+ )
118
+ ],
119
+ responses={
120
+ 200: openapi.OpenApiTypes.OBJECT,
121
+ 404: serializers.ErrorResponse(),
122
+ 500: serializers.ErrorResponse(),
123
+ },
124
+ examples=[
125
+ openapi.OpenApiExample(
126
+ name="Carrier List",
127
+ value=lib.to_dict(samples.CARRIER_SERICES_SAMPLE),
128
+ )
129
+ ],
130
+ )
131
+ def get(self, request: Request, carrier_name: str):
132
+ """
133
+ Retrieve a carrier's services
134
+ """
135
+ references = dataunits.contextual_reference()
136
+
137
+ if carrier_name not in references["carriers"]:
138
+ raise Exception(f"Unknown carrier: {carrier_name}")
139
+
140
+ services = references["services"].get(carrier_name, {})
141
+
142
+ return Response(services, status=status.HTTP_200_OK)
143
+
144
+
145
+ class CarrierOptions(api.APIView):
146
+ permission_classes = []
147
+
148
+ @openapi.extend_schema(
149
+ auth=[],
150
+ tags=["Carriers"],
151
+ operation_id=f"{ENDPOINT_ID}get_options",
152
+ extensions={"x-operationId": "getOptions"},
153
+ summary="Get carrier options",
154
+ parameters=[
155
+ openapi.OpenApiParameter(
156
+ "carrier_name",
157
+ location=openapi.OpenApiParameter.PATH,
158
+ type=openapi.OpenApiTypes.STR,
159
+ description=(
160
+ "The unique carrier slug. <br/>"
161
+ f"Values: {', '.join([f'`{c}`' for c in dataunits.CARRIER_NAMES])}"
162
+ ),
163
+ )
164
+ ],
165
+ responses={
166
+ 200: openapi.OpenApiTypes.OBJECT,
167
+ 404: serializers.ErrorResponse(),
168
+ 500: serializers.ErrorResponse(),
169
+ },
170
+ examples=[
171
+ openapi.OpenApiExample(
172
+ name="Carrier Options",
173
+ value=lib.to_dict(samples.CARRIER_OPTIONS_SAMPLE),
174
+ )
175
+ ],
176
+ )
177
+ def get(self, request: Request, carrier_name: str):
178
+ """
179
+ Retrieve a carrier's options
180
+ """
181
+ references = dataunits.contextual_reference()
182
+
183
+ if carrier_name not in references["carriers"]:
184
+ raise Exception(f"Unknown carrier: {carrier_name}")
185
+
186
+ options = references["options"].get(carrier_name, {})
187
+
188
+ return Response(options, status=status.HTTP_200_OK)
189
+
190
+
191
+ class CarrierLabelPreview(VirtualDownloadView):
192
+ def get(
193
+ self,
194
+ request: Request,
195
+ pk: str,
196
+ format: str = "pdf",
197
+ **kwargs,
198
+ ):
199
+ """
200
+ Preview a carrier label template...
201
+ """
202
+ try:
203
+ query_params = request.GET.dict()
204
+ carrier = models.Carrier.objects.get(carrier_code="generic", pk=pk)
205
+
206
+ self.document = self._generate_label(carrier, format)
207
+ self.name = f"{carrier.custom_carrier_name}_label.{format}"
208
+ self.attachment = query_params.get("download", False)
209
+
210
+ response = super(CarrierLabelPreview, self).get(
211
+ request, pk, format, **kwargs
212
+ )
213
+ response["X-Frame-Options"] = "ALLOWALL"
214
+ return response
215
+ except Exception as e:
216
+ return JsonResponse(dict(error=str(e)), status=status.HTTP_409_CONFLICT)
217
+
218
+ def get_file(self):
219
+ content = base64.b64decode(self.document or "")
220
+ buffer = io.BytesIO()
221
+ buffer.write(content)
222
+
223
+ return ContentFile(buffer.getvalue(), name=self.name)
224
+
225
+ def _generate_label(self, carrier, format):
226
+ import karrio.sdk as karrio
227
+ import karrio.providers.generic.units as units
228
+
229
+ template = carrier.label_template
230
+ data = lib.identity(
231
+ template.shipment_sample
232
+ if template is not None and len(template.shipment_sample.items()) > 0
233
+ else units.SAMPLE_SHIPMENT_REQUEST
234
+ )
235
+ service = lib.identity(
236
+ data.get("service") or next((s.service_code for s in carrier.services))
237
+ )
238
+ request = lib.to_object(
239
+ datatypes.ShipmentRequest,
240
+ {
241
+ **data,
242
+ "service": service,
243
+ "label_type": format.upper(),
244
+ "selected_rate_id": data.get("selected_rate_id") or "",
245
+ "rates": data.get("rates") or [],
246
+ },
247
+ )
248
+
249
+ shipment, _ = karrio.Shipment.create(request).from_(carrier.gateway).parse()
250
+
251
+ if shipment is None:
252
+ raise Exception("Failed to generate label")
253
+
254
+ return shipment.docs.label
255
+
256
+
257
+ urlpatterns = [
258
+ path("carriers", CarrierList.as_view(), name="carrier-list"),
259
+ path("carriers/<str:carrier_name>", CarrierDetails.as_view(), name="carrier-details"),
260
+ path("carriers/<str:carrier_name>/services", CarrierServices.as_view(), name="carrier-services"),
261
+ path("carriers/<str:carrier_name>/options", CarrierOptions.as_view(), name="carrier-options"),
262
+ re_path(
263
+ r"^carriers/(?P<pk>\w+)/label.(?P<format>[a-z0-9]+)",
264
+ CarrierLabelPreview.as_view(),
265
+ name="carrier-label",
266
+ ),
267
+ ]