diff --git a/CHANGES.rst b/CHANGES.rst index b7bacaf..173ed22 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,9 +1,10 @@ Change Log ========== -1.0.15 ------- +1.1.0 +----- +* A quick PEP8 pass on most of the codebase. Yucky. (gtaylor) * Changing recommended install method to use pip + PyPi. (radlws) * Updated rate_request and freight_rate_request examples for WSDL v16 compatibility. (foxxyz) diff --git a/README.rst b/README.rst index 82c54dd..4c2a928 100644 --- a/README.rst +++ b/README.rst @@ -3,40 +3,26 @@ Python FedEx SOAP API Module :Author: Greg Taylor :License: BSD +:Status: Stable What is it? ----------- -A light wrapper around FedEx's Webservice Soap API. - -Requirements ------------- - -The only dependency is the suds SOAP module, which is available at:: - - https://fedorahosted.org/suds/ - -You may also use easy_install or pip to install from PyPi:: - - pip install suds +A light wrapper around FedEx's Webservice Soap API. We don't do much of any +validation, but we'll help you sort through the pile of SOAP objects FedEx +uses. Installation ------------ -As root/admin on your machine:: - - python setup.py install - -Pip install, bringing in all dependencies:: +The easiest way is via pip or easy_install:: pip install fedex - + Documentation ------------- -For documentation, see the project webpage at:: - - http://code.google.com/p/python-fedex/ +Refer to the documentation_ for more details on the project. There are also a lot of useful examples under the examples directory within this directory. @@ -56,3 +42,5 @@ This software is licensed under the BSD License. python-fedex is not authored by, endorsed by, or in any way affiliated with FedEx. + +.. _documentation: https://pythonhosted.org/fedex/ diff --git a/fedex/__init__.py b/fedex/__init__.py index b8c21c3..21064bb 100644 --- a/fedex/__init__.py +++ b/fedex/__init__.py @@ -52,4 +52,4 @@ our U{Google Code project} and enter an issue in the U{Issue Tracker}. """ -VERSION = '1.0.15' +VERSION = '1.1.0' diff --git a/fedex/base_service.py b/fedex/base_service.py index 84e96c5..d5813a3 100755 --- a/fedex/base_service.py +++ b/fedex/base_service.py @@ -4,43 +4,55 @@ common may be found here. In particular, the L{FedexBaseService} class handles most of the basic, -repetetive setup work that most requests do. +repetitive setup work that most requests do. """ + import os import logging + import suds from suds.client import Client + class FedexBaseServiceException(Exception): """ Exception: Serves as the base exception that other service-related exception objects are sub-classed from. """ + def __init__(self, error_code, value): self.error_code = error_code self.value = value + def __unicode__(self): return "%s (Error code: %s)" % (repr(self.value), self.error_code) + def __str__(self): return self.__unicode__() + class FedexFailure(FedexBaseServiceException): """ Exception: The request could not be handled at this time. This is generally a server problem. """ + pass + class FedexError(FedexBaseServiceException): """ Exception: These are generally problems with the client-provided data. """ + pass + class SchemaValidationError(FedexBaseServiceException): """ Exception: There is probably a problem in the data you provided. """ + def __init__(self, fault): self.error_code = -1 self.value = "suds encountered an error validating your data against this service's WSDL schema. Please double-check for missing or invalid values, filling all required fields." @@ -49,6 +61,7 @@ def __init__(self, fault): except AttributeError: pass + class FedexBaseService(object): """ This class is the master class for all Fedex request objects. It gets all @@ -59,6 +72,7 @@ class FedexBaseService(object): @note: This object should never be used directly, use one of the included sub-classes. """ + def __init__(self, config_obj, wsdl_name, *args, **kwargs): """ This constructor should only be called by children of the class. As is @@ -70,6 +84,7 @@ def __init__(self, config_obj, wsdl_name, *args, **kwargs): differentiate this transaction from others. This value will be returned with the response from Fedex. """ + self.logger = logging.getLogger('fedex') """@ivar: Python logger instance with name 'fedex'.""" self.config_obj = config_obj @@ -87,8 +102,6 @@ def __init__(self, config_obj, wsdl_name, *args, **kwargs): self.client = Client('file:///%s' % self.wsdl_path.lstrip('/')) - #print self.client - self.VersionId = None """@ivar: Holds details on the version numbers of the WSDL.""" self.WebAuthenticationDetail = None @@ -114,6 +127,7 @@ def __set_web_authentication_detail(self): Sets up the WebAuthenticationDetail node. This is required for all requests. """ + # Start of the authentication stuff. WebAuthenticationCredential = self.client.factory.create('WebAuthenticationCredential') WebAuthenticationCredential.Key = self.config_obj.key @@ -129,6 +143,7 @@ def __set_client_detail(self): Sets up the ClientDetail node, which is required for all shipping related requests. """ + ClientDetail = self.client.factory.create('ClientDetail') ClientDetail.AccountNumber = self.config_obj.account_number ClientDetail.MeterNumber = self.config_obj.meter_number @@ -141,6 +156,7 @@ def __set_transaction_detail(self, *args, **kwargs): """ Checks kwargs for 'customer_transaction_id' and sets it if present. """ + customer_transaction_id = kwargs.get('customer_transaction_id', False) if customer_transaction_id: TransactionDetail = self.client.factory.create('TransactionDetail') @@ -152,6 +168,7 @@ def __set_version_id(self): """ Pulles the versioning info for the request from the child request. """ + VersionId = self.client.factory.create('VersionId') VersionId.ServiceId = self._version_info['service_id'] VersionId.Major = self._version_info['major'] @@ -166,6 +183,7 @@ def __prepare_wsdl_objects(self): any of the required WSDL objects so the user can just print their __str__() methods and see what they need to fill in. """ + pass def __check_response_for_fedex_error(self): @@ -173,6 +191,7 @@ def __check_response_for_fedex_error(self): This checks the response for general Fedex errors that aren't related to any one WSDL. """ + if self.response.HighestSeverity == "FAILURE": for notification in self.response.Notifications: if notification.Severity == "FAILURE": @@ -185,6 +204,7 @@ def _check_response_for_request_errors(self): specific to that module. For example, invalid tracking numbers in a Tracking request. """ + if self.response.HighestSeverity == "ERROR": for notification in self.response.Notifications: if notification.Severity == "ERROR": @@ -195,6 +215,7 @@ def create_wsdl_object_of_type(self, type_name): """ Creates and returns a WSDL object of the specified type. """ + return self.client.factory.create(type_name) def send_request(self, send_function=None): @@ -206,6 +227,7 @@ def send_request(self, send_function=None): allows for overriding the default function in cases such as validation requests. """ + # Send the request and get the response back. try: # If the user has overridden the send function, use theirs diff --git a/fedex/printers/unix.py b/fedex/printers/unix.py index be46094..5a8516f 100644 --- a/fedex/printers/unix.py +++ b/fedex/printers/unix.py @@ -3,13 +3,16 @@ installations. By "Unix", we mean Linux, Mac OS, BSD, and various flavors of Unix. """ + import binascii + class DirectDevicePrinter(object): """ This class pipes the label data directly through a /dev/* entry. Consequently, this is very Unix/Linux specific. It *MAY* work on Mac too. """ + def __init__(self, shipment, device="/dev/ttyS0"): """ Instantiates from a shipment object. You may optionally specify @@ -19,6 +22,7 @@ def __init__(self, shipment, device="/dev/ttyS0"): @param shipment: A Fedex ProcessShipmentRequest object to pull the printed label data from. """ + self.device = device """@ivar: A string with the path to the device to print to.""" self.shipment = shipment @@ -32,8 +36,11 @@ def print_label(self, package_num=None): @param package_num: 0-based index of the package to print. This is only useful for shipments with more than one package. """ + if package_num: - packages = [self.shipment.response.CompletedShipmentDetail.CompletedPackageDetails[package_num]] + packages = [ + self.shipment.response.CompletedShipmentDetail.CompletedPackageDetails[package_num] + ] else: packages = self.shipment.response.CompletedShipmentDetail.CompletedPackageDetails @@ -50,6 +57,7 @@ def _print_base64(self, base64_data): @type base64_data: L{str} @param base64_data: The base64 encoded string for the label to print. """ + label_file = open(self.device, "w") label_file.write(base64_data) - label_file.close() \ No newline at end of file + label_file.close() diff --git a/fedex/services/address_validation_service.py b/fedex/services/address_validation_service.py index efab092..f566731 100644 --- a/fedex/services/address_validation_service.py +++ b/fedex/services/address_validation_service.py @@ -6,39 +6,46 @@ easy access. For more details on each, refer to the respective class's documentation. """ + from datetime import datetime from .. base_service import FedexBaseService + class FedexAddressValidationRequest(FedexBaseService): """ This class allows you validate anywhere from one to a hundred addresses in one go. Create AddressToValidate WSDL objects and add them to each instance of this request using add_address(). """ + def __init__(self, config_obj, *args, **kwargs): """ @type config_obj: L{FedexConfig} @param config_obj: A valid FedexConfig object. """ + self._config_obj = config_obj - # Holds version info for the VersionId SOAP object. - self._version_info = {'service_id': 'aval', 'major': '2', - 'intermediate': '0', 'minor': '0'} + self._version_info = { + 'service_id': 'aval', + 'major': '2', + 'intermediate': '0', + 'minor': '0' + } self.AddressValidationOptions = None """@ivar: Holds the AddressValidationOptions WSDL object.""" self.addresses_to_validate = [] """@ivar: Holds the AddressToValidate WSDL object.""" # Call the parent FedexBaseService class for basic setup work. - super(FedexAddressValidationRequest, self).__init__(self._config_obj, - 'AddressValidationService_v2.wsdl', - *args, **kwargs) + super(FedexAddressValidationRequest, self).__init__( + self._config_obj, 'AddressValidationService_v2.wsdl', *args, **kwargs) def _prepare_wsdl_objects(self): """ Create the data structure and get it ready for the WSDL request. """ + # This holds some optional options for the request.. self.AddressValidationOptions = self.client.factory.create('AddressValidationOptions') @@ -53,6 +60,7 @@ def _assemble_and_send_request(self): @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES ON FedexBaseService AND IS INHERITED. """ + # We get an exception like this when specifying an IntegratorId: # suds.TypeNotFound: Type not found: 'IntegratorId' # Setting it to None does not seem to appease it. @@ -62,14 +70,14 @@ def _assemble_and_send_request(self): self.logger.debug(self.TransactionDetail) self.logger.debug(self.VersionId) # Fire off the query. - response = self.client.service.addressValidation(WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - RequestTimestamp=datetime.now(), - Options=self.AddressValidationOptions, - AddressesToValidate=self.addresses_to_validate) - return response + return self.client.service.addressValidation( + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + RequestTimestamp=datetime.now(), + Options=self.AddressValidationOptions, + AddressesToValidate=self.addresses_to_validate) def add_address(self, address_item): """ @@ -81,4 +89,5 @@ def add_address(self, address_item): this FedexAddressValidationRequest object. See examples/create_shipment.py for more details. """ - self.addresses_to_validate.append(address_item) \ No newline at end of file + + self.addresses_to_validate.append(address_item) diff --git a/fedex/services/rate_service.py b/fedex/services/rate_service.py index bd765f5..4f6eed5 100644 --- a/fedex/services/rate_service.py +++ b/fedex/services/rate_service.py @@ -5,15 +5,18 @@ determine estimated or courtesy billing quotes. Time in Transit can be returned with the rates if it is specified in the request. """ + from datetime import datetime from .. base_service import FedexBaseService + class FedexRateServiceRequest(FedexBaseService): """ This class allows you to get the shipping charges for a particular address. You will need to populate the data structures in self.RequestedShipment, then send the request. """ + def __init__(self, config_obj, *args, **kwargs): """ The optional keyword args detailed on L{FedexBaseService} @@ -22,6 +25,7 @@ def __init__(self, config_obj, *args, **kwargs): @type config_obj: L{FedexConfig} @param config_obj: A valid FedexConfig object. """ + self._config_obj = config_obj # Holds version info for the VersionId SOAP object. @@ -42,8 +46,8 @@ def _prepare_wsdl_objects(self): the data structure and get it ready for the WSDL request. """ - # Default behavior is to not request transit information - self.ReturnTransitAndCommit = False + # Default behavior is to not request transit information + self.ReturnTransitAndCommit = False # This is the primary data structure for processShipment requests. self.RequestedShipment = self.client.factory.create('RequestedShipment') @@ -87,10 +91,7 @@ def _prepare_wsdl_objects(self): # This is good to review if you'd like to see what the data structure # looks like. self.logger.debug(self.RequestedShipment) - - - def _assemble_and_send_request(self): """ Fires off the Fedex request. @@ -98,14 +99,15 @@ def _assemble_and_send_request(self): @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES ON FedexBaseService AND IS INHERITED. """ + # Fire off the query. - response = self.client.service.getRates(WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - RequestedShipment=self.RequestedShipment, - ReturnTransitAndCommit=self.ReturnTransitAndCommit) - return response + return self.client.service.getRates( + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + RequestedShipment=self.RequestedShipment, + ReturnTransitAndCommit=self.ReturnTransitAndCommit) def add_package(self, package_item): """ @@ -118,8 +120,8 @@ def add_package(self, package_item): this ShipmentRequest object. See examples/create_shipment.py for more details. """ + self.RequestedShipment.RequestedPackageLineItems.append(package_item) package_weight = package_item.Weight.Value self.RequestedShipment.TotalWeight.Value += package_weight self.RequestedShipment.PackageCount += 1 - diff --git a/fedex/services/ship_service.py b/fedex/services/ship_service.py index c45a2e0..1992526 100644 --- a/fedex/services/ship_service.py +++ b/fedex/services/ship_service.py @@ -5,9 +5,11 @@ ShipService WSDL file. Each is encapsulated in a class for easy access. For more details on each, refer to the respective class's documentation. """ + from datetime import datetime from .. base_service import FedexBaseService + class FedexProcessShipmentRequest(FedexBaseService): """ This class allows you to process (create) a new FedEx shipment. You will @@ -15,6 +17,7 @@ class FedexProcessShipmentRequest(FedexBaseService): send the request. Label printing is supported and very configurable, returning an ASCII representation with the response as well. """ + def __init__(self, config_obj, *args, **kwargs): """ The optional keyword args detailed on L{FedexBaseService} @@ -23,24 +26,27 @@ def __init__(self, config_obj, *args, **kwargs): @type config_obj: L{FedexConfig} @param config_obj: A valid FedexConfig object. """ + self._config_obj = config_obj - # Holds version info for the VersionId SOAP object. - self._version_info = {'service_id': 'ship', 'major': '13', - 'intermediate': '0', 'minor': '0'} - + self._version_info = { + 'service_id': 'ship', + 'major': '13', + 'intermediate': '0', + 'minor': '0' + } self.RequestedShipment = None """@ivar: Holds the RequestedShipment WSDL object.""" # Call the parent FedexBaseService class for basic setup work. - super(FedexProcessShipmentRequest, self).__init__(self._config_obj, - 'ShipService_v13.wsdl', - *args, **kwargs) + super(FedexProcessShipmentRequest, self).__init__( + self._config_obj, 'ShipService_v13.wsdl', *args, **kwargs) def _prepare_wsdl_objects(self): """ This is the data that will be used to create your shipment. Create the data structure and get it ready for the WSDL request. """ + # This is the primary data structure for processShipment requests. self.RequestedShipment = self.client.factory.create('RequestedShipment') self.RequestedShipment.ShipTimestamp = datetime.now() @@ -99,6 +105,7 @@ def send_validation_request(self): used to make sure "good" values are given by the user or the application using the library. """ + self.send_request(send_function=self._assemble_and_send_validation_request) def _assemble_and_send_validation_request(self): @@ -109,13 +116,14 @@ def _assemble_and_send_validation_request(self): send_validation_request(), WHICH RESIDES ON FedexBaseService AND IS INHERITED. """ + # Fire off the query. - response = self.client.service.validateShipment(WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - RequestedShipment=self.RequestedShipment) - return response + return self.client.service.validateShipment( + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + RequestedShipment=self.RequestedShipment) def _assemble_and_send_request(self): """ @@ -124,13 +132,14 @@ def _assemble_and_send_request(self): @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES ON FedexBaseService AND IS INHERITED. """ + # Fire off the query. - response = self.client.service.processShipment(WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - RequestedShipment=self.RequestedShipment) - return response + return self.client.service.processShipment( + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + RequestedShipment=self.RequestedShipment) def add_package(self, package_item): """ @@ -143,19 +152,23 @@ def add_package(self, package_item): this ShipmentRequest object. See examples/create_shipment.py for more details. """ + self.RequestedShipment.RequestedPackageLineItems.append(package_item) package_weight = package_item.Weight.Value self.RequestedShipment.TotalWeight.Value += package_weight self.RequestedShipment.PackageCount += 1 - + + class FedexDeleteShipmentRequest(FedexBaseService): """ This class allows you to delete a shipment, given a tracking number. """ + def __init__(self, config_obj, *args, **kwargs): """ Deletes a shipment via a tracking number. """ + self._config_obj = config_obj # Holds version info for the VersionId SOAP object. @@ -174,6 +187,7 @@ def _prepare_wsdl_objects(self): """ Preps the WSDL data structures for the user. """ + self.DeletionControlType = self.client.factory.create('DeletionControlType') self.TrackingId = self.client.factory.create('TrackingId') self.TrackingId.TrackingIdType = self.client.factory.create('TrackingIdType') @@ -185,14 +199,14 @@ def _assemble_and_send_request(self): @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES ON FedexBaseService AND IS INHERITED. """ + client = self.client # Fire off the query. - response = client.service.deleteShipment(WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - ShipTimestamp = datetime.now(), - TrackingId=self.TrackingId, - DeletionControl=self.DeletionControlType) - - return response \ No newline at end of file + return client.service.deleteShipment( + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + ShipTimestamp = datetime.now(), + TrackingId=self.TrackingId, + DeletionControl=self.DeletionControlType) diff --git a/fedex/services/track_service.py b/fedex/services/track_service.py index a62bc73..cc0301a 100644 --- a/fedex/services/track_service.py +++ b/fedex/services/track_service.py @@ -5,15 +5,19 @@ TrackService WSDL file. Each is encapsulated in a class for easy access. For more details on each, refer to the respective class's documentation. """ -import logging + + from .. base_service import FedexBaseService, FedexError + class FedexInvalidTrackingNumber(FedexError): """ Exception: Sent when a bad tracking number is provided. """ + pass + class FedexTrackRequest(FedexBaseService): """ This class allows you to track shipments by providing a tracking @@ -23,6 +27,7 @@ class FedexTrackRequest(FedexBaseService): want to read the documentation for the L{__init__} method. Particularly, the tracking_value and package_identifier arguments. """ + def __init__(self, config_obj, *args, **kwargs): """ Sends a shipment tracking request. The optional keyword args @@ -34,11 +39,16 @@ def __init__(self, config_obj, *args, **kwargs): @type tracking_number_unique_id: str @param tracking_number_unique_id: Used to distinguish duplicate FedEx tracking numbers. """ + self._config_obj = config_obj # Holds version info for the VersionId SOAP object. - self._version_info = {'service_id': 'trck', 'major': '5', - 'intermediate': '0', 'minor': '0'} + self._version_info = { + 'service_id': 'trck', + 'major': '5', + 'intermediate': '0', + 'minor': '0' + } self.TrackPackageIdentifier = None """@ivar: Holds the TrackPackageIdentifier WSDL object.""" @@ -46,9 +56,8 @@ def __init__(self, config_obj, *args, **kwargs): """@ivar: Holds the TrackingNumberUniqueIdentifier WSDL object.""" # Call the parent FedexBaseService class for basic setup work. - super(FedexTrackRequest, self).__init__(self._config_obj, - 'TrackService_v5.wsdl', - *args, **kwargs) + super(FedexTrackRequest, self).__init__( + self._config_obj, 'TrackService_v5.wsdl', *args, **kwargs) self.IncludeDetailedScans = False def _prepare_wsdl_objects(self): @@ -56,6 +65,7 @@ def _prepare_wsdl_objects(self): This sets the package identifier information. This may be a tracking number or a few different things as per the Fedex spec. """ + self.TrackPackageIdentifier = self.client.factory.create('TrackPackageIdentifier') # Default to tracking number. self.TrackPackageIdentifier.Type = 'TRACKING_NUMBER_OR_DOORTAG' @@ -69,11 +79,10 @@ def _check_response_for_request_errors(self): for notification in self.response.Notifications: if notification.Severity == "ERROR": if "Invalid tracking number" in notification.Message: - raise FedexInvalidTrackingNumber(notification.Code, - notification.Message) + raise FedexInvalidTrackingNumber( + notification.Code, notification.Message) else: - raise FedexError(notification.Code, - notification.Message) + raise FedexError(notification.Code, notification.Message) def _assemble_and_send_request(self): """ @@ -82,14 +91,14 @@ def _assemble_and_send_request(self): @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES ON FedexBaseService AND IS INHERITED. """ + client = self.client # Fire off the query. - response = client.service.track(WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - IncludeDetailedScans=self.IncludeDetailedScans, - PackageIdentifier=self.TrackPackageIdentifier, - TrackingNumberUniqueIdentifier = self.TrackingNumberUniqueIdentifier) - - return response + return client.service.track( + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + IncludeDetailedScans=self.IncludeDetailedScans, + PackageIdentifier=self.TrackPackageIdentifier, + TrackingNumberUniqueIdentifier = self.TrackingNumberUniqueIdentifier) diff --git a/label_certification/cert_config.py b/label_certification/cert_config.py index 0483fda..277e296 100644 --- a/label_certification/cert_config.py +++ b/label_certification/cert_config.py @@ -11,43 +11,48 @@ from fedex.printers.unix import DirectDevicePrinter # Change these values to match your testing account/meter number. -CONFIG_OBJ = FedexConfig(key='xxxxxxxxxxxxxxxx', - password='xxxxxxxxxxxxxxxxxxxxxxxxx', - account_number='#########', - meter_number='#########', - use_test_server=True) +CONFIG_OBJ = FedexConfig( + key='xxxxxxxxxxxxxxxx', + password='xxxxxxxxxxxxxxxxxxxxxxxxx', + account_number='#########', + meter_number='#########', + use_test_server=True) # Change this to whoever should be the contact person for shipments. -SHIPPER_CONTACT_INFO = {'PersonName': 'Some Person', - 'CompanyName': 'Your Company', - 'PhoneNumber': '##########'} +SHIPPER_CONTACT_INFO = { + 'PersonName': 'Some Person', + 'CompanyName': 'Your Company', + 'PhoneNumber': '##########' +} # The dictionary below should be your office/client's address that shipping # will be originating from. -SHIPPER_ADDRESS = {'StreetLines': ['Address Line 1'], - 'City': 'Some City', - 'StateOrProvinceCode': 'SC', - 'PostalCode': '29631', - 'CountryCode': 'US', - 'Residential': False} +SHIPPER_ADDRESS = { + 'StreetLines': ['Address Line 1'], + 'City': 'Some City', + 'StateOrProvinceCode': 'SC', + 'PostalCode': '29631', + 'CountryCode': 'US', + 'Residential': False +} # This contains the configuration for your label printer. LABEL_SPECIFICATION = { - # Specifies the label type to be returned. - # LABEL_DATA_ONLY or COMMON2D - 'LabelFormatType': 'COMMON2D', - # Specifies which format the label file will be - # sent to you in. - # DPL, EPL2, PDF, PNG, ZPLII - 'ImageType': 'EPL2', - # To use doctab stocks, you must change ImageType above - # to one of the label printer formats (ZPLII, EPL2, DPL). - # See documentation for paper types, there quite a few. - 'LabelStockType': 'STOCK_4X6.75_LEADING_DOC_TAB', - # This indicates if the top or bottom of the label comes - # out of the printer first. - # BOTTOM_EDGE_OF_TEXT_FIRST or TOP_EDGE_OF_TEXT_FIRST - 'LabelPrintingOrientation': 'BOTTOM_EDGE_OF_TEXT_FIRST' + # Specifies the label type to be returned. + # LABEL_DATA_ONLY or COMMON2D + 'LabelFormatType': 'COMMON2D', + # Specifies which format the label file will be + # sent to you in. + # DPL, EPL2, PDF, PNG, ZPLII + 'ImageType': 'EPL2', + # To use doctab stocks, you must change ImageType above + # to one of the label printer formats (ZPLII, EPL2, DPL). + # See documentation for paper types, there quite a few. + 'LabelStockType': 'STOCK_4X6.75_LEADING_DOC_TAB', + # This indicates if the top or bottom of the label comes + # out of the printer first. + # BOTTOM_EDGE_OF_TEXT_FIRST or TOP_EDGE_OF_TEXT_FIRST + 'LabelPrintingOrientation': 'BOTTOM_EDGE_OF_TEXT_FIRST' } # This should just be a reference to the correct printer class for your @@ -55,6 +60,7 @@ # NOTE: This should NOT be an instance. It should just be a reference. LabelPrinterClass = DirectDevicePrinter + def transfer_config_dict(soap_object, data_dict): """ This is a utility function used in the certification modules to transfer @@ -64,4 +70,4 @@ def transfer_config_dict(soap_object, data_dict): """ for key, val in data_dict.items(): # Transfer each key to the matching attribute ont he SOAP object. - setattr(soap_object, key, val) \ No newline at end of file + setattr(soap_object, key, val) diff --git a/label_certification/express.py b/label_certification/express.py index e19f6cb..9a3040d 100755 --- a/label_certification/express.py +++ b/label_certification/express.py @@ -4,6 +4,7 @@ certification process. See your FedEx Label Developer Tool Kit documentation for more details. """ + import logging from cert_config import CONFIG_OBJ, SHIPPER_CONTACT_INFO, SHIPPER_ADDRESS, LABEL_SPECIFICATION from cert_config import transfer_config_dict @@ -74,4 +75,4 @@ shipment.send_request() device = LabelPrinterClass(shipment) - device.print_label() \ No newline at end of file + device.print_label()