karrio-teleship 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.
- karrio/mappers/teleship/__init__.py +4 -0
- karrio/mappers/teleship/hooks.py +27 -0
- karrio/mappers/teleship/mapper.py +114 -0
- karrio/mappers/teleship/proxy.py +239 -0
- karrio/mappers/teleship/settings.py +21 -0
- karrio/plugins/teleship/__init__.py +32 -0
- karrio/providers/teleship/__init__.py +41 -0
- karrio/providers/teleship/duties.py +115 -0
- karrio/providers/teleship/error.py +44 -0
- karrio/providers/teleship/hooks/__init__.py +5 -0
- karrio/providers/teleship/hooks/event.py +163 -0
- karrio/providers/teleship/hooks/oauth.py +103 -0
- karrio/providers/teleship/manifest.py +68 -0
- karrio/providers/teleship/pickup/__init__.py +8 -0
- karrio/providers/teleship/pickup/cancel.py +43 -0
- karrio/providers/teleship/pickup/schedule.py +66 -0
- karrio/providers/teleship/rate.py +287 -0
- karrio/providers/teleship/shipment/__init__.py +9 -0
- karrio/providers/teleship/shipment/cancel.py +48 -0
- karrio/providers/teleship/shipment/create.py +322 -0
- karrio/providers/teleship/tracking.py +100 -0
- karrio/providers/teleship/units.py +154 -0
- karrio/providers/teleship/utils.py +57 -0
- karrio/providers/teleship/webhook/__init__.py +8 -0
- karrio/providers/teleship/webhook/deregister.py +47 -0
- karrio/providers/teleship/webhook/register.py +48 -0
- karrio/schemas/teleship/__init__.py +0 -0
- karrio/schemas/teleship/duties_taxes_request.py +82 -0
- karrio/schemas/teleship/duties_taxes_response.py +28 -0
- karrio/schemas/teleship/error_response.py +17 -0
- karrio/schemas/teleship/manifest_request.py +39 -0
- karrio/schemas/teleship/manifest_response.py +31 -0
- karrio/schemas/teleship/pickup_request.py +31 -0
- karrio/schemas/teleship/pickup_response.py +48 -0
- karrio/schemas/teleship/rate_request.py +128 -0
- karrio/schemas/teleship/rate_response.py +66 -0
- karrio/schemas/teleship/shipment_cancel_request.py +8 -0
- karrio/schemas/teleship/shipment_cancel_response.py +17 -0
- karrio/schemas/teleship/shipment_request.py +137 -0
- karrio/schemas/teleship/shipment_response.py +247 -0
- karrio/schemas/teleship/tracking_request.py +8 -0
- karrio/schemas/teleship/tracking_response.py +52 -0
- karrio/schemas/teleship/webhook_request.py +18 -0
- karrio/schemas/teleship/webhook_response.py +20 -0
- karrio_teleship-2025.5.dist-info/METADATA +44 -0
- karrio_teleship-2025.5.dist-info/RECORD +49 -0
- karrio_teleship-2025.5.dist-info/WHEEL +5 -0
- karrio_teleship-2025.5.dist-info/entry_points.txt +2 -0
- karrio_teleship-2025.5.dist-info/top_level.txt +4 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Karrio Teleship tracking API implementation."""
|
|
2
|
+
|
|
3
|
+
import karrio.schemas.teleship.tracking_response as teleship_res
|
|
4
|
+
|
|
5
|
+
import typing
|
|
6
|
+
import karrio.lib as lib
|
|
7
|
+
import karrio.core.models as models
|
|
8
|
+
import karrio.providers.teleship.error as error
|
|
9
|
+
import karrio.providers.teleship.utils as provider_utils
|
|
10
|
+
import karrio.providers.teleship.units as provider_units
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def parse_tracking_response(
|
|
14
|
+
_response: lib.Deserializable[typing.List[typing.Tuple[str, dict]]],
|
|
15
|
+
settings: provider_utils.Settings,
|
|
16
|
+
) -> typing.Tuple[typing.List[models.TrackingDetails], typing.List[models.Message]]:
|
|
17
|
+
responses = _response.deserialize()
|
|
18
|
+
|
|
19
|
+
# Aggregate error messages using functional sum pattern
|
|
20
|
+
messages: typing.List[models.Message] = sum(
|
|
21
|
+
[
|
|
22
|
+
error.parse_error_response(
|
|
23
|
+
response, settings, **dict(tracking_number=tracking_number)
|
|
24
|
+
)
|
|
25
|
+
for tracking_number, response in responses
|
|
26
|
+
],
|
|
27
|
+
start=[],
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Extract tracking details using list comprehension (skip error responses)
|
|
31
|
+
tracking_details = [
|
|
32
|
+
_extract_details(details, settings)
|
|
33
|
+
for tracking_number, details in responses
|
|
34
|
+
if details and not details.get("messages")
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
return tracking_details, messages
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _extract_details(
|
|
41
|
+
data: dict,
|
|
42
|
+
settings: provider_utils.Settings,
|
|
43
|
+
) -> models.TrackingDetails:
|
|
44
|
+
"""Extract tracking details from carrier response data"""
|
|
45
|
+
|
|
46
|
+
tracking = lib.to_object(teleship_res.TrackingResponseType, data)
|
|
47
|
+
last_event = next(iter(tracking.events or []), None)
|
|
48
|
+
status = next(
|
|
49
|
+
(
|
|
50
|
+
status.name
|
|
51
|
+
for status in list(provider_units.TrackingStatus)
|
|
52
|
+
if last_event and last_event.code in status.value
|
|
53
|
+
),
|
|
54
|
+
provider_units.TrackingStatus.in_transit.name,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return models.TrackingDetails(
|
|
58
|
+
carrier_id=settings.carrier_id,
|
|
59
|
+
carrier_name=settings.carrier_name,
|
|
60
|
+
tracking_number=tracking.trackingNumber,
|
|
61
|
+
events=[
|
|
62
|
+
models.TrackingEvent(
|
|
63
|
+
date=lib.fdate(event.timestamp, "%Y-%m-%dT%H:%M:%SZ"),
|
|
64
|
+
time=lib.flocaltime(event.timestamp, "%Y-%m-%dT%H:%M:%SZ"),
|
|
65
|
+
description=event.description,
|
|
66
|
+
code=event.code,
|
|
67
|
+
location=event.location,
|
|
68
|
+
)
|
|
69
|
+
for event in tracking.events
|
|
70
|
+
],
|
|
71
|
+
delivered=status == "delivered",
|
|
72
|
+
status=status,
|
|
73
|
+
estimated_delivery=lib.fdate(
|
|
74
|
+
tracking.estimatedDelivery,
|
|
75
|
+
try_formats=["%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%SZ"],
|
|
76
|
+
),
|
|
77
|
+
info=models.TrackingInfo(
|
|
78
|
+
shipment_service=tracking.firstMile.carrier,
|
|
79
|
+
carrier_tracking_link=settings.tracking_url.format(tracking.trackingNumber),
|
|
80
|
+
customer_name=tracking.shipTo.address.city,
|
|
81
|
+
shipment_destination_country=tracking.shipTo.address.country,
|
|
82
|
+
shipment_origin_country=tracking.shipFrom.address.country,
|
|
83
|
+
),
|
|
84
|
+
meta=dict(
|
|
85
|
+
shipment_id=tracking.shipmentId,
|
|
86
|
+
customer_reference=tracking.customerReference,
|
|
87
|
+
ship_date=tracking.shipDate,
|
|
88
|
+
last_mile_carrier=tracking.lastMile.carrier,
|
|
89
|
+
last_mile_tracking=tracking.lastMile.trackingNumber,
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def tracking_request(
|
|
95
|
+
payload: models.TrackingRequest,
|
|
96
|
+
settings: provider_utils.Settings,
|
|
97
|
+
) -> lib.Serializable:
|
|
98
|
+
"""Create a tracking request for the carrier API"""
|
|
99
|
+
# Return tracking numbers as serializable for proxy to handle
|
|
100
|
+
return lib.Serializable(payload.tracking_numbers)
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import karrio.lib as lib
|
|
2
|
+
import karrio.core.units as units
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# System config schema for runtime settings (e.g., OAuth credentials)
|
|
6
|
+
# Format: Dict[str, Tuple[default_value, description, type]]
|
|
7
|
+
# Note: The actual env values are read by the server (constance.py) using decouple
|
|
8
|
+
SYSTEM_CONFIG = {
|
|
9
|
+
"TELESHIP_OAUTH_CLIENT_ID": (
|
|
10
|
+
"",
|
|
11
|
+
"The Teleship OAuth client ID",
|
|
12
|
+
str,
|
|
13
|
+
),
|
|
14
|
+
"TELESHIP_OAUTH_CLIENT_SECRET": (
|
|
15
|
+
"",
|
|
16
|
+
"The Teleship OAuth client secret",
|
|
17
|
+
str,
|
|
18
|
+
),
|
|
19
|
+
"TELESHIP_SANDBOX_OAUTH_CLIENT_ID": (
|
|
20
|
+
"",
|
|
21
|
+
"The Teleship sandbox OAuth client ID",
|
|
22
|
+
str,
|
|
23
|
+
),
|
|
24
|
+
"TELESHIP_SANDBOX_OAUTH_CLIENT_SECRET": (
|
|
25
|
+
"",
|
|
26
|
+
"The Teleship sandbox OAuth client secret",
|
|
27
|
+
str,
|
|
28
|
+
),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class LabelType(lib.StrEnum):
|
|
33
|
+
"""Carrier specific label type"""
|
|
34
|
+
|
|
35
|
+
PDF = "PDF"
|
|
36
|
+
ZPL = "ZPL"
|
|
37
|
+
PNG = "PNG"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ConnectionConfig(lib.Enum):
|
|
41
|
+
"""Teleship connection configuration."""
|
|
42
|
+
|
|
43
|
+
shipping_options = lib.OptionEnum("shipping_options", list)
|
|
44
|
+
shipping_services = lib.OptionEnum("shipping_services", list)
|
|
45
|
+
label_format = lib.OptionEnum(
|
|
46
|
+
"label_format",
|
|
47
|
+
lib.units.create_enum("LabelType", [_.name for _ in list(LabelType)]),
|
|
48
|
+
"PDF",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class PackagingType(lib.StrEnum):
|
|
53
|
+
"""Carrier specific packaging type"""
|
|
54
|
+
|
|
55
|
+
envelope = "envelope"
|
|
56
|
+
tube = "tube"
|
|
57
|
+
parcel = "parcel"
|
|
58
|
+
|
|
59
|
+
""" Unified Packaging type mapping """
|
|
60
|
+
pak = envelope
|
|
61
|
+
small_box = parcel
|
|
62
|
+
medium_box = parcel
|
|
63
|
+
your_packaging = parcel
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ShippingService(lib.StrEnum):
|
|
67
|
+
"""Carrier specific services"""
|
|
68
|
+
|
|
69
|
+
teleship_expedited_pickup = "TELESHIP-EXPEDITED-PICKUP"
|
|
70
|
+
teleship_expedited_dropoff = "TELESHIP-EXPEDITED-DROPOFF"
|
|
71
|
+
teleship_standard_dropoff = "TELESHIP-STANDARD-DROPOFF"
|
|
72
|
+
teleship_standard_pickup = "TELESHIP-STANDARD-PICKUP"
|
|
73
|
+
teleship_postal_dropoff = "TELESHIP-POSTAL-DROPOFF"
|
|
74
|
+
teleship_postal_pickup = "TELESHIP-POSTAL-PICKUP"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ShippingOption(lib.Enum):
|
|
78
|
+
"""Carrier specific options"""
|
|
79
|
+
|
|
80
|
+
teleship_signature_required = lib.OptionEnum("signatureRequired", bool)
|
|
81
|
+
teleship_delivery_warranty = lib.OptionEnum("deliveryWarranty", bool)
|
|
82
|
+
teleship_delivery_PUDO = lib.OptionEnum("deliveryPUDO", bool)
|
|
83
|
+
teleship_low_carbon = lib.OptionEnum("lowCarbon", bool)
|
|
84
|
+
teleship_duty_tax_calculation = lib.OptionEnum("dutyTaxCalculation", bool)
|
|
85
|
+
teleship_customer_reference = lib.OptionEnum("customerReference")
|
|
86
|
+
teleship_order_tracking_reference = lib.OptionEnum("orderTrackingReference")
|
|
87
|
+
teleship_commercial_invoice_reference = lib.OptionEnum("commercialInvoiceReference")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def shipping_options_initializer(
|
|
91
|
+
options: dict,
|
|
92
|
+
package_options: units.ShippingOptions = None,
|
|
93
|
+
) -> units.ShippingOptions:
|
|
94
|
+
"""
|
|
95
|
+
Apply default values to the given options.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
if package_options is not None:
|
|
99
|
+
options.update(package_options.content)
|
|
100
|
+
|
|
101
|
+
def items_filter(key: str) -> bool:
|
|
102
|
+
return key in ShippingOption # type: ignore
|
|
103
|
+
|
|
104
|
+
return units.ShippingOptions(options, ShippingOption, items_filter=items_filter)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class CustomsContentType(lib.StrEnum):
|
|
108
|
+
"""Teleship customs content types"""
|
|
109
|
+
|
|
110
|
+
# Teleship-specific values (PascalCase)
|
|
111
|
+
documents = "Documents"
|
|
112
|
+
gift = "Gift"
|
|
113
|
+
sample = "Sample"
|
|
114
|
+
other = "Other"
|
|
115
|
+
commercial_goods = "CommercialGoods"
|
|
116
|
+
return_of_goods = "ReturnOfGoods"
|
|
117
|
+
|
|
118
|
+
""" Unified content type mapping """
|
|
119
|
+
merchandise = commercial_goods
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class CustomsOption(lib.Enum):
|
|
123
|
+
"""Teleship customs identifiers"""
|
|
124
|
+
|
|
125
|
+
EORI = lib.OptionEnum("EORI")
|
|
126
|
+
IOSS = lib.OptionEnum("IOSS")
|
|
127
|
+
VAT = lib.OptionEnum("VAT")
|
|
128
|
+
EIN = lib.OptionEnum("EIN")
|
|
129
|
+
VOECNUMBER = lib.OptionEnum("VOECNUMBER")
|
|
130
|
+
|
|
131
|
+
""" Unified Customs Identifier type mapping """
|
|
132
|
+
|
|
133
|
+
ioss = IOSS
|
|
134
|
+
eori_number = EORI
|
|
135
|
+
vat = VAT
|
|
136
|
+
ein = EIN
|
|
137
|
+
voec_number = VOECNUMBER
|
|
138
|
+
vat_registration_number = VAT
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class TrackingStatus(lib.Enum):
|
|
142
|
+
"""Teleship tracking statuses"""
|
|
143
|
+
|
|
144
|
+
delivered = ["delivered"]
|
|
145
|
+
in_transit = [
|
|
146
|
+
"in_transit",
|
|
147
|
+
"collected",
|
|
148
|
+
"in_hub",
|
|
149
|
+
"out_for_delivery",
|
|
150
|
+
"customs_cleared",
|
|
151
|
+
]
|
|
152
|
+
out_for_delivery = ["out_for_delivery"]
|
|
153
|
+
delivery_failed = ["delivery_failed", "returned", "cancelled"]
|
|
154
|
+
pending = ["pending", "created", "label_created"]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
import karrio.lib as lib
|
|
4
|
+
import karrio.core as core
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Settings(core.Settings):
|
|
10
|
+
"""Teleship connection settings."""
|
|
11
|
+
|
|
12
|
+
# Add carrier specific api connection properties here
|
|
13
|
+
client_id: str
|
|
14
|
+
client_secret: str
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def carrier_name(self):
|
|
18
|
+
return "teleship"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def server_url(self):
|
|
22
|
+
return os.getenv("TELESHIP_SERVER_URL") or (
|
|
23
|
+
"https://sandbox.teleship.com"
|
|
24
|
+
if self.test_mode
|
|
25
|
+
else "https://api.teleship.com"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def tracking_url(self):
|
|
30
|
+
return "https://track.teleship.com/{}"
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def connection_config(self) -> lib.units.Options:
|
|
34
|
+
from karrio.providers.teleship.units import ConnectionConfig
|
|
35
|
+
|
|
36
|
+
return lib.to_connection_config(
|
|
37
|
+
self.config or {},
|
|
38
|
+
option_type=ConnectionConfig,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def oauth_client_id(self):
|
|
43
|
+
return (
|
|
44
|
+
self.connection_system_config.get("TELESHIP_OAUTH_CLIENT_ID")
|
|
45
|
+
if self.test_mode
|
|
46
|
+
else self.connection_system_config.get("TELESHIP_SANDBOX_OAUTH_CLIENT_ID")
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def oauth_client_secret(self):
|
|
51
|
+
return (
|
|
52
|
+
self.connection_system_config.get("TELESHIP_OAUTH_CLIENT_SECRET")
|
|
53
|
+
if self.test_mode
|
|
54
|
+
else self.connection_system_config.get(
|
|
55
|
+
"TELESHIP_SANDBOX_OAUTH_CLIENT_SECRET"
|
|
56
|
+
)
|
|
57
|
+
)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from karrio.providers.teleship.webhook.register import (
|
|
2
|
+
webhook_registration_request,
|
|
3
|
+
parse_webhook_registration_response,
|
|
4
|
+
)
|
|
5
|
+
from karrio.providers.teleship.webhook.deregister import (
|
|
6
|
+
webhook_deregistration_request,
|
|
7
|
+
parse_webhook_deregistration_response,
|
|
8
|
+
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Karrio Teleship webhook deregistration implementation."""
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
import karrio.lib as lib
|
|
5
|
+
import karrio.core.models as models
|
|
6
|
+
import karrio.providers.teleship.error as error
|
|
7
|
+
import karrio.providers.teleship.utils as provider_utils
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def parse_webhook_deregistration_response(
|
|
11
|
+
_response: lib.Deserializable[str],
|
|
12
|
+
settings: provider_utils.Settings,
|
|
13
|
+
) -> typing.Tuple[models.ConfirmationDetails, typing.List[models.Message]]:
|
|
14
|
+
response = _response.deserialize()
|
|
15
|
+
messages = error.parse_error_response(response, settings)
|
|
16
|
+
|
|
17
|
+
# Teleship returns 204 No Content on successful deletion
|
|
18
|
+
# or success response with status
|
|
19
|
+
success = not any(messages) and (
|
|
20
|
+
isinstance(response, dict) and response.get("success") is not False
|
|
21
|
+
or response == ""
|
|
22
|
+
or response is None
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
confirmation = (
|
|
26
|
+
models.ConfirmationDetails(
|
|
27
|
+
carrier_id=settings.carrier_id,
|
|
28
|
+
carrier_name=settings.carrier_name,
|
|
29
|
+
success=success,
|
|
30
|
+
operation="webhook_deregistration",
|
|
31
|
+
)
|
|
32
|
+
if success
|
|
33
|
+
else None
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return confirmation, messages
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def webhook_deregistration_request(
|
|
40
|
+
payload: models.WebhookDeregistrationRequest,
|
|
41
|
+
settings: provider_utils.Settings,
|
|
42
|
+
) -> lib.Serializable:
|
|
43
|
+
"""Create a Teleship webhook deregistration request"""
|
|
44
|
+
|
|
45
|
+
request = {"webhookId": payload.webhook_id}
|
|
46
|
+
|
|
47
|
+
return lib.Serializable(request, lib.to_dict)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Karrio Teleship webhook registration implementation."""
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
import karrio.schemas.teleship.webhook_request as teleship
|
|
5
|
+
import karrio.schemas.teleship.webhook_response as webhook
|
|
6
|
+
import karrio.lib as lib
|
|
7
|
+
import karrio.core.models as models
|
|
8
|
+
import karrio.providers.teleship.error as error
|
|
9
|
+
import karrio.providers.teleship.utils as provider_utils
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def parse_webhook_registration_response(
|
|
13
|
+
_response: lib.Deserializable[str],
|
|
14
|
+
settings: provider_utils.Settings,
|
|
15
|
+
) -> typing.Tuple[models.WebhookRegistrationDetails, typing.List[models.Message]]:
|
|
16
|
+
response = _response.deserialize()
|
|
17
|
+
messages = error.parse_error_response(response, settings)
|
|
18
|
+
details = lib.to_object(webhook.WebhookResponseType, response)
|
|
19
|
+
|
|
20
|
+
webhook_details = (
|
|
21
|
+
models.WebhookRegistrationDetails(
|
|
22
|
+
carrier_id=settings.carrier_id,
|
|
23
|
+
carrier_name=settings.carrier_name,
|
|
24
|
+
webhook_identifier=details.id,
|
|
25
|
+
secret=details.secret,
|
|
26
|
+
meta=lib.to_dict(details),
|
|
27
|
+
)
|
|
28
|
+
if details and details.id
|
|
29
|
+
else None
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return webhook_details, messages
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def webhook_registration_request(
|
|
36
|
+
payload: models.WebhookRegistrationRequest,
|
|
37
|
+
settings: provider_utils.Settings,
|
|
38
|
+
) -> lib.Serializable:
|
|
39
|
+
"""Create a Teleship webhook registration request"""
|
|
40
|
+
|
|
41
|
+
request = teleship.WebhookRequestType(
|
|
42
|
+
url=payload.url,
|
|
43
|
+
description=payload.description,
|
|
44
|
+
enabled=True,
|
|
45
|
+
enabledEvents=(payload.enabled_events if any(payload.enabled_events) else ["*"]),
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return lib.Serializable(request, lib.to_dict)
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import attr
|
|
2
|
+
import jstruct
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@attr.s(auto_attribs=True)
|
|
7
|
+
class UnitWeightType:
|
|
8
|
+
unit: typing.Optional[str] = None
|
|
9
|
+
value: typing.Optional[float] = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@attr.s(auto_attribs=True)
|
|
13
|
+
class ConsigneeChargesType:
|
|
14
|
+
amount: typing.Optional[float] = None
|
|
15
|
+
currency: typing.Optional[str] = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@attr.s(auto_attribs=True)
|
|
19
|
+
class CommodityType:
|
|
20
|
+
title: typing.Optional[str] = None
|
|
21
|
+
description: typing.Optional[str] = None
|
|
22
|
+
hsCode: typing.Optional[str] = None
|
|
23
|
+
sku: typing.Optional[str] = None
|
|
24
|
+
quantity: typing.Optional[int] = None
|
|
25
|
+
value: typing.Optional[ConsigneeChargesType] = jstruct.JStruct[ConsigneeChargesType]
|
|
26
|
+
unitWeight: typing.Optional[UnitWeightType] = jstruct.JStruct[UnitWeightType]
|
|
27
|
+
countryOfOrigin: typing.Optional[str] = None
|
|
28
|
+
category: typing.Optional[str] = None
|
|
29
|
+
imageUrl: typing.Optional[str] = None
|
|
30
|
+
productUrl: typing.Optional[str] = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@attr.s(auto_attribs=True)
|
|
34
|
+
class CustomsType:
|
|
35
|
+
contentType: typing.Optional[str] = None
|
|
36
|
+
incoterms: typing.Optional[str] = None
|
|
37
|
+
invoiceNumber: typing.Optional[str] = None
|
|
38
|
+
invoiceDate: typing.Optional[str] = None
|
|
39
|
+
EORI: typing.Optional[str] = None
|
|
40
|
+
VAT: typing.Optional[str] = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@attr.s(auto_attribs=True)
|
|
44
|
+
class MessageType:
|
|
45
|
+
code: typing.Optional[int] = None
|
|
46
|
+
level: typing.Optional[str] = None
|
|
47
|
+
timestamp: typing.Optional[str] = None
|
|
48
|
+
message: typing.Optional[str] = None
|
|
49
|
+
details: typing.Optional[typing.List[str]] = None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@attr.s(auto_attribs=True)
|
|
53
|
+
class AddressType:
|
|
54
|
+
line1: typing.Optional[str] = None
|
|
55
|
+
line2: typing.Optional[str] = None
|
|
56
|
+
city: typing.Optional[str] = None
|
|
57
|
+
state: typing.Optional[str] = None
|
|
58
|
+
postcode: typing.Optional[str] = None
|
|
59
|
+
country: typing.Optional[str] = None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@attr.s(auto_attribs=True)
|
|
63
|
+
class ShipType:
|
|
64
|
+
name: typing.Optional[str] = None
|
|
65
|
+
email: typing.Optional[str] = None
|
|
66
|
+
phone: typing.Optional[str] = None
|
|
67
|
+
company: typing.Optional[str] = None
|
|
68
|
+
address: typing.Optional[AddressType] = jstruct.JStruct[AddressType]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@attr.s(auto_attribs=True)
|
|
72
|
+
class DutiesTaxesRequestType:
|
|
73
|
+
messages: typing.Optional[typing.List[MessageType]] = jstruct.JList[MessageType]
|
|
74
|
+
shipTo: typing.Optional[ShipType] = jstruct.JStruct[ShipType]
|
|
75
|
+
shipFrom: typing.Optional[ShipType] = jstruct.JStruct[ShipType]
|
|
76
|
+
commodities: typing.Optional[typing.List[CommodityType]] = jstruct.JList[CommodityType]
|
|
77
|
+
customs: typing.Optional[CustomsType] = jstruct.JStruct[CustomsType]
|
|
78
|
+
currency: typing.Optional[str] = None
|
|
79
|
+
orderTrackingReference: typing.Optional[int] = None
|
|
80
|
+
freightCost: typing.Optional[ConsigneeChargesType] = jstruct.JStruct[ConsigneeChargesType]
|
|
81
|
+
consigneeCharges: typing.Optional[ConsigneeChargesType] = jstruct.JStruct[ConsigneeChargesType]
|
|
82
|
+
insuranceValue: typing.Optional[ConsigneeChargesType] = jstruct.JStruct[ConsigneeChargesType]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import attr
|
|
2
|
+
import jstruct
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@attr.s(auto_attribs=True)
|
|
7
|
+
class ChargeType:
|
|
8
|
+
name: typing.Optional[str] = None
|
|
9
|
+
amount: typing.Optional[float] = None
|
|
10
|
+
currency: typing.Optional[str] = None
|
|
11
|
+
rate: typing.Optional[float] = None
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@attr.s(auto_attribs=True)
|
|
15
|
+
class CommodityType:
|
|
16
|
+
itemNumber: typing.Optional[int] = None
|
|
17
|
+
title: typing.Optional[str] = None
|
|
18
|
+
charges: typing.Optional[typing.List[ChargeType]] = jstruct.JList[ChargeType]
|
|
19
|
+
restrictions: typing.Optional[typing.List[typing.Any]] = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@attr.s(auto_attribs=True)
|
|
23
|
+
class DutiesTaxesResponseType:
|
|
24
|
+
messages: typing.Optional[typing.List[typing.Any]] = None
|
|
25
|
+
price: typing.Optional[float] = None
|
|
26
|
+
currency: typing.Optional[str] = None
|
|
27
|
+
charges: typing.Optional[typing.List[ChargeType]] = jstruct.JList[ChargeType]
|
|
28
|
+
commodities: typing.Optional[typing.List[CommodityType]] = jstruct.JList[CommodityType]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import attr
|
|
2
|
+
import jstruct
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@attr.s(auto_attribs=True)
|
|
7
|
+
class MessageType:
|
|
8
|
+
code: typing.Optional[int] = None
|
|
9
|
+
level: typing.Optional[str] = None
|
|
10
|
+
message: typing.Optional[str] = None
|
|
11
|
+
timestamp: typing.Optional[str] = None
|
|
12
|
+
details: typing.Optional[typing.List[str]] = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@attr.s(auto_attribs=True)
|
|
16
|
+
class ErrorResponseType:
|
|
17
|
+
messages: typing.Optional[typing.List[MessageType]] = jstruct.JList[MessageType]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import attr
|
|
2
|
+
import jstruct
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@attr.s(auto_attribs=True)
|
|
7
|
+
class AddressAddressType:
|
|
8
|
+
line1: typing.Optional[str] = None
|
|
9
|
+
line2: typing.Optional[str] = None
|
|
10
|
+
city: typing.Optional[str] = None
|
|
11
|
+
state: typing.Optional[str] = None
|
|
12
|
+
postcode: typing.Optional[int] = None
|
|
13
|
+
country: typing.Optional[str] = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@attr.s(auto_attribs=True)
|
|
17
|
+
class ManifestRequestAddressType:
|
|
18
|
+
name: typing.Optional[str] = None
|
|
19
|
+
email: typing.Optional[str] = None
|
|
20
|
+
phone: typing.Optional[str] = None
|
|
21
|
+
company: typing.Optional[str] = None
|
|
22
|
+
address: typing.Optional[AddressAddressType] = jstruct.JStruct[AddressAddressType]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@attr.s(auto_attribs=True)
|
|
26
|
+
class MessageType:
|
|
27
|
+
code: typing.Optional[int] = None
|
|
28
|
+
level: typing.Optional[str] = None
|
|
29
|
+
timestamp: typing.Optional[str] = None
|
|
30
|
+
message: typing.Optional[str] = None
|
|
31
|
+
details: typing.Optional[typing.List[str]] = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@attr.s(auto_attribs=True)
|
|
35
|
+
class ManifestRequestType:
|
|
36
|
+
messages: typing.Optional[typing.List[MessageType]] = jstruct.JList[MessageType]
|
|
37
|
+
shipmentIds: typing.Optional[typing.List[str]] = None
|
|
38
|
+
reference: typing.Optional[str] = None
|
|
39
|
+
address: typing.Optional[ManifestRequestAddressType] = jstruct.JStruct[ManifestRequestAddressType]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import attr
|
|
2
|
+
import jstruct
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@attr.s(auto_attribs=True)
|
|
7
|
+
class AddressAddressType:
|
|
8
|
+
line1: typing.Optional[str] = None
|
|
9
|
+
line2: typing.Optional[str] = None
|
|
10
|
+
city: typing.Optional[str] = None
|
|
11
|
+
state: typing.Optional[str] = None
|
|
12
|
+
postcode: typing.Optional[int] = None
|
|
13
|
+
country: typing.Optional[str] = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@attr.s(auto_attribs=True)
|
|
17
|
+
class ManifestResponseAddressType:
|
|
18
|
+
name: typing.Optional[str] = None
|
|
19
|
+
email: typing.Optional[str] = None
|
|
20
|
+
phone: typing.Optional[str] = None
|
|
21
|
+
company: typing.Optional[str] = None
|
|
22
|
+
address: typing.Optional[AddressAddressType] = jstruct.JStruct[AddressAddressType]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@attr.s(auto_attribs=True)
|
|
26
|
+
class ManifestResponseType:
|
|
27
|
+
id: typing.Optional[str] = None
|
|
28
|
+
status: typing.Optional[str] = None
|
|
29
|
+
reference: typing.Optional[str] = None
|
|
30
|
+
createdAt: typing.Optional[str] = None
|
|
31
|
+
address: typing.Optional[ManifestResponseAddressType] = jstruct.JStruct[ManifestResponseAddressType]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import attr
|
|
2
|
+
import jstruct
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@attr.s(auto_attribs=True)
|
|
7
|
+
class AddressAddressType:
|
|
8
|
+
line1: typing.Optional[str] = None
|
|
9
|
+
line2: typing.Optional[str] = None
|
|
10
|
+
city: typing.Optional[str] = None
|
|
11
|
+
state: typing.Optional[str] = None
|
|
12
|
+
postcode: typing.Optional[str] = None
|
|
13
|
+
country: typing.Optional[str] = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@attr.s(auto_attribs=True)
|
|
17
|
+
class PickupRequestAddressType:
|
|
18
|
+
name: typing.Optional[str] = None
|
|
19
|
+
email: typing.Optional[str] = None
|
|
20
|
+
phone: typing.Optional[str] = None
|
|
21
|
+
company: typing.Optional[str] = None
|
|
22
|
+
address: typing.Optional[AddressAddressType] = jstruct.JStruct[AddressAddressType]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@attr.s(auto_attribs=True)
|
|
26
|
+
class PickupRequestType:
|
|
27
|
+
startAt: typing.Optional[str] = None
|
|
28
|
+
endAt: typing.Optional[str] = None
|
|
29
|
+
shipmentIds: typing.Optional[typing.List[str]] = None
|
|
30
|
+
address: typing.Optional[PickupRequestAddressType] = jstruct.JStruct[PickupRequestAddressType]
|
|
31
|
+
reference: typing.Optional[str] = None
|