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.
Files changed (49) hide show
  1. karrio/mappers/teleship/__init__.py +4 -0
  2. karrio/mappers/teleship/hooks.py +27 -0
  3. karrio/mappers/teleship/mapper.py +114 -0
  4. karrio/mappers/teleship/proxy.py +239 -0
  5. karrio/mappers/teleship/settings.py +21 -0
  6. karrio/plugins/teleship/__init__.py +32 -0
  7. karrio/providers/teleship/__init__.py +41 -0
  8. karrio/providers/teleship/duties.py +115 -0
  9. karrio/providers/teleship/error.py +44 -0
  10. karrio/providers/teleship/hooks/__init__.py +5 -0
  11. karrio/providers/teleship/hooks/event.py +163 -0
  12. karrio/providers/teleship/hooks/oauth.py +103 -0
  13. karrio/providers/teleship/manifest.py +68 -0
  14. karrio/providers/teleship/pickup/__init__.py +8 -0
  15. karrio/providers/teleship/pickup/cancel.py +43 -0
  16. karrio/providers/teleship/pickup/schedule.py +66 -0
  17. karrio/providers/teleship/rate.py +287 -0
  18. karrio/providers/teleship/shipment/__init__.py +9 -0
  19. karrio/providers/teleship/shipment/cancel.py +48 -0
  20. karrio/providers/teleship/shipment/create.py +322 -0
  21. karrio/providers/teleship/tracking.py +100 -0
  22. karrio/providers/teleship/units.py +154 -0
  23. karrio/providers/teleship/utils.py +57 -0
  24. karrio/providers/teleship/webhook/__init__.py +8 -0
  25. karrio/providers/teleship/webhook/deregister.py +47 -0
  26. karrio/providers/teleship/webhook/register.py +48 -0
  27. karrio/schemas/teleship/__init__.py +0 -0
  28. karrio/schemas/teleship/duties_taxes_request.py +82 -0
  29. karrio/schemas/teleship/duties_taxes_response.py +28 -0
  30. karrio/schemas/teleship/error_response.py +17 -0
  31. karrio/schemas/teleship/manifest_request.py +39 -0
  32. karrio/schemas/teleship/manifest_response.py +31 -0
  33. karrio/schemas/teleship/pickup_request.py +31 -0
  34. karrio/schemas/teleship/pickup_response.py +48 -0
  35. karrio/schemas/teleship/rate_request.py +128 -0
  36. karrio/schemas/teleship/rate_response.py +66 -0
  37. karrio/schemas/teleship/shipment_cancel_request.py +8 -0
  38. karrio/schemas/teleship/shipment_cancel_response.py +17 -0
  39. karrio/schemas/teleship/shipment_request.py +137 -0
  40. karrio/schemas/teleship/shipment_response.py +247 -0
  41. karrio/schemas/teleship/tracking_request.py +8 -0
  42. karrio/schemas/teleship/tracking_response.py +52 -0
  43. karrio/schemas/teleship/webhook_request.py +18 -0
  44. karrio/schemas/teleship/webhook_response.py +20 -0
  45. karrio_teleship-2025.5.dist-info/METADATA +44 -0
  46. karrio_teleship-2025.5.dist-info/RECORD +49 -0
  47. karrio_teleship-2025.5.dist-info/WHEEL +5 -0
  48. karrio_teleship-2025.5.dist-info/entry_points.txt +2 -0
  49. 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