Exemplo n.º 1
0
 def get_rates(
     self, request: Serializable[Union[RateV4Request, IntlRateV2Request]]
 ) -> Deserializable[str]:
     query = urllib.parse.urlencode(request.serialize())
     response = http(url=f"{self.settings.server_url}?{query}",
                     method="GET")
     return Deserializable(response, to_xml)
Exemplo n.º 2
0
 def get_tracking(
         self,
         request: Serializable[TrackFieldRequest]) -> Deserializable[str]:
     query = urllib.parse.urlencode(request.serialize())
     response = http(url=f"{self.settings.server_url}?{query}",
                     method="GET")
     return Deserializable(response, to_xml)
Exemplo n.º 3
0
    def get_tracking(self,
                     request: Serializable[List[str]]) -> Deserializable[str]:
        """
        get_tracking make parallel request for each pin
        """
        _throttle = 0.0

        def track(tracking_pin: str) -> str:
            nonlocal _throttle
            time.sleep(_throttle)
            _throttle += 0.025

            return http(
                url=
                f"{self.settings.server_url}/vis/track/pin/{tracking_pin}/detail",
                headers={
                    "Accept": "application/vnd.cpc.track-v2+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": f"{self.settings.language}-CA",
                },
                method="GET",
            )

        response: List[str] = exec_async(track, request.serialize())

        return Deserializable(XP.bundle_xml(xml_strings=response), XP.to_xml)
Exemplo n.º 4
0
    def create_shipment(
            self, request: Serializable[Pipeline]) -> Deserializable[str]:
        def process(job: Job):
            if job.data is None:
                return job.fallback

            return self._send_request(
                request=job.data,
                path=dict(
                    create="/EWS/V2/Shipping/ShippingService.asmx",
                    validate="/EWS/V2/Shipping/ShippingService.asmx",
                    document=
                    "/EWS/V1/ShippingDocuments/ShippingDocumentsService.asmx",
                )[job.id],
                soapaction=dict(
                    create="http://purolator.com/pws/service/v2/CreateShipment",
                    validate=
                    "http://purolator.com/pws/service/v2/ValidateShipment",
                    document="http://purolator.com/pws/service/v1/GetDocuments",
                )[job.id],
            )

        pipeline: Pipeline = request.serialize()
        _, *response = pipeline.apply(process)
        return Deserializable(XP.bundle_xml(response), XP.to_xml)
Exemplo n.º 5
0
 def get_rates(self, request: Serializable) -> Deserializable[str]:
     response = http(
         url=self.settings.server_url,
         data=bytearray(request.serialize(), "utf-8"),
         headers={"Content-Type": "application/xml"},
         method="POST",
     )
     return Deserializable(response, XP.to_xml)
Exemplo n.º 6
0
    def cancel_shipment(self, request: Serializable) -> Deserializable:
        response = self._send_request(
            path="/EWS/V2/Shipping/ShippingService.asmx",
            soapaction="http://purolator.com/pws/service/v2/VoidShipment",
            request=request,
        )

        return Deserializable(response, XP.to_xml)
Exemplo n.º 7
0
    def get_tracking(self,
                     request: Serializable[Envelope]) -> Deserializable[str]:
        response = self._send_request(
            path="/PWS/V1/Tracking/TrackingService.asmx",
            soapaction="http://purolator.com/pws/service/v1/TrackPackagesByPin",
            request=request,
        )

        return Deserializable(response, XP.to_xml)
Exemplo n.º 8
0
    def get_rates(self,
                  request: Serializable[Envelope]) -> Deserializable[str]:
        response = self._send_request(
            path="/EWS/V2/Estimating/EstimatingService.asmx",
            soapaction="http://purolator.com/pws/service/v2/GetFullEstimate",
            request=request,
        )

        return Deserializable(response, XP.to_xml)
Exemplo n.º 9
0
    def cancel_pickup(self,
                      request: Serializable[Envelope]) -> Deserializable[str]:
        response = self._send_request(
            path="/EWS/V1/PickUp/PickUpService.asmx",
            soapaction="http://purolator.com/pws/service/v1/VoidPickUp",
            request=request,
        )

        return Deserializable(response, XP.to_xml)
Exemplo n.º 10
0
    def create_shipment(self, request: Serializable[Pipeline]) -> Deserializable[str]:
        def _contract_shipment(job: Job):
            return http(
                url=f"{self.settings.server_url}/rs/{self.settings.customer_number}/{self.settings.customer_number}/shipment",
                data=bytearray(job.data.serialize(), "utf-8"),
                headers={
                    "Content-Type": "application/vnd.cpc.shipment-v8+xml",
                    "Accept": "application/vnd.cpc.shipment-v8+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": "en-CA",
                },
                method="POST",
            )

        def _non_contract_shipment(job: Job):
            return http(
                url=f"{self.settings.server_url}/rs/{self.settings.customer_number}/ncshipment",
                data=bytearray(job.data.serialize(), "utf-8"),
                headers={
                    "Accept": "application/vnd.cpc.ncshipment-v4+xml",
                    "Content-Type": "application/vnd.cpc.ncshipment-v4+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": "en-CA",
                },
                method="POST",
            )

        def _get_label(job: Job):
            label_string = http(
                decoder=lambda b: base64.encodebytes(b).decode("utf-8"),
                url=job.data,
                headers={
                    "Accept": "application/pdf",
                    "Authorization": f"Basic {self.settings.authorization}",
                },
                method="GET",
            )
            return f'<label>{label_string}</label>'

        def process(job: Job):
            if job.data is None:
                return job.fallback

            subprocess = {
                'contract_shipment': _contract_shipment,
                'non_contract_shipment': _non_contract_shipment,
                'shipment_label': _get_label
            }
            if job.id not in subprocess:
                raise PurplShipError(f"Unknown shipment request job id: {job.id}")

            return subprocess[job.id](job)

        pipeline: Pipeline = request.serialize()
        response = pipeline.apply(process)

        return Deserializable(bundle_xml(response), to_xml)
Exemplo n.º 11
0
 def get_tracking(
         self, request: Serializable[TrackRequest]) -> Deserializable[str]:
     response = http(
         url=f"{self.settings.server_url}/track",
         data=bytearray(request.serialize(), "utf-8"),
         headers={"Content-Type": "application/xml"},
         method="POST",
     )
     return Deserializable(response, to_xml)
Exemplo n.º 12
0
 def cancel_pickup(
         self,
         request: Serializable[CancelPURequest]) -> Deserializable[str]:
     response = http(
         url=self.settings.server_url,
         data=bytearray(request.serialize(), "utf-8"),
         headers={"Content-Type": "application/xml"},
         method="POST",
     )
     return Deserializable(response, to_xml)
Exemplo n.º 13
0
    def validate_address(
            self, request: Serializable[Envelope]) -> Deserializable[str]:
        response = self._send_request(
            path="/EWS/V2/ServiceAvailability/ServiceAvailabilityService.asmx",
            soapaction=
            "http://purolator.com/pws/service/v2/ValidateCityPostalCodeZip",
            request=request,
        )

        return Deserializable(response, XP.to_xml)
Exemplo n.º 14
0
 def create_shipment(
         self, request: Serializable[ProcessShipmentRequest]
 ) -> Deserializable[str]:
     response = http(
         url=self.settings.server_url,
         data=bytearray(request.serialize(), "utf-8"),
         headers={"Content-Type": "application/xml"},
         method="POST",
     )
     return Deserializable(response, to_xml)
Exemplo n.º 15
0
 def cancel_pickup(self, request: Serializable[str]) -> Deserializable[str]:
     pickuprequest = request.serialize()
     response = http(
         url=
         f"{self.settings.server_url}/enab/{self.settings.customer_number}/pickuprequest/{pickuprequest}",
         headers={
             "Accept": "application/vnd.cpc.pickuprequest+xml",
             "Authorization": f"Basic {self.settings.authorization}",
             "Accept-language": f"{self.settings.language}-CA",
         },
         method="DELETE",
     )
     return Deserializable(response or "<wrapper></wrapper>", XP.to_xml)
Exemplo n.º 16
0
 def get_rates(self, request: Serializable[mailing_scenario]) -> Deserializable[str]:
     response = http(
         url=f"{self.settings.server_url}/rs/ship/price",
         data=bytearray(request.serialize(), "utf-8"),
         headers={
             "Content-Type": "application/vnd.cpc.ship.rate-v4+xml",
             "Accept": "application/vnd.cpc.ship.rate-v4+xml",
             "Authorization": f"Basic {self.settings.authorization}",
             "Accept-language": "en-CA",
         },
         method="POST",
     )
     return Deserializable(response, to_xml)
Exemplo n.º 17
0
 def get_tracking(self,
                  request: Serializable[Envelope]) -> Deserializable[str]:
     response = http(
         url=
         f"{self.settings.server_url}/PWS/V1/Tracking/TrackingService.asmx",
         data=request.serialize().encode("utf-8"),
         headers={
             "Content-Type": "text/xml; charset=utf-8",
             "soapaction":
             "http://purolator.com/pws/service/v1/TrackPackagesByPin",
             "Authorization": f"Basic {self.settings.authorization}",
         },
         method="POST",
     )
     return Deserializable(response, to_xml)
Exemplo n.º 18
0
 def get_rates(self,
               request: Serializable[Envelope]) -> Deserializable[str]:
     response = http(
         url=
         f"{self.settings.server_url}/EWS/V2/Estimating/EstimatingService.asmx",
         data=bytearray(request.serialize(), "utf-8"),
         headers={
             "Content-Type": "text/xml; charset=utf-8",
             "soapaction":
             "http://purolator.com/pws/service/v2/GetFullEstimate",
             "Authorization": f"Basic {self.settings.authorization}",
         },
         method="POST",
     )
     return Deserializable(response, to_xml)
Exemplo n.º 19
0
    def get_tracking(
            self,
            request: Serializable[List[TrackRequest]]) -> Deserializable[str]:
        """
        get_tracking make parrallel request for each TrackRequest
        """
        def get_tracking(track_request: str):
            return http(
                url=f"{self.settings.server_url}/Track",
                data=bytearray(track_request, "utf-8"),
                headers={"Content-Type": "application/xml"},
                method="POST",
            )

        response: List[str] = exec_parrallel(get_tracking, request.serialize())

        return Deserializable(bundle_xml(xml_strings=response), to_xml)
Exemplo n.º 20
0
    def schedule_pickup(
            self, request: Serializable[Pipeline]) -> Deserializable[str]:
        def _availability(job: Job) -> str:
            return http(
                url=
                f"{self.settings.server_url}/ad/pickup/pickupavailability/{job.data}",
                headers={
                    "Accept": "application/vnd.cpc.pickup+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": f"{self.settings.language}-CA",
                },
                method="GET",
            )

        def _create_pickup(job: Job) -> str:
            return http(
                url=
                f"{self.settings.server_url}/enab/{self.settings.customer_number}/pickuprequest",
                data=bytearray(job.data.serialize(), "utf-8"),
                headers={
                    "Accept": "application/vnd.cpc.pickuprequest+xml",
                    "Content-Type": "application/vnd.cpc.pickuprequest+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": f"{self.settings.language}-CA",
                },
                method="POST",
            )

        def process(job: Job):
            if job.data is None:
                return job.fallback

            subprocess = {
                "create_pickup": _create_pickup,
                "availability": _availability,
            }
            if job.id not in subprocess:
                raise PurplShipError(
                    f"Unknown pickup request job id: {job.id}")

            return subprocess[job.id](job)

        pipeline: Pipeline = request.serialize()
        response = pipeline.apply(process)

        return Deserializable(XP.bundle_xml(response), XP.to_xml)
Exemplo n.º 21
0
    def modify_pickup(self,
                      request: Serializable[dict]) -> Deserializable[str]:
        def _get_pickup(job: Job) -> str:
            return http(
                url=f"{self.settings.server_url}{job.data.serialize()}",
                headers={
                    "Accept": "application/vnd.cpc.pickup+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": f"{self.settings.language}-CA",
                },
                method="GET",
            )

        def _update_pickup(job: Job) -> str:
            payload = job.data.serialize()
            return http(
                url=
                f"{self.settings.server_url}/enab/{self.settings.customer_number}/pickuprequest/{payload['pickuprequest']}",
                data=bytearray(payload["data"], "utf-8"),
                headers={
                    "Accept": "application/vnd.cpc.pickuprequest+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": f"{self.settings.language}-CA",
                },
                method="PUT",
            )

        def process(job: Job):
            if job.data is None:
                return job.fallback

            subprocess = {
                "update_pickup": _update_pickup,
                "get_pickup": _get_pickup,
            }
            if job.id not in subprocess:
                raise PurplShipError(
                    f"Unknown pickup request job id: {job.id}")

            return subprocess[job.id](job)

        pipeline: Pipeline = request.serialize()
        response = pipeline.apply(process)

        return Deserializable(XP.bundle_xml(response), XP.to_xml)
Exemplo n.º 22
0
    def create_shipment(
            self, request: Serializable[Pipeline]) -> Deserializable[str]:
        def process(job: Job):
            return (http(
                url=
                f"{self.settings.server_url}{SHIPPING_SERVICES[job.id]['path']}",
                data=bytearray(job.data, "utf-8"),
                headers={
                    "Content-Type": "text/xml; charset=utf-8",
                    "soapaction": SHIPPING_SERVICES[job.id]['action'],
                    "Authorization": f"Basic {self.settings.authorization}",
                },
                method="POST",
            ) if job.data is not None else job.fallback)

        pipeline: Pipeline = request.serialize()
        _, *response = pipeline.apply(process)
        return Deserializable(bundle_xml(response), to_xml)
Exemplo n.º 23
0
    def get_tracking(self, request: Serializable[List[str]]) -> Deserializable[str]:
        """
        get_tracking make parallel request for each pin
        """

        def track(tracking_pin: str) -> str:
            return http(
                url=f"{self.settings.server_url}/vis/track/pin/{tracking_pin}/summary",
                headers={
                    "Accept": "application/vnd.cpc.track+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": "en-CA",
                },
                method="GET",
            )

        response: List[str] = exec_parrallel(track, request.serialize())

        return Deserializable(bundle_xml(xml_strings=response), to_xml)
Exemplo n.º 24
0
    def modify_pickup(self,
                      request: Serializable[Pipeline]) -> Deserializable[str]:
        def process(job: Job):
            if job.data is None:
                return job.fallback

            return self._send_request(
                path="/EWS/V1/PickUp/PickUpService.asmx",
                request=job.data,
                soapaction=dict(
                    validate=
                    "http://purolator.com/pws/service/v1/ValidatePickUp",
                    modify="http://purolator.com/pws/service/v1/ModifyPickUp",
                )[job.id],
            )

        pipeline: Pipeline = request.serialize()
        response = pipeline.apply(process)

        return Deserializable(XP.bundle_xml(response), XP.to_xml)
Exemplo n.º 25
0
    def cancel_shipment(self, request: Serializable) -> Deserializable:
        def _request(method: str, shipment_id: str, path: str = '', **kwargs):
            return http(
                url=
                f"{self.settings.server_url}/rs/{self.settings.customer_number}/{self.settings.customer_number}/shipment/{shipment_id}{path}",
                headers={
                    "Content-Type": "application/vnd.cpc.shipment-v8+xml",
                    "Accept": "application/vnd.cpc.shipment-v8+xml",
                    "Authorization": f"Basic {self.settings.authorization}",
                    "Accept-language": f"{self.settings.language}-CA",
                },
                method=method,
                **kwargs)

        def process(job: Job):
            if job.data is None:
                return job.fallback

            subprocess = {
                "info":
                lambda _: _request('GET', job.data.serialize()),
                "refund":
                lambda _: _request(
                    'POST',
                    job.data['id'],
                    '/refund',
                    data=bytearray(job.data['payload'].serialize(), "utf-8")),
                "cancel":
                lambda _: _request('DELETE', job.data.serialize()),
            }
            if job.id not in subprocess:
                raise PurplShipError(
                    f"Unknown shipment cancel request job id: {job.id}")

            return subprocess[job.id](job)

        pipeline: Pipeline = request.serialize()
        response = pipeline.apply(process)
        return Deserializable(XP.bundle_xml(response), XP.to_xml)
Exemplo n.º 26
0
 def parse_cancel_shipment_response(
         self, response: Deserializable
 ) -> Tuple[ConfirmationDetails, List[Message]]:
     return parse_shipment_cancel_response(response.deserialize(),
                                           self.settings)
Exemplo n.º 27
0
 def parse_address_validation_response(
     self, response: Deserializable
 ) -> Tuple[AddressValidationDetails, List[Message]]:
     return parse_address_validation_response(response.deserialize(),
                                              self.settings)