karrio-easypost 2025.5.7__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.
@@ -61,23 +61,11 @@ def rate_request(payload: models.RateRequest, _) -> lib.Serializable:
61
61
  initializer=provider_units.shipping_options_initializer,
62
62
  )
63
63
  is_intl = shipper.country_code != recipient.country_code
64
- customs = (
65
- models.Customs(
66
- commodities=(
67
- package.parcel.items
68
- if any(package.parcel.items)
69
- else [
70
- models.Commodity(
71
- sku="0000",
72
- quantity=1,
73
- weight=package.weight.value,
74
- weight_unit=package.weight_unit.value,
75
- )
76
- ]
77
- )
78
- )
79
- if is_intl
80
- else None
64
+ customs = lib.to_customs_info(
65
+ payload.customs,
66
+ shipper=payload.shipper,
67
+ recipient=payload.recipient,
68
+ weight_unit=package.weight_unit.value,
81
69
  )
82
70
 
83
71
  requests = easypost.ShipmentRequest(
@@ -163,9 +151,9 @@ def rate_request(payload: models.RateRequest, _) -> lib.Serializable:
163
151
  options={option.code: option.state for _, option in options.items()},
164
152
  customs_info=(
165
153
  easypost.CustomsInfo(
166
- contents_type="other",
167
- customs_certify=True,
168
- customs_signer=shipper.person_name,
154
+ contents_type=customs.content_type or "other",
155
+ customs_certify=customs.certify if customs.certify is not None else True,
156
+ customs_signer=customs.signer or shipper.person_name,
169
157
  customs_items=[
170
158
  easypost.CustomsItem(
171
159
  description=lib.text(
@@ -182,10 +170,14 @@ def rate_request(payload: models.RateRequest, _) -> lib.Serializable:
182
170
  printed_commodity_identifier=(item.sku or item.id),
183
171
  hs_tariff_number=item.hs_code,
184
172
  )
185
- for item in customs.commodities
173
+ for item in (
174
+ package.parcel.items
175
+ if any(package.parcel.items)
176
+ else customs.commodities or []
177
+ )
186
178
  ],
187
179
  )
188
- if customs
180
+ if payload.customs and is_intl
189
181
  else None
190
182
  ),
191
183
  )
@@ -5,6 +5,16 @@ import karrio.core.units as units
5
5
  import karrio.core.models as models
6
6
 
7
7
 
8
+ # EasyPost API carrier name normalization mapping
9
+ # Maps EasyPost's carrier variations to Karrio's standard CarrierId enum names
10
+ CARRIER_NAME_NORMALIZATION = {
11
+ "UPSDAP": "UPS",
12
+ "UPS DAP": "UPS",
13
+ "FedExDefault": "FedEx",
14
+ "FedEx Default": "FedEx",
15
+ }
16
+
17
+
8
18
  class LabelType(lib.Enum):
9
19
  PDF = "PDF"
10
20
  ZPL = "ZPL"
@@ -862,13 +872,38 @@ class Service(lib.StrEnum):
862
872
 
863
873
  @staticmethod
864
874
  def info(serviceName, carrier):
865
- rate_provider = CarrierId.map(carrier).name_or_key
866
- service = Service.map(serviceName)
875
+ # Normalize carrier name to handle EasyPost API variations
876
+ normalized_carrier = CARRIER_NAME_NORMALIZATION.get(carrier, carrier)
877
+ rate_provider = CarrierId.map(normalized_carrier).name_or_key
878
+
879
+ # Try carrier-qualified lookup first to avoid service name collisions
880
+ service_code = None
881
+ carrier_enum = CarrierId.map(normalized_carrier)
882
+
883
+ if carrier_enum.name and serviceName:
884
+ # Construct carrier-qualified service code: easypost_{carrier}_{service}
885
+ carrier_code = carrier_enum.name
886
+ service_snake = lib.to_snake_case(serviceName)
887
+ qualified_service_name = f"easypost_{carrier_code}_{service_snake}"
888
+
889
+ # Check if the qualified service exists
890
+ # Note: We cannot use Service.map() because Python enums with duplicate
891
+ # values create aliases, so Service.easypost_usps_priority and
892
+ # Service.easypost_canadapost_priority are the SAME object (both = 'Priority')
893
+ if hasattr(Service, qualified_service_name):
894
+ service_code = qualified_service_name
895
+
896
+ # Fallback to original behavior if qualified lookup fails
897
+ if not service_code:
898
+ service = Service.map(serviceName)
899
+ service_code = service.name_or_key
900
+
901
+ # Format the service name for display
867
902
  service_name = re.sub(
868
- r"((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))", r" \1", service.name_or_key
903
+ r"((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))", r" \1", service_code
869
904
  ).replace("easypost_", "")
870
905
 
871
- return rate_provider, service.name_or_key, service_name
906
+ return rate_provider, service_code, service_name
872
907
 
873
908
 
874
909
  class CarrierId(lib.StrEnum):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: karrio_easypost
3
- Version: 2025.5.7
3
+ Version: 2026.1.1
4
4
  Summary: Karrio - EasyPost Shipping extension
5
5
  Author-email: karrio <hello@karrio.io>
6
6
  License-Expression: LGPL-3.0
@@ -5,9 +5,9 @@ karrio/mappers/easypost/settings.py,sha256=tVxN6QXlpYgjslfMRzc-6uvI1E-vp6H6f_NsD
5
5
  karrio/plugins/easypost/__init__.py,sha256=UwD6JC4LkF47ZodzuHvaq8l__713e_aCLTej3SkEhH4,484
6
6
  karrio/providers/easypost/__init__.py,sha256=v89eaMBV-Kn7Za7WzrXpSkKfFG2HSRB0SXByoI2hOec,333
7
7
  karrio/providers/easypost/error.py,sha256=GrONkEpEi8ujKNvd4I9Z9xGfqFrc4QE2wOkoMJOFEjk,953
8
- karrio/providers/easypost/rate.py,sha256=_uJ_9PgB5AM_oMDjAsY_wFd_DUz-zm_zu4qPkSyZHTY,7710
8
+ karrio/providers/easypost/rate.py,sha256=lT8b5WUT0PBGa66sq6G97LBqDZ559esaKJmaOiydnpY,7676
9
9
  karrio/providers/easypost/tracking.py,sha256=DvjNyjLDFHDZ9Iu9zJjZwxOBCb8rXz3uBtwu8dlAmxg,4913
10
- karrio/providers/easypost/units.py,sha256=JCJBcJXV017JChD7DCj-YbMs_c-DhhxttyG25NhFS00,53298
10
+ karrio/providers/easypost/units.py,sha256=4VrHtGONrsqDv7zwWu_GC37N_V8RjXV1gf3tAUR_yV0,54794
11
11
  karrio/providers/easypost/utils.py,sha256=rJ1uxvaOXcwCAbPmiklk0UoJwhbix0sjVc6jV1BWbtQ,774
12
12
  karrio/providers/easypost/shipment/__init__.py,sha256=oEO3ToyRIVyE5mcc_exdZRpM6WMu6PMD2UpdkUJrKqI,232
13
13
  karrio/providers/easypost/shipment/cancel.py,sha256=QEIkm4aPwzOyFMV4fvx_7b8VErwIhcBGl9ZszQM5nsM,1010
@@ -18,9 +18,9 @@ karrio/schemas/easypost/shipment_purchase.py,sha256=xNQWUKV6aYFFdTn7xLCjjtya0h-o
18
18
  karrio/schemas/easypost/shipment_request.py,sha256=7HirvgDktcppvHlEeMz49ryK6sPWIBP-c1_1xE3y8ow,2858
19
19
  karrio/schemas/easypost/shipments_response.py,sha256=KgWbIoPvI1NoQOGoV30-K3Dl6JFkKdAS3B3yHQfb6R4,8957
20
20
  karrio/schemas/easypost/trackers_response.py,sha256=Q0Z74hKZYLDmfKh7lzxM7cfe3x-z-LXve94d7s3r9Kw,2915
21
- karrio_easypost-2025.5.7.dist-info/licenses/LICENSE,sha256=qvVLDB3Y1leH0p_1m30RxZrOGOx8F9O5eZIwdyVzcuQ,7651
22
- karrio_easypost-2025.5.7.dist-info/METADATA,sha256=vkvKW878hnvvHaHVnBtQj9yrQht3PAhImJTFYtYK0qg,1040
23
- karrio_easypost-2025.5.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
- karrio_easypost-2025.5.7.dist-info/entry_points.txt,sha256=mArG7sxxZUl07ycYJn7BGzz1uv-hZPVROniK64EbUz4,61
25
- karrio_easypost-2025.5.7.dist-info/top_level.txt,sha256=FZCY8Nwft8oEGHdl--xku8P3TrnOxu5dETEU_fWpRSM,20
26
- karrio_easypost-2025.5.7.dist-info/RECORD,,
21
+ karrio_easypost-2026.1.1.dist-info/licenses/LICENSE,sha256=qvVLDB3Y1leH0p_1m30RxZrOGOx8F9O5eZIwdyVzcuQ,7651
22
+ karrio_easypost-2026.1.1.dist-info/METADATA,sha256=kEheX5Eq5TGqFNaL59ImNTekUYQviKWKL-93uRM_XkU,1040
23
+ karrio_easypost-2026.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
+ karrio_easypost-2026.1.1.dist-info/entry_points.txt,sha256=mArG7sxxZUl07ycYJn7BGzz1uv-hZPVROniK64EbUz4,61
25
+ karrio_easypost-2026.1.1.dist-info/top_level.txt,sha256=FZCY8Nwft8oEGHdl--xku8P3TrnOxu5dETEU_fWpRSM,20
26
+ karrio_easypost-2026.1.1.dist-info/RECORD,,