-
-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
revert: deprecated eshipper_xml and usps* extensions
- Loading branch information
Showing
463 changed files
with
264,240 additions
and
3,333 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# karrio.eshipper_xml | ||
|
||
This package is a eShipper XML extension of the [karrio](https://pypi.org/project/karrio) multi carrier shipping SDK. | ||
|
||
## Requirements | ||
|
||
`Python 3.7+` | ||
|
||
## Installation | ||
|
||
```bash | ||
pip install karrio.eshipper_xml | ||
``` | ||
|
||
## Usage | ||
|
||
```python | ||
import karrio | ||
from karrio.mappers.eshipper_xml.settings import Settings | ||
|
||
|
||
# Initialize a carrier gateway | ||
eshipper_xml = karrio.gateway["eshipper_xml"].create( | ||
Settings( | ||
... | ||
) | ||
) | ||
``` | ||
|
||
Check the [karrio Mutli-carrier SDK docs](https://docs.karrio.io) for Shipping API requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
SCHEMAS=./vendor/schemas | ||
LIB_MODULES=./karrio/schemas/eshipper_xml | ||
find "${LIB_MODULES}" -name "*.py" -exec rm -r {} \; | ||
touch "${LIB_MODULES}/__init__.py" | ||
|
||
generateDS --no-namespace-defs -o "${LIB_MODULES}/quote_request.py" $SCHEMAS/quote_request.xsd | ||
generateDS --no-namespace-defs -o "${LIB_MODULES}/quote_reply.py" $SCHEMAS/quote_reply.xsd | ||
generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_request.py" $SCHEMAS/shipping_request.xsd | ||
generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_reply.py" $SCHEMAS/shipping_reply.xsd | ||
generateDS --no-namespace-defs -o "${LIB_MODULES}/error.py" $SCHEMAS/error.xsd | ||
generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_request.py" $SCHEMAS/shipment_cancel_request.xsd | ||
generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_reply.py" $SCHEMAS/shipment_cancel_reply.xsd |
21 changes: 21 additions & 0 deletions
21
modules/connectors/eshipper_xml/karrio/mappers/eshipper_xml/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from karrio.core.metadata import Metadata | ||
|
||
from karrio.mappers.eshipper_xml.mapper import Mapper | ||
from karrio.mappers.eshipper_xml.proxy import Proxy | ||
from karrio.mappers.eshipper_xml.settings import Settings | ||
import karrio.providers.eshipper_xml.units as units | ||
|
||
|
||
METADATA = Metadata( | ||
id="eshipper_xml", | ||
label="eShipper XML", | ||
is_hub=True, | ||
# Integrations | ||
Mapper=Mapper, | ||
Proxy=Proxy, | ||
Settings=Settings, | ||
# Data Units | ||
options=units.ShippingOption, | ||
services=units.ShippingService, | ||
hub_carriers=units.CARRIER_IDS, | ||
) |
55 changes: 55 additions & 0 deletions
55
modules/connectors/eshipper_xml/karrio/mappers/eshipper_xml/mapper.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from typing import List, Tuple | ||
from karrio.api.mapper import Mapper as BaseMapper | ||
from karrio.mappers.eshipper_xml.settings import Settings | ||
from karrio.core.utils.serializable import Deserializable, Serializable | ||
from karrio.core.models import ( | ||
RateRequest, | ||
ShipmentRequest, | ||
ShipmentDetails, | ||
ShipmentCancelRequest, | ||
RateDetails, | ||
Message, | ||
ConfirmationDetails, | ||
) | ||
from karrio.providers.eshipper_xml import ( | ||
parse_quote_reply, | ||
quote_request, | ||
parse_shipping_reply, | ||
shipping_request, | ||
shipment_cancel_request, | ||
parse_shipment_cancel_reply, | ||
) | ||
|
||
|
||
class Mapper(BaseMapper): | ||
settings: Settings | ||
|
||
# Request Mappers | ||
|
||
def create_rate_request(self, payload: RateRequest) -> Serializable: | ||
return quote_request(payload, self.settings) | ||
|
||
def create_shipment_request(self, payload: ShipmentRequest) -> Serializable: | ||
return shipping_request(payload, self.settings) | ||
|
||
def create_cancel_shipment_request( | ||
self, payload: ShipmentCancelRequest | ||
) -> Serializable: | ||
return shipment_cancel_request(payload, self.settings) | ||
|
||
# Response Parsers | ||
|
||
def parse_rate_response( | ||
self, response: Deserializable | ||
) -> Tuple[List[RateDetails], List[Message]]: | ||
return parse_quote_reply(response, self.settings) | ||
|
||
def parse_shipment_response( | ||
self, response: Deserializable | ||
) -> Tuple[ShipmentDetails, List[Message]]: | ||
return parse_shipping_reply(response, self.settings) | ||
|
||
def parse_cancel_shipment_response( | ||
self, response: Deserializable | ||
) -> Tuple[ConfirmationDetails, List[Message]]: | ||
return parse_shipment_cancel_reply(response, self.settings) |
38 changes: 38 additions & 0 deletions
38
modules/connectors/eshipper_xml/karrio/mappers/eshipper_xml/proxy.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from karrio.core.utils import XP, request as http | ||
from karrio.api.proxy import Proxy as BaseProxy | ||
from karrio.mappers.eshipper_xml.settings import Settings | ||
from karrio.core.utils.serializable import Serializable, Deserializable | ||
|
||
|
||
class Proxy(BaseProxy): | ||
settings: Settings | ||
|
||
def get_rates(self, request: Serializable) -> Deserializable: | ||
response = http( | ||
url=self.settings.server_url, | ||
data=request.serialize(), | ||
trace=self.trace_as("xml"), | ||
method="POST", | ||
headers={"Content-Type": "application/xml"}, | ||
) | ||
return Deserializable(response, XP.to_xml) | ||
|
||
def create_shipment(self, request: Serializable) -> Deserializable: | ||
response = http( | ||
url=self.settings.server_url, | ||
data=request.serialize(), | ||
trace=self.trace_as("xml"), | ||
method="POST", | ||
headers={"Content-Type": "application/xml"}, | ||
) | ||
return Deserializable(response, XP.to_xml) | ||
|
||
def cancel_shipment(self, request: Serializable) -> Deserializable: | ||
response = http( | ||
url=self.settings.server_url, | ||
data=request.serialize(), | ||
trace=self.trace_as("xml"), | ||
method="POST", | ||
headers={"Content-Type": "application/xml"}, | ||
) | ||
return Deserializable(response, XP.to_xml) |
19 changes: 19 additions & 0 deletions
19
modules/connectors/eshipper_xml/karrio/mappers/eshipper_xml/settings.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
"""Karrio eshipper_xml connection settings.""" | ||
|
||
import attr | ||
from karrio.providers.eshipper_xml.utils import Settings as BaseSettings | ||
|
||
|
||
@attr.s(auto_attribs=True) | ||
class Settings(BaseSettings): | ||
"""eshipper_xml connection settings.""" | ||
|
||
username: str | ||
password: str | ||
|
||
id: str = None | ||
test_mode: bool = False | ||
carrier_id: str = "eshipper_xml" | ||
account_country_code: str = None | ||
metadata: dict = {} | ||
config: dict = {} |
9 changes: 9 additions & 0 deletions
9
modules/connectors/eshipper_xml/karrio/providers/eshipper_xml/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from karrio.providers.eshipper_xml.quote import parse_quote_reply, quote_request | ||
from karrio.providers.eshipper_xml.shipping import ( | ||
parse_shipping_reply, | ||
shipping_request, | ||
) | ||
from karrio.providers.eshipper_xml.void_shipment import ( | ||
shipment_cancel_request, | ||
parse_shipment_cancel_reply, | ||
) |
19 changes: 19 additions & 0 deletions
19
modules/connectors/eshipper_xml/karrio/providers/eshipper_xml/error.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from typing import List | ||
from karrio.schemas.eshipper_xml.error import ErrorType | ||
from karrio.core.models import Message | ||
from karrio.core.utils import Element, XP | ||
from karrio.providers.eshipper_xml.utils import Settings | ||
|
||
|
||
def parse_error_response(response: Element, settings: Settings) -> List[Message]: | ||
errors = XP.find("Error", response, ErrorType) | ||
return [_extract_error(node, settings) for node in errors] | ||
|
||
|
||
def _extract_error(error: ErrorType, settings: Settings) -> Message: | ||
return Message( | ||
code="Error", | ||
carrier_name=settings.carrier_name, | ||
carrier_id=settings.carrier_id, | ||
message=error.Message, | ||
) |
175 changes: 175 additions & 0 deletions
175
modules/connectors/eshipper_xml/karrio/providers/eshipper_xml/quote.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
from karrio.schemas.eshipper_xml.quote_reply import QuoteType | ||
from karrio.schemas.eshipper_xml.quote_request import ( | ||
EShipper, | ||
QuoteRequestType, | ||
FromType, | ||
ToType, | ||
PackagesType, | ||
PackageType, | ||
) | ||
|
||
import typing | ||
import karrio.lib as lib | ||
import karrio.core.models as models | ||
import karrio.providers.eshipper_xml.error as provider_error | ||
import karrio.providers.eshipper_xml.units as provider_units | ||
import karrio.providers.eshipper_xml.utils as provider_utils | ||
|
||
|
||
def parse_quote_reply( | ||
_response: lib.Deserializable[lib.Element], | ||
settings: provider_utils.Settings, | ||
) -> typing.Tuple[typing.List[models.RateDetails], typing.List[models.Message]]: | ||
response = _response.deserialize() | ||
estimates = lib.find_element("Quote", response) | ||
return ( | ||
[_extract_rate(node, settings) for node in estimates], | ||
provider_error.parse_error_response(response, settings), | ||
) | ||
|
||
|
||
def _extract_rate( | ||
node: lib.Element, settings: provider_utils.Settings | ||
) -> models.RateDetails: | ||
quote = lib.to_object(QuoteType, node) | ||
rate_provider, service, service_name = provider_units.ShippingService.info( | ||
quote.serviceId, quote.carrierId, quote.serviceName, quote.carrierName | ||
) | ||
charges = [ | ||
("Base charge", quote.baseCharge), | ||
("Fuel surcharge", quote.fuelSurcharge), | ||
*((surcharge.name, surcharge.amount) for surcharge in quote.Surcharge), | ||
] | ||
|
||
return models.RateDetails( | ||
carrier_name=settings.carrier_name, | ||
carrier_id=settings.carrier_id, | ||
currency=quote.currency, | ||
service=service, | ||
total_charge=lib.to_decimal(quote.totalCharge), | ||
transit_days=quote.transitDays, | ||
extra_charges=[ | ||
models.ChargeDetails( | ||
name=name, | ||
currency="CAD", | ||
amount=lib.to_decimal(amount), | ||
) | ||
for name, amount in charges | ||
if amount | ||
], | ||
meta=dict(rate_provider=rate_provider, service_name=service_name), | ||
) | ||
|
||
|
||
def quote_request( | ||
payload: models.RateRequest, | ||
settings: provider_utils.Settings, | ||
) -> lib.Serializable: | ||
shipper = lib.to_address(payload.shipper) | ||
recipient = lib.to_address(payload.recipient) | ||
packages = lib.to_packages( | ||
payload.parcels, | ||
package_option_type=provider_units.ShippingOption, | ||
required=["weight", "height", "width", "length"], | ||
) | ||
options = lib.to_shipping_options( | ||
payload.options, | ||
package_options=packages.options, | ||
initializer=provider_units.shipping_options_initializer, | ||
) | ||
packaging_type = provider_units.PackagingType[ | ||
packages.package_type or "eshipper_boxes" | ||
].value | ||
packaging = ( | ||
"Pallet" | ||
if packaging_type in [provider_units.PackagingType.pallet.value] | ||
else "Package" | ||
) | ||
service = ( | ||
lib.to_services(payload.services, provider_units.ShippingService).first | ||
or provider_units.ShippingService.eshipper_all | ||
) | ||
|
||
request = EShipper( | ||
username=settings.username, | ||
password=settings.password, | ||
version="3.0.0", | ||
QuoteRequest=QuoteRequestType( | ||
saturdayPickupRequired=options.eshipper_saturday_pickup_required.state, | ||
homelandSecurity=options.eshipper_homeland_security.state, | ||
pierCharge=None, | ||
exhibitionConventionSite=options.eshipper_exhibition_convention_site.state, | ||
militaryBaseDelivery=options.eshipper_military_base_delivery.state, | ||
customsIn_bondFreight=options.eshipper_customs_in_bond_freight.state, | ||
limitedAccess=options.eshipper_limited_access.state, | ||
excessLength=options.eshipper_excess_length.state, | ||
tailgatePickup=options.eshipper_tailgate_pickup.state, | ||
residentialPickup=options.eshipper_residential_pickup.state, | ||
crossBorderFee=None, | ||
notifyRecipient=options.eshipper_notify_recipient.state, | ||
singleShipment=options.eshipper_single_shipment.state, | ||
tailgateDelivery=options.eshipper_tailgate_delivery.state, | ||
residentialDelivery=options.eshipper_residential_delivery.state, | ||
insuranceType=options.insurance.state is not None, | ||
scheduledShipDate=None, | ||
insideDelivery=options.eshipper_inside_delivery.state, | ||
isSaturdayService=options.eshipper_is_saturday_service.state, | ||
dangerousGoodsType=options.eshipper_dangerous_goods_type.state, | ||
serviceId=service.value, | ||
stackable=options.eshipper_stackable.state, | ||
From=FromType( | ||
id=None, | ||
company=shipper.company_name or " ", | ||
instructions=None, | ||
email=shipper.email, | ||
attention=shipper.person_name, | ||
phone=shipper.phone_number, | ||
tailgateRequired=None, | ||
residential=shipper.residential, | ||
address1=shipper.street, | ||
address2=lib.text(shipper.address_line2), | ||
city=shipper.city, | ||
state=shipper.state_code, | ||
zip=shipper.postal_code, | ||
country=shipper.country_code, | ||
), | ||
To=ToType( | ||
id=None, | ||
company=recipient.company_name or " ", | ||
notifyRecipient=None, | ||
instructions=None, | ||
email=recipient.email, | ||
attention=recipient.person_name, | ||
phone=recipient.phone_number, | ||
tailgateRequired=None, | ||
residential=recipient.residential, | ||
address1=recipient.street, | ||
address2=lib.text(recipient.address_line2), | ||
city=recipient.city, | ||
state=recipient.state_code, | ||
zip=recipient.postal_code, | ||
country=recipient.country_code, | ||
), | ||
COD=None, | ||
Packages=PackagesType( | ||
Package=[ | ||
PackageType( | ||
length=provider_utils.ceil(package.length.IN), | ||
width=provider_utils.ceil(package.width.IN), | ||
height=provider_utils.ceil(package.height.IN), | ||
weight=provider_utils.ceil(package.weight.LB), | ||
type_=packaging_type, | ||
freightClass=package.parcel.freight_class, | ||
nmfcCode=None, | ||
insuranceAmount=package.options.insurance.state, | ||
codAmount=package.options.cash_on_delivery.state, | ||
description=package.parcel.description, | ||
) | ||
for package in packages | ||
], | ||
type_=packaging, | ||
), | ||
), | ||
) | ||
|
||
return lib.Serializable(request, provider_utils.standard_request_serializer) |
Oops, something went wrong.