From 6862eb603edfee921ff49514c40fc95efa43ac58 Mon Sep 17 00:00:00 2001 From: Rad Date: Wed, 13 Jan 2016 21:14:47 -0500 Subject: [PATCH 01/65] add ship signature to ship request add an example where the shipment request can include a signature option on delivery. This can be commented out to not require the signature option. --- examples/create_shipment.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/create_shipment.py b/examples/create_shipment.py index 9bf6e4d..860d626 100755 --- a/examples/create_shipment.py +++ b/examples/create_shipment.py @@ -111,6 +111,13 @@ # BAG, BARREL, BASKET, BOX, BUCKET, BUNDLE, CARTON, CASE, CONTAINER, ENVELOPE etc.. package1.PhysicalPackaging = 'ENVELOPE' package1.Weight = package1_weight + +# Add a signature option for the package using SpecialServicesRequested or comment out. +# SpecialServiceTypes can be APPOINTMENT_DELIVERY, COD, DANGEROUS_GOODS, DRY_ICE, SIGNATURE_OPTION etc.. +package1.SpecialServicesRequested.SpecialServiceTypes = 'SIGNATURE_OPTION' +# SignatureOptionType can be ADULT, DIRECT, INDIRECT, NO_SIGNATURE_REQUIRED, SERVICE_DEFAULT +package1.SpecialServicesRequested.SignatureOptionDetail.OptionType = 'SERVICE_DEFAULT' + # Un-comment this to see the other variables you may set on a package. # print(package1) From 9740f9450b6ac57bfc7610f3169754e0a7be0cb0 Mon Sep 17 00:00:00 2001 From: Rad Date: Fri, 15 Jan 2016 18:29:14 -0500 Subject: [PATCH 02/65] fix request response logging --- fedex/base_service.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fedex/base_service.py b/fedex/base_service.py index 3bca8d1..3ec99cb 100755 --- a/fedex/base_service.py +++ b/fedex/base_service.py @@ -17,16 +17,19 @@ class GeneralSudsPlugin(MessagePlugin): def __init__(self, **kwargs): + + self.request_logger = logging.getLogger('fedex.request') + self.response_logger = logging.getLogger('fedex.response') self.kwargs = kwargs def marshalled(self, context): context.envelope = context.envelope.prune() def sending(self, context): - logging.info("FedEx Request {}".format(context.envelope)) + self.request_logger.info("FedEx Request {}".format(context.envelope)) def received(self, context): - logging.info("FedEx Response {}".format(context.reply)) + self.response_logger.info("FedEx Response {}".format(context.reply)) class FedexBaseServiceException(Exception): From f81e612466587ead5879f4508b7250a0981af384 Mon Sep 17 00:00:00 2001 From: radzhome Date: Fri, 15 Jan 2016 23:41:54 -0500 Subject: [PATCH 03/65] update certification process --- label_certification/express.py | 4 +++- label_certification/ground.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/label_certification/express.py b/label_certification/express.py index 9e59d44..dac3528 100755 --- a/label_certification/express.py +++ b/label_certification/express.py @@ -17,7 +17,6 @@ shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP' shipment.RequestedShipment.ServiceType = 'PRIORITY_OVERNIGHT' shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING' -shipment.RequestedShipment.PackageDetail = 'INDIVIDUAL_PACKAGES' # Shipper contact info. transfer_config_dict(shipment.RequestedShipment.Shipper.Contact, @@ -41,6 +40,9 @@ shipment.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER' +# Senders account information +shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = CONFIG_OBJ.account_number + # Label config. transfer_config_dict(shipment.RequestedShipment.LabelSpecification, LABEL_SPECIFICATION) diff --git a/label_certification/ground.py b/label_certification/ground.py index d04f534..4b518d1 100755 --- a/label_certification/ground.py +++ b/label_certification/ground.py @@ -16,7 +16,6 @@ shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP' shipment.RequestedShipment.ServiceType = 'FEDEX_GROUND' shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING' -shipment.RequestedShipment.PackageDetail = 'INDIVIDUAL_PACKAGES' # Shipper contact info. transfer_config_dict(shipment.RequestedShipment.Shipper.Contact, @@ -40,6 +39,9 @@ shipment.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER' +# Senders account information +shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = CONFIG_OBJ.account_number + # Label config. transfer_config_dict(shipment.RequestedShipment.LabelSpecification, LABEL_SPECIFICATION) From a739ffefe96d0b5aed991e4b939623dcc6583ea1 Mon Sep 17 00:00:00 2001 From: radzhome Date: Fri, 15 Jan 2016 00:53:23 -0500 Subject: [PATCH 04/65] add location serivce wsdl, base, test and example --- examples/location_request.py | 53 + fedex/services/location_service.py | 79 ++ fedex/wsdl/LocationsService_v3.wsdl | 970 ++++++++++++++++++ .../test_server_wsdl/LocationsService_v3.wsdl | 970 ++++++++++++++++++ tests/test_location_service.py | 44 + 5 files changed, 2116 insertions(+) create mode 100644 examples/location_request.py create mode 100644 fedex/services/location_service.py create mode 100755 fedex/wsdl/LocationsService_v3.wsdl create mode 100755 fedex/wsdl/test_server_wsdl/LocationsService_v3.wsdl create mode 100644 tests/test_location_service.py diff --git a/examples/location_request.py b/examples/location_request.py new file mode 100644 index 0000000..ddcc922 --- /dev/null +++ b/examples/location_request.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +""" +This example shows how to use the FedEx Location service. +The variables populated below represents the minimum required values. +You will need to fill all of these, or risk seeing a SchemaValidationError +exception thrown by suds. + +""" +import logging +from example_config import CONFIG_OBJ +from fedex.services.location_service import FedexSearchLocationRequest + +# Set this to the INFO level to see the response from Fedex printed in stdout. +logging.basicConfig(level=logging.INFO) + + +# This is the object that will be handling our request. +# We're using the FedexConfig object from example_config.py in this dir. +customer_transaction_id = "*** LocationService Request v3 using Python ***" # Optional transaction_id +location_request = FedexSearchLocationRequest(CONFIG_OBJ, customer_transaction_id=customer_transaction_id) + +# Specify the type of search and search criteria. +location_request.LocationsSearchCriterion = 'PHONE_NUMBER' +location_request.PhoneNumber = '4169297819' +location_request.MultipleMatchesAction = 'RETURN_ALL' + +# Set constraints, see SearchLocationConstraints definition. +location_request.Constraints.LocationTypesToInclude = ['FEDEX_SELF_SERVICE_LOCATION', + 'FEDEX_AUTHORIZED_SHIP_CENTER'] + +location_request.Address.PostalCode = '38119' +location_request.Address.CountryCode = 'US' + +# If you'd like to see some documentation on the ship service WSDL, un-comment +# this line. (Spammy). +# print(rate_request.client) + +# Un-comment this to see your complete, ready-to-send request as it stands +# before it is actually sent. This is useful for seeing what values you can +# change. +# print(location_request.LocationsSearchCriterion) + +# Fires off the request, sets the 'response' attribute on the object. +location_request.send_request() + +# This will show the reply to your request being sent. You can access the +# attributes through the response attribute on the request object. This is +# good to un-comment to see the variables returned by the FedEx reply. +# print(location_request.response) + +# Here is the overall end result of the query. +print("HighestSeverity:", location_request.response.HighestSeverity) + diff --git a/fedex/services/location_service.py b/fedex/services/location_service.py new file mode 100644 index 0000000..dc98a90 --- /dev/null +++ b/fedex/services/location_service.py @@ -0,0 +1,79 @@ +""" +Location Service Module +================================= +This package contains the shipping methods defined by Fedex's +LocationService WSDL file. Each is encapsulated in a class for +easy access. For more details on each, refer to the respective class's +documentation. +""" + +from ..base_service import FedexBaseService + + +class FedexSearchLocationRequest(FedexBaseService): + """ + This class allows you validate service availability + """ + + 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': 'locs', + 'major': '3', + 'intermediate': '0', + 'minor': '0' + } + + """@ivar: set default objects.""" + self.Address = None + self.PhoneNumber = None + self.MultipleMatchesAction = None + self.Constraints = [] + self.LocationsSearchCriterion = None + + """@ivar: Holds the WSDL object.""" + + super(FedexSearchLocationRequest, self).__init__( + self._config_obj, 'LocationsService_v3.wsdl', *args, **kwargs) + + def _prepare_wsdl_objects(self): + """ + Create the data structure and get it ready for the WSDL request. + """ + self.MultipleMatchesAction = 'RETURN_ALL' + self.Constraints = self.create_wsdl_object_of_type('SearchLocationConstraints') + self.Address = self.create_wsdl_object_of_type('Address') + + def _assemble_and_send_request(self): + """ + Fires off the Fedex request. + + @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. + del self.ClientDetail.IntegratorId + self.logger.debug(self.WebAuthenticationDetail) + self.logger.debug(self.ClientDetail) + self.logger.debug(self.TransactionDetail) + self.logger.debug(self.VersionId) + # Fire off the query. + return self.client.service.searchLocations( + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + LocationsSearchCriterion=self.LocationsSearchCriterion, + PhoneNumber=self.PhoneNumber, + MultipleMatchesAction=self.MultipleMatchesAction, + Constraints=self.Constraints, + Address=self.Address) diff --git a/fedex/wsdl/LocationsService_v3.wsdl b/fedex/wsdl/LocationsService_v3.wsdl new file mode 100755 index 0000000..3f4de00 --- /dev/null +++ b/fedex/wsdl/LocationsService_v3.wsdl @@ -0,0 +1,970 @@ + + + + + + + + Descriptive data for a physical location. May be used as an actual physical address (place to which one could go), or as a container of "address parts" which should be handled as a unit (such as a city-state-ZIP combination within the US). + + + + + Combination of number, street name, etc. At least one line is required for a valid physical address; empty lines should not be included. + + + + + Name of city, town, etc. + + + + + Identifying abbreviation for US state, Canada province, etc. Format and presence of this field will vary, depending on country. + + + + + Identification of a region (usually small) for mail/package delivery. Format and presence of this field will vary, depending on country. + + + + + Relevant only to addresses in Puerto Rico. + + + + + The two-letter code used to identify a country. + + + + + The fully spelt out name of a country. + + + + + Indicates whether this address residential (as opposed to commercial). + + + + + + + Additional information about a physical location, such as suite number, cross street, floor number in a building. These details are not typically a part of a standard address definition; however, these details might help locate the address. + + + + + + + Indicates whether how this location can be accessed. + + + + + Specifies building number or name. + + + + + Specifies a department in the company or retail store. + + + + + Specifies the floor number. + + + + + + Specifies apartment number. + + + + + Specifies the room number, if one is specified. + + + + + + This is used to specify additional details about the address such as landmark. For e.g. This field is used to capture details such as an address being inside a facility such as, Chilli's Care Center, St. Jude - Inside. + + + + + + + Specifies the relationship between the address specificed and the address of the FedEx Location in terms of distance. + + + + + Address as provided in the request. + + + + + Specify the geographic co-ordinates for the matched address. + + + + + Specifies the distance between the matched address and the addresses of matched FedEx locations. Also specifies the details of the FedEx locations. + + + + + + + Identification of a FedEx operating company (transportation). + + + + + + + + + + + + + + + + + + This field describe a subset of the carrier's products or services which may have unique characteristics: i.e. latest drop-off times at a particular location vary depending on the destination type. + + + + + Specifies the details about the latest times a drop off can be made at a location most days. These are the normal drop off times. + + + + + Specifies the details about the exceptional latest times a drop off can be made at a location. These are drop off times that are a variation from the normal drop off times. + + + + + Specifies the details about the effective latest times drop off can be made at a location on the date requested. These are drop off times that are derived from the normal and exceptional drop off times, depending upon the date requested. + + + + + + + + Specifies the special services supported at the clearance location for an individual destination country. + + + + + Identifies the country whose special services are specified below. + + + + + Identifies the constrained special services supported for the country above. + + + + + + + Specifies the details about the countries supported by this location. + + + + + Services supported for clearance + + + + + Identifies the type of consolidation for which these clearance location attributes were extracted. + + + + + Identifies the type of clearance performed at this location. + + + + + Identifies the constrained special services supported at this location. + + + + + + + + + Descriptive data for the client submitting a transaction. + + + + + The FedEx account number associated with this transaction. + + + + + This number is assigned by FedEx and identifies the unique device from which the request is originating + + + + + + Only used in transactions which require identification of the FedEx Office integrator. + + + + + Indicates the region from which the transaction is submitted. + + + + + The language to be used for human-readable Notification.localizedMessages in responses to the request containing this ClientDetail object. Different requests from the same client may contain different Localization data. (Contrast with TransactionDetail.localization, which governs data payload language/translation.) + + + + + + + + + + + + + + + + + The descriptive data for a point-of-contact person. + + + + + Client provided identifier corresponding to this contact information. + + + + + Identifies the contact person's name. + + + + + Identifies the contact person's title. + + + + + Identifies the company this contact is associated with. + + + + + Identifies the phone number associated with this contact. + + + + + Identifies the phone extension associated with this contact. + + + + + Identifies a toll free number, if any, associated with this contact. + + + + + Identifies the pager number associated with this contact. + + + + + Identifies the fax number associated with this contact. + + + + + Identifies the email address associated with this contact. + + + + + + + Describes relationship between origin and destination countries. + + + + + + + + + + + + + + + + + + + + Driving or other transportation distances, distinct from dimension measurements. + + + + + Identifies the distance quantity. + + + + + Identifies the unit of measure for the distance value. + + + + + + + Specifies the location details and other information relevant to the location that is derived from the inputs provided in the request. + + + + + Distance between an address of a geographic location and an address of a FedEx location. + + + + + + Details about a FedEx location such as services offered, working hours and pick and drop off times. + + + + + + + + + + + + + + + + + + + Indicates a FedEx Express operating region. + + + + + + + + + + + + Identifies a kind of FedEx facility. + + + + + + + + + + + + + + + + + + + + + + Specifies the latest time by which a package can be dropped off at a FedEx location. + + + + + + + Specifies the details about the overlay to the last drop off time for a carrier at a FedEx location. + + + + + + + Specifies the reason for the overlay of the daily last drop off time for a carrier. + + + + + + + + Specifies the time and reason to overlay the last drop off time for a carrier at a FedEx location. + + + + + + + + + Identifies the representation of human-readable text. + + + + + Two-letter code for language (e.g. EN, FR, etc.) + + + + + Two-letter code for the region (e.g. us, ca, etc..). + + + + + + + Indicates how this can be accessed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Describes an individual location providing a set of customer service features. + + + + + + + + + + + + Details about the clearance location. + + + + + + + + + Normal operating hours for the location. + + + + + Operating hours for the location that are exception from the normal hours of operation. + + + + + + + + + Specifies the location hours for a location. + + + + + + + + + + Specifies the crieteria used to filter the location search results. + + + + + + + + Specifies the criterion to be used to sort the location details. + + + + + + + + + + + Specifies the criterion and order to be used to sort the location details. + + + + + Specifies the criterion to be used to sort the location details. + + + + + Specifies sort order of the location details. + + + + + + + Specifies sort order of the location details. + + + + + + + + + Specifies the criteria types that may be used to search for FedEx locations. + + + + + + + + + + + + + + + + + The descriptive data regarding the result of the submitted transaction. + + + + + The severity of this notification. This can indicate success or failure or some other information about the request. The values that can be returned are SUCCESS - Your transaction succeeded with no other applicable information. NOTE - Additional information that may be of interest to you about your transaction. WARNING - Additional information that you need to know about your transaction that you may need to take action on. ERROR - Information about an error that occurred while processing your transaction. FAILURE - FedEx was unable to process your transaction at this time due to a system failure. Please try again later + + + + + Indicates the source of this notification. Combined with the Code it uniquely identifies this notification + + + + + A code that represents this notification. Combined with the Source it uniquely identifies this notification. + + + + + Human-readable text that explains this notification. + + + + + The translated message. The language and locale specified in the ClientDetail. Localization are used to determine the representation. Currently only supported in a TrackReply. + + + + + A collection of name/value pairs that provide specific data to help the client determine the nature of an error (or warning, etc.) witout having to parse the message string. + + + + + + + + + Identifies the type of data contained in Value (e.g. SERVICE_TYPE, PACKAGE_SEQUENCE, etc..). + + + + + The value of the parameter (e.g. PRIORITY_OVERNIGHT, 2, etc..). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Attributes about a reservation at a FedEx location. + + + + + + + + + + + + + Specifies additional constraints on the attributes of the locations being searched. + + + + + Specifies value and units of the radius around the address to search for FedEx locations. + + + + + The latest time at which the customer can drop off a package for being shipped using an express service. + + + + + Specifies the criteria used to filter the results of locations search. + + + + + Specifies the types of services supported by a FedEx location for redirect to hold. + + + + + + + + + + + + + + + + + + Specifies total number of location results that are available. + + + + + Specifies the number of location results returned in this reply. + + + + + Specifies the address formatted to have correct postal code per USPS standards. + + + + + The details about the relationship between the address requested and the locations returned. + + + + + + + + + Descriptive data to be used in authentication of the sender's identity (and right to use FedEx web services). + + + + + + + + + Specifies the criterion that may be used to search for FedEx locations. + + + + + Tracking number to be used when searching for locations. This tracking number, along with other location search constraints, help to narrow the search for locations. + + + + + + + + Specifies the criterion to be used to return location results when there are mutiple matches. + + + + + Specifies the details on how the location search results be sorted in the reply. + + + + + Contraints to be applied to location attributes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Specifies the types of services supported by a FedEx location for redirect to hold. + + + + + + + + + + + + + + + + + + Free form text to be echoed back in the reply. Used to match requests and replies. + + + + + Governs data payload language/translations (contrasted with ClientDetail.localization, which governs Notification.localizedMessage language selection). + + + + + + + + + + + + + + Used in authentication of the sender's identity. + + + + + This was renamed from cspCredential. + + + + + Credential used to authenticate a specific software application. This value is provided by FedEx after registration. + + + + + + + Two part authentication string used for the sender's identity + + + + + Identifying part of authentication credential. This value is provided by FedEx after registration + + + + + Secret part of authentication key. This value is provided by FedEx after registration. + + + + + + + Identifies the version/level of a service operation expected by a caller (in each request) and performed by the callee (in each reply). + + + + + Identifies a system or sub-system which performs an operation. + + + + + Identifies the service business level. + + + + + Identifies the service interface level. + + + + + Identifies the service code level. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fedex/wsdl/test_server_wsdl/LocationsService_v3.wsdl b/fedex/wsdl/test_server_wsdl/LocationsService_v3.wsdl new file mode 100755 index 0000000..b2a23e9 --- /dev/null +++ b/fedex/wsdl/test_server_wsdl/LocationsService_v3.wsdl @@ -0,0 +1,970 @@ + + + + + + + + Descriptive data for a physical location. May be used as an actual physical address (place to which one could go), or as a container of "address parts" which should be handled as a unit (such as a city-state-ZIP combination within the US). + + + + + Combination of number, street name, etc. At least one line is required for a valid physical address; empty lines should not be included. + + + + + Name of city, town, etc. + + + + + Identifying abbreviation for US state, Canada province, etc. Format and presence of this field will vary, depending on country. + + + + + Identification of a region (usually small) for mail/package delivery. Format and presence of this field will vary, depending on country. + + + + + Relevant only to addresses in Puerto Rico. + + + + + The two-letter code used to identify a country. + + + + + The fully spelt out name of a country. + + + + + Indicates whether this address residential (as opposed to commercial). + + + + + + + Additional information about a physical location, such as suite number, cross street, floor number in a building. These details are not typically a part of a standard address definition; however, these details might help locate the address. + + + + + + + Indicates whether how this location can be accessed. + + + + + Specifies building number or name. + + + + + Specifies a department in the company or retail store. + + + + + Specifies the floor number. + + + + + + Specifies apartment number. + + + + + Specifies the room number, if one is specified. + + + + + + This is used to specify additional details about the address such as landmark. For e.g. This field is used to capture details such as an address being inside a facility such as, Chilli's Care Center, St. Jude - Inside. + + + + + + + Specifies the relationship between the address specificed and the address of the FedEx Location in terms of distance. + + + + + Address as provided in the request. + + + + + Specify the geographic co-ordinates for the matched address. + + + + + Specifies the distance between the matched address and the addresses of matched FedEx locations. Also specifies the details of the FedEx locations. + + + + + + + Identification of a FedEx operating company (transportation). + + + + + + + + + + + + + + + + + + This field describe a subset of the carrier's products or services which may have unique characteristics: i.e. latest drop-off times at a particular location vary depending on the destination type. + + + + + Specifies the details about the latest times a drop off can be made at a location most days. These are the normal drop off times. + + + + + Specifies the details about the exceptional latest times a drop off can be made at a location. These are drop off times that are a variation from the normal drop off times. + + + + + Specifies the details about the effective latest times drop off can be made at a location on the date requested. These are drop off times that are derived from the normal and exceptional drop off times, depending upon the date requested. + + + + + + + + Specifies the special services supported at the clearance location for an individual destination country. + + + + + Identifies the country whose special services are specified below. + + + + + Identifies the constrained special services supported for the country above. + + + + + + + Specifies the details about the countries supported by this location. + + + + + Services supported for clearance + + + + + Identifies the type of consolidation for which these clearance location attributes were extracted. + + + + + Identifies the type of clearance performed at this location. + + + + + Identifies the constrained special services supported at this location. + + + + + + + + + Descriptive data for the client submitting a transaction. + + + + + The FedEx account number associated with this transaction. + + + + + This number is assigned by FedEx and identifies the unique device from which the request is originating + + + + + + Only used in transactions which require identification of the FedEx Office integrator. + + + + + Indicates the region from which the transaction is submitted. + + + + + The language to be used for human-readable Notification.localizedMessages in responses to the request containing this ClientDetail object. Different requests from the same client may contain different Localization data. (Contrast with TransactionDetail.localization, which governs data payload language/translation.) + + + + + + + + + + + + + + + + + The descriptive data for a point-of-contact person. + + + + + Client provided identifier corresponding to this contact information. + + + + + Identifies the contact person's name. + + + + + Identifies the contact person's title. + + + + + Identifies the company this contact is associated with. + + + + + Identifies the phone number associated with this contact. + + + + + Identifies the phone extension associated with this contact. + + + + + Identifies a toll free number, if any, associated with this contact. + + + + + Identifies the pager number associated with this contact. + + + + + Identifies the fax number associated with this contact. + + + + + Identifies the email address associated with this contact. + + + + + + + Describes relationship between origin and destination countries. + + + + + + + + + + + + + + + + + + + + Driving or other transportation distances, distinct from dimension measurements. + + + + + Identifies the distance quantity. + + + + + Identifies the unit of measure for the distance value. + + + + + + + Specifies the location details and other information relevant to the location that is derived from the inputs provided in the request. + + + + + Distance between an address of a geographic location and an address of a FedEx location. + + + + + + Details about a FedEx location such as services offered, working hours and pick and drop off times. + + + + + + + + + + + + + + + + + + + Indicates a FedEx Express operating region. + + + + + + + + + + + + Identifies a kind of FedEx facility. + + + + + + + + + + + + + + + + + + + + + + Specifies the latest time by which a package can be dropped off at a FedEx location. + + + + + + + Specifies the details about the overlay to the last drop off time for a carrier at a FedEx location. + + + + + + + Specifies the reason for the overlay of the daily last drop off time for a carrier. + + + + + + + + Specifies the time and reason to overlay the last drop off time for a carrier at a FedEx location. + + + + + + + + + Identifies the representation of human-readable text. + + + + + Two-letter code for language (e.g. EN, FR, etc.) + + + + + Two-letter code for the region (e.g. us, ca, etc..). + + + + + + + Indicates how this can be accessed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Describes an individual location providing a set of customer service features. + + + + + + + + + + + + Details about the clearance location. + + + + + + + + + Normal operating hours for the location. + + + + + Operating hours for the location that are exception from the normal hours of operation. + + + + + + + + + Specifies the location hours for a location. + + + + + + + + + + Specifies the crieteria used to filter the location search results. + + + + + + + + Specifies the criterion to be used to sort the location details. + + + + + + + + + + + Specifies the criterion and order to be used to sort the location details. + + + + + Specifies the criterion to be used to sort the location details. + + + + + Specifies sort order of the location details. + + + + + + + Specifies sort order of the location details. + + + + + + + + + Specifies the criteria types that may be used to search for FedEx locations. + + + + + + + + + + + + + + + + + The descriptive data regarding the result of the submitted transaction. + + + + + The severity of this notification. This can indicate success or failure or some other information about the request. The values that can be returned are SUCCESS - Your transaction succeeded with no other applicable information. NOTE - Additional information that may be of interest to you about your transaction. WARNING - Additional information that you need to know about your transaction that you may need to take action on. ERROR - Information about an error that occurred while processing your transaction. FAILURE - FedEx was unable to process your transaction at this time due to a system failure. Please try again later + + + + + Indicates the source of this notification. Combined with the Code it uniquely identifies this notification + + + + + A code that represents this notification. Combined with the Source it uniquely identifies this notification. + + + + + Human-readable text that explains this notification. + + + + + The translated message. The language and locale specified in the ClientDetail. Localization are used to determine the representation. Currently only supported in a TrackReply. + + + + + A collection of name/value pairs that provide specific data to help the client determine the nature of an error (or warning, etc.) witout having to parse the message string. + + + + + + + + + Identifies the type of data contained in Value (e.g. SERVICE_TYPE, PACKAGE_SEQUENCE, etc..). + + + + + The value of the parameter (e.g. PRIORITY_OVERNIGHT, 2, etc..). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Attributes about a reservation at a FedEx location. + + + + + + + + + + + + + Specifies additional constraints on the attributes of the locations being searched. + + + + + Specifies value and units of the radius around the address to search for FedEx locations. + + + + + The latest time at which the customer can drop off a package for being shipped using an express service. + + + + + Specifies the criteria used to filter the results of locations search. + + + + + Specifies the types of services supported by a FedEx location for redirect to hold. + + + + + + + + + + + + + + + + + + Specifies total number of location results that are available. + + + + + Specifies the number of location results returned in this reply. + + + + + Specifies the address formatted to have correct postal code per USPS standards. + + + + + The details about the relationship between the address requested and the locations returned. + + + + + + + + + Descriptive data to be used in authentication of the sender's identity (and right to use FedEx web services). + + + + + + + + + Specifies the criterion that may be used to search for FedEx locations. + + + + + Tracking number to be used when searching for locations. This tracking number, along with other location search constraints, help to narrow the search for locations. + + + + + + + + Specifies the criterion to be used to return location results when there are mutiple matches. + + + + + Specifies the details on how the location search results be sorted in the reply. + + + + + Contraints to be applied to location attributes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Specifies the types of services supported by a FedEx location for redirect to hold. + + + + + + + + + + + + + + + + + + Free form text to be echoed back in the reply. Used to match requests and replies. + + + + + Governs data payload language/translations (contrasted with ClientDetail.localization, which governs Notification.localizedMessage language selection). + + + + + + + + + + + + + + Used in authentication of the sender's identity. + + + + + This was renamed from cspCredential. + + + + + Credential used to authenticate a specific software application. This value is provided by FedEx after registration. + + + + + + + Two part authentication string used for the sender's identity + + + + + Identifying part of authentication credential. This value is provided by FedEx after registration + + + + + Secret part of authentication key. This value is provided by FedEx after registration. + + + + + + + Identifies the version/level of a service operation expected by a caller (in each request) and performed by the callee (in each reply). + + + + + Identifies a system or sub-system which performs an operation. + + + + + Identifies the service business level. + + + + + Identifies the service interface level. + + + + + Identifies the service code level. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/test_location_service.py b/tests/test_location_service.py new file mode 100644 index 0000000..a800cc7 --- /dev/null +++ b/tests/test_location_service.py @@ -0,0 +1,44 @@ +""" +Test module for the Fedex LocationService WSDL. +""" + +import unittest + +import sys + +sys.path.insert(0, '..') +from fedex.services.location_service import FedexSearchLocationRequest + +# Common global config object for testing. +from common import get_test_config + +CONFIG_OBJ = get_test_config() + + +@unittest.skipIf(not CONFIG_OBJ.account_number, "No credentials provided.") +class SearchLocationServiceTests(unittest.TestCase): + """ + These tests verify that the shipping service WSDL is in good shape. + """ + + def test_location_phone_search(self): + # Test location service phone query + + location_request = FedexSearchLocationRequest(CONFIG_OBJ) + + location_request.LocationsSearchCriterion = 'PHONE_NUMBER' + location_request.PhoneNumber = '4169297819' + location_request.MultipleMatchesAction = 'RETURN_ALL' + + location_request.Constraints.LocationTypesToInclude = ['FEDEX_AUTHORIZED_SHIP_CENTER'] + + location_request.Address.PostalCode = '38119' + location_request.Address.CountryCode = 'US' + + location_request.send_request() + + assert location_request.response + + +if __name__ == "__main__": + unittest.main() From c2106ff3e0f4081ae3883a2378b11e8979f9e975 Mon Sep 17 00:00:00 2001 From: radzhome Date: Sun, 17 Jan 2016 15:06:08 -0500 Subject: [PATCH 05/65] redirect logging to stdout in examples --- examples/address_validation.py | 5 +++-- examples/create_freight_shipment.py | 7 +++---- examples/create_shipment.py | 4 ++-- examples/delete_shipment.py | 4 +++- examples/example_config.py | 1 + examples/freight_rate_request.py | 5 +++-- examples/location_request.py | 6 +++--- examples/postal_inquiry.py | 4 +++- examples/rate_request.py | 5 +++-- examples/service_availability_request.py | 7 ++++--- examples/track_shipment.py | 4 +++- 11 files changed, 31 insertions(+), 21 deletions(-) diff --git a/examples/address_validation.py b/examples/address_validation.py index c48d61e..80a0939 100755 --- a/examples/address_validation.py +++ b/examples/address_validation.py @@ -4,6 +4,8 @@ class can handle up to 100 addresses for validation. """ import logging +import sys + from example_config import CONFIG_OBJ from fedex.services.address_validation_service import FedexAddressValidationRequest @@ -11,7 +13,7 @@ class can handle up to 100 addresses for validation. # BY DEFAULT, THE SERVICE IS DISABLED AND YOU WILL RECEIVE AUTHENTICATION FAILED, 1000 RESPONSE. # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our avs request. # We're using the FedexConfig object from example_config.py in this dir. @@ -47,7 +49,6 @@ class can handle up to 100 addresses for validation. address2.Address.CountryCode = 'US' avs_request.add_address(address2) - # If you'd like to see some documentation on the ship service WSDL, un-comment # this line. (Spammy). # print(avs_request.client) diff --git a/examples/create_freight_shipment.py b/examples/create_freight_shipment.py index 3ad98f7..d60dafb 100644 --- a/examples/create_freight_shipment.py +++ b/examples/create_freight_shipment.py @@ -9,7 +9,9 @@ label data that is returned with the reply. """ import logging +import sys import binascii + from example_config import CONFIG_OBJ from fedex.services.ship_service import FedexProcessShipmentRequest @@ -17,10 +19,9 @@ # Valid choices for this example are PDF, PNG GENERATE_IMAGE_TYPE = 'PDF' - # Set this to the INFO level to see the response from Fedex printed in stdout. # logging.basicConfig(filename="suds.log", level=logging.DEBUG) -logging.basicConfig(level=logging.INFO) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # NOTE: A VALID 'freight_account_number' REQUIRED IN YOUR 'CONFIB_OBJ' FOR THIS SERVICE TO WORK. # OTHERWISE YOU WILL GET FEDEX FREIGHT OR ASSOCIATED ADDRESS IS REQUIRED, ERROR 3619. @@ -87,7 +88,6 @@ shipment.RequestedShipment.FreightShipmentDetail.Role = role.SHIPPER shipment.RequestedShipment.FreightShipmentDetail.CollectTermsType = 'STANDARD' - # Specifies the label type to be returned. shipment.RequestedShipment.LabelSpecification.LabelFormatType = 'FEDEX_FREIGHT_STRAIGHT_BILL_OF_LADING' @@ -160,7 +160,6 @@ amount = shipment.response.CompletedShipmentDetail.ShipmentRating.ShipmentRateDetails[0].TotalNetCharge.Amount print("Net Shipping Cost (US$): {}".format(amount)) - # # Get the label image in ASCII format from the reply. Note the list indices # we're using. You'll need to adjust or iterate through these if your shipment # has multiple packages. diff --git a/examples/create_shipment.py b/examples/create_shipment.py index 0dcfdc2..8804d18 100755 --- a/examples/create_shipment.py +++ b/examples/create_shipment.py @@ -10,6 +10,7 @@ import logging import binascii import datetime +import sys from example_config import CONFIG_OBJ from fedex.services.ship_service import FedexProcessShipmentRequest @@ -18,9 +19,8 @@ # Valid choices for this example are PDF, PNG GENERATE_IMAGE_TYPE = 'PDF' - # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our shipment request. # We're using the FedexConfig object from example_config.py in this dir. diff --git a/examples/delete_shipment.py b/examples/delete_shipment.py index 01d81ca..bdaf756 100755 --- a/examples/delete_shipment.py +++ b/examples/delete_shipment.py @@ -3,11 +3,13 @@ This example shows how to delete existing shipments. """ import logging +import sys + from example_config import CONFIG_OBJ from fedex.services.ship_service import FedexDeleteShipmentRequest # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. # We're using the FedexConfig object from example_config.py in this dir. diff --git a/examples/example_config.py b/examples/example_config.py index b52e6d0..6fbcf51 100644 --- a/examples/example_config.py +++ b/examples/example_config.py @@ -5,6 +5,7 @@ """ import os import sys + # Use the fedex directory included in the downloaded package instead of # any globally installed versions. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/examples/freight_rate_request.py b/examples/freight_rate_request.py index 1da36b9..390fef1 100644 --- a/examples/freight_rate_request.py +++ b/examples/freight_rate_request.py @@ -9,11 +9,13 @@ is Out of Delivery Area (ODA). """ import logging +import sys + from example_config import CONFIG_OBJ from fedex.services.rate_service import FedexRateServiceRequest # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. # We're using the FedexConfig object from example_config.py in this dir. @@ -29,7 +31,6 @@ rate_request.RequestedShipment.FreightShipmentDetail.FedExFreightAccountNumber = CONFIG_OBJ.freight_account_number - # Shipper rate_request.RequestedShipment.Shipper.AccountNumber = CONFIG_OBJ.freight_account_number rate_request.RequestedShipment.Shipper.Contact.PersonName = 'Sender Name' diff --git a/examples/location_request.py b/examples/location_request.py index ddcc922..e63e7f7 100644 --- a/examples/location_request.py +++ b/examples/location_request.py @@ -7,12 +7,13 @@ """ import logging +import sys + from example_config import CONFIG_OBJ from fedex.services.location_service import FedexSearchLocationRequest # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) - +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. # We're using the FedexConfig object from example_config.py in this dir. @@ -50,4 +51,3 @@ # Here is the overall end result of the query. print("HighestSeverity:", location_request.response.HighestSeverity) - diff --git a/examples/postal_inquiry.py b/examples/postal_inquiry.py index d9b749b..b8fb8e2 100755 --- a/examples/postal_inquiry.py +++ b/examples/postal_inquiry.py @@ -4,11 +4,13 @@ information about postal codes. """ import logging +import sys + from example_config import CONFIG_OBJ from fedex.services.package_movement import PostalCodeInquiryRequest # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # We're using the FedexConfig object from example_config.py in this dir. inquiry = PostalCodeInquiryRequest(CONFIG_OBJ) diff --git a/examples/rate_request.py b/examples/rate_request.py index e8feb25..2b1aed5 100644 --- a/examples/rate_request.py +++ b/examples/rate_request.py @@ -9,12 +9,13 @@ is Out of Delivery Area (ODA). """ import logging +import sys + from example_config import CONFIG_OBJ from fedex.services.rate_service import FedexRateServiceRequest # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) - +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. # We're using the FedexConfig object from example_config.py in this dir. diff --git a/examples/service_availability_request.py b/examples/service_availability_request.py index 8c8f5fb..9fcfa23 100644 --- a/examples/service_availability_request.py +++ b/examples/service_availability_request.py @@ -7,13 +7,14 @@ exception thrown by suds. """ import logging +import sys import datetime + from example_config import CONFIG_OBJ from fedex.services.availability_commitment_service import FedexAvailabilityCommitmentRequest # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) - +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our service availability request. # We're using the FedexConfig object from example_config.py in this dir. @@ -32,7 +33,7 @@ # avc_request.Packaging = 'FEDEX_ENVELOPE' # Can be set to the expected date. Defaults to today if not set. -# avc_request.ShipDate = datetime.date.today().isoformat() +avc_request.ShipDate = datetime.date.today().isoformat() # Can be set to PRIORITY_OVERNIGHT, FEDEX_2_DAY, STANDARD_OVERNIGHT etc.. Defaults to showing all options if not set. # avc_request.Service = 'FEDEX_2_DAY' diff --git a/examples/track_shipment.py b/examples/track_shipment.py index 227f414..2d64cad 100755 --- a/examples/track_shipment.py +++ b/examples/track_shipment.py @@ -3,11 +3,13 @@ This example shows how to track shipments. """ import logging +import sys + from example_config import CONFIG_OBJ from fedex.services.track_service import FedexTrackRequest # Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) +logging.basicConfig(stream=sys.stdout, level=logging.INFO) # NOTE: TRACKING IS VERY ERRATIC ON THE TEST SERVERS. YOU MAY NEED TO USE # PRODUCTION KEYS/PASSWORDS/ACCOUNT #. THE TEST SERVERS OFTEN RETURN A NOT FOUND ERROR. From b8680b2d917b136631c53dbbfad4741dd3bcde91 Mon Sep 17 00:00:00 2001 From: radzhome Date: Sun, 17 Jan 2016 19:55:05 -0500 Subject: [PATCH 06/65] improved output for location service example, updated doc --- examples/location_request.py | 53 +++++++++++++++++++++++++++++- fedex/services/location_service.py | 4 ++- fedex/tools/__init__.py | 0 fedex/tools/response_tools.py | 53 ++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 fedex/tools/__init__.py create mode 100644 fedex/tools/response_tools.py diff --git a/examples/location_request.py b/examples/location_request.py index e63e7f7..ab94834 100644 --- a/examples/location_request.py +++ b/examples/location_request.py @@ -11,6 +11,7 @@ from example_config import CONFIG_OBJ from fedex.services.location_service import FedexSearchLocationRequest +from fedex.tools.response_tools import sobject_to_dict # Set this to the INFO level to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) @@ -26,6 +27,7 @@ location_request.MultipleMatchesAction = 'RETURN_ALL' # Set constraints, see SearchLocationConstraints definition. +# For LocationTypesToInclude, see FedExLocationType definition. location_request.Constraints.LocationTypesToInclude = ['FEDEX_SELF_SERVICE_LOCATION', 'FEDEX_AUTHORIZED_SHIP_CENTER'] @@ -49,5 +51,54 @@ # good to un-comment to see the variables returned by the FedEx reply. # print(location_request.response) +# This will convert the response to a python dict object. To +# make it easier to work with. +print(sobject_to_dict(location_request.response)) + # Here is the overall end result of the query. -print("HighestSeverity:", location_request.response.HighestSeverity) +print("HighestSeverity: {}".format(location_request.response.HighestSeverity)) +print("TotalResultsAvailable: {}".format(location_request.response.TotalResultsAvailable)) +print("ResultsReturned: {}".format(location_request.response.ResultsReturned)) + +result = location_request.response.AddressToLocationRelationships[0] +print("MatchedAddress: {}, {} Residential: {}".format(result.MatchedAddress.PostalCode, + result.MatchedAddress.CountryCode, + result.MatchedAddress.Residential)) +print("MatchedAddressGeographicCoordinates: {}".format(result.MatchedAddressGeographicCoordinates.strip("/"))) + +# Locations sorted by closest found to furthest. +locations = result.DistanceAndLocationDetails +for location in locations: + print("Distance: {}{}".format(location.Distance.Value, location.Distance.Units)) + + location_detail = location.LocationDetail + print("LocationID: {}".format(location_detail.LocationId)) + print("StoreNumber: {}".format(location_detail.StoreNumber)) + + if hasattr(location_detail, 'LocationContactAndAddress'): + contact_and_address = location_detail.LocationContactAndAddress + contact_and_address = sobject_to_dict(contact_and_address) + print("LocationContactAndAddress Dict: {}".format(contact_and_address)) + + print("GeographicCoordinates {}".format(getattr(location_detail, 'GeographicCoordinates'))) + print("LocationType {}".format(getattr(location_detail, 'LocationType'))) + + if hasattr(location_detail, 'Attributes'): + for attribute in location_detail.Attributes: + print "Attribute: {}".format(attribute) + + print("MapUrl {}".format(getattr(location_detail, 'MapUrl'))) + + if hasattr(location_detail, 'NormalHours'): + for open_time in location_detail.NormalHours: + print("NormalHours Dict: {}".format(sobject_to_dict(open_time))) + + if hasattr(location_detail, 'HoursForEffectiveDate'): + for effective_open_time in location_detail.HoursForEffectiveDate: + print("HoursForEffectiveDate Dict: {}".format(sobject_to_dict(effective_open_time))) + + if hasattr(location_detail, 'CarrierDetails'): + for carrier_detail in location_detail.CarrierDetails: + print("CarrierDetails Dict: {}".format(sobject_to_dict(carrier_detail))) + + print("") diff --git a/fedex/services/location_service.py b/fedex/services/location_service.py index dc98a90..233b3d7 100644 --- a/fedex/services/location_service.py +++ b/fedex/services/location_service.py @@ -12,7 +12,9 @@ class FedexSearchLocationRequest(FedexBaseService): """ - This class allows you validate service availability + This class allows you to figure out a FedEx location closest + to a specified location, based on location type. The response includes + location details like operating times, directions and a map link. """ def __init__(self, config_obj, *args, **kwargs): diff --git a/fedex/tools/__init__.py b/fedex/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fedex/tools/response_tools.py b/fedex/tools/response_tools.py new file mode 100644 index 0000000..79541df --- /dev/null +++ b/fedex/tools/response_tools.py @@ -0,0 +1,53 @@ +"""Response output conversion tools to help parse suds +response object output. +""" +from suds.sudsobject import asdict +from suds.sax.text import Text + + +def object_to_dict(obj): + """ Converts a suds object to a dictionary. + :param o: object + :return: dictionary + """ + out = {} + for k, v in asdict(obj).items(): + k = k.lower() + if hasattr(v, '__keylist__'): + out[k] = object_to_dict(v) + elif isinstance(v, list): + out[k] = [] + for item in v: + if hasattr(item, '__keylist__'): + out[k].append(object_to_dict(item)) + else: + out[k].append( + item.title() if isinstance(item, Text) else item) + else: + out[k] = v.title() if isinstance(v, Text) else v + return out +# +# import datetime +# +# def object_to_dict(obj): +# """ Converts an object to a dictionary. +# :param o: object +# :return: dictionary +# """ +# if isinstance(obj, (str, unicode, bool, int, long, float, datetime.datetime, datetime.date, datetime.time)): +# return obj +# data_dict = {} +# try: +# all_keys = obj.__dict__.keys() # vars(obj).keys() +# except AttributeError: +# return obj +# fields = [k for k in all_keys if not k.startswith('_')] +# for field in fields: +# val = getattr(obj, field) +# if isinstance(val, (list, tuple)): +# data_dict[field] = [] +# for item in val: +# data_dict[field].append(object_to_dict(item)) +# else: +# data_dict[field] = object_to_dict(val) +# return data_dict \ No newline at end of file From d3ad0af8303b46c2bd2213ccb2435a15a8feb9e1 Mon Sep 17 00:00:00 2001 From: radzhome Date: Sun, 17 Jan 2016 19:56:37 -0500 Subject: [PATCH 07/65] added tool to convert suds object output to dict --- fedex/tools/response_tools.py | 89 +++++++++++++++++------------------ 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/fedex/tools/response_tools.py b/fedex/tools/response_tools.py index 79541df..96e2273 100644 --- a/fedex/tools/response_tools.py +++ b/fedex/tools/response_tools.py @@ -1,53 +1,52 @@ """Response output conversion tools to help parse suds response object output. """ -from suds.sudsobject import asdict -from suds.sax.text import Text - -def object_to_dict(obj): - """ Converts a suds object to a dictionary. - :param o: object - :return: dictionary - """ - out = {} - for k, v in asdict(obj).items(): - k = k.lower() - if hasattr(v, '__keylist__'): - out[k] = object_to_dict(v) - elif isinstance(v, list): - out[k] = [] - for item in v: - if hasattr(item, '__keylist__'): - out[k].append(object_to_dict(item)) - else: - out[k].append( - item.title() if isinstance(item, Text) else item) - else: - out[k] = v.title() if isinstance(v, Text) else v - return out -# -# import datetime +# This is the suds way of doing this, but its slower. +# For reference only. +# from suds.sudsobject import asdict +# from suds.sax.text import Text # -# def object_to_dict(obj): -# """ Converts an object to a dictionary. -# :param o: object +# def response_to_dict(obj): +# """ Converts a suds object to a dictionary. +# :param obj: object # :return: dictionary # """ -# if isinstance(obj, (str, unicode, bool, int, long, float, datetime.datetime, datetime.date, datetime.time)): -# return obj -# data_dict = {} -# try: -# all_keys = obj.__dict__.keys() # vars(obj).keys() -# except AttributeError: -# return obj -# fields = [k for k in all_keys if not k.startswith('_')] -# for field in fields: -# val = getattr(obj, field) -# if isinstance(val, (list, tuple)): -# data_dict[field] = [] -# for item in val: -# data_dict[field].append(object_to_dict(item)) +# out = {} +# for k, v in asdict(obj).items(): # k = k.lower() +# if hasattr(v, '__keylist__'): +# out[k] = response_to_dict(v) +# elif isinstance(v, list): # tuple not used +# out[k] = [] +# for item in v: +# if hasattr(item, '__keylist__'): +# out[k].append(response_to_dict(item)) +# else: +# out[k].append( +# item.title() if isinstance(item, Text) else item) # else: -# data_dict[field] = object_to_dict(val) -# return data_dict \ No newline at end of file +# out[k] = v.title() if isinstance(v, Text) else v +# return out + + +def sobject_to_dict(obj, key_to_lower=False): + """ Converts a suds object to a dict. + :param key_to_lower: If set, changes index key name to lower case. + :param obj: suds object + :return: dict object + """ + if not hasattr(obj, '__keylist__'): + return obj + data = {} + fields = obj.__keylist__ + for field in fields: + val = getattr(obj, field) + if key_to_lower: + field = field.lower() + if isinstance(val, list): + data[field] = [] + for item in val: + data[field].append(sobject_to_dict(item)) + else: + data[field] = sobject_to_dict(val) + return data \ No newline at end of file From 73b8d13520e711595d80c1d601aaa5bb2658a332 Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 00:03:46 -0500 Subject: [PATCH 08/65] added json and dict response output --- examples/address_validation.py | 13 +++- examples/create_freight_shipment.py | 16 ++++- examples/create_shipment.py | 15 +++- examples/delete_shipment.py | 27 +++++-- examples/freight_rate_request.py | 17 +++-- examples/location_request.py | 13 ++-- examples/postal_inquiry.py | 19 ++++- examples/rate_request.py | 32 +++++++-- examples/service_availability_request.py | 13 +++- examples/track_shipment.py | 11 ++- fedex/tools/conversion.py | 92 ++++++++++++++++++++++++ fedex/tools/response_tools.py | 52 -------------- tests/test_tools.py | 0 13 files changed, 238 insertions(+), 82 deletions(-) create mode 100644 fedex/tools/conversion.py delete mode 100644 fedex/tools/response_tools.py create mode 100644 tests/test_tools.py diff --git a/examples/address_validation.py b/examples/address_validation.py index 80a0939..cc96d78 100755 --- a/examples/address_validation.py +++ b/examples/address_validation.py @@ -12,7 +12,7 @@ class can handle up to 100 addresses for validation. # NOTE: TO USE ADDRESS VALIDATION SERVICES, YOU NEED TO REQUEST FEDEX TO ENABLE THIS SERVICE FOR YOUR ACCOUNT. # BY DEFAULT, THE SERVICE IS DISABLED AND YOU WILL RECEIVE AUTHENTICATION FAILED, 1000 RESPONSE. -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our avs request. @@ -64,7 +64,16 @@ class can handle up to 100 addresses for validation. avs_request.send_request() # good to un-comment to see the variables returned by the Fedex reply. -print(avs_request.response) +# print(avs_request.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.response_tools import basic_sobject_to_dict +# print(basic_sobject_to_dict(avs_request.response)) + +# This will dump the response data dict to json. +# from fedex.tools.response_tools import sobject_to_json +# print(sobject_to_json(avs_request.response)) # Overall end result of the query for i in range(len(avs_request.response.AddressResults)): diff --git a/examples/create_freight_shipment.py b/examples/create_freight_shipment.py index d60dafb..ec5e0db 100644 --- a/examples/create_freight_shipment.py +++ b/examples/create_freight_shipment.py @@ -19,8 +19,7 @@ # Valid choices for this example are PDF, PNG GENERATE_IMAGE_TYPE = 'PDF' -# Set this to the INFO level to see the response from Fedex printed in stdout. -# logging.basicConfig(filename="suds.log", level=logging.DEBUG) +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # NOTE: A VALID 'freight_account_number' REQUIRED IN YOUR 'CONFIB_OBJ' FOR THIS SERVICE TO WORK. @@ -147,7 +146,18 @@ # This will show the reply to your shipment being sent. You can access the # attributes through the response attribute on the request object. This is # good to un-comment to see the variables returned by the Fedex reply. -print(shipment.response) +# print(shipment.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. Also see basic_sobject_to_dict, it's faster but lacks options. +# from fedex.tools.response_tools import sobject_to_dict +# response_dict = sobject_to_dict(shipment.response) +# response_dict['CompletedShipmentDetail']['ShipmentDocuments'][0]['Parts'][0]['Image'] = '' +# print(response_dict) # Image is empty string for display purposes. + +# This will dump the response data dict to json. +# from fedex.tools.response_tools import sobject_to_json +# print(sobject_to_json(shipment.response)) # Here is the overall end result of the query. print("HighestSeverity: {}".format(shipment.response.HighestSeverity)) diff --git a/examples/create_shipment.py b/examples/create_shipment.py index 8804d18..a6cb653 100755 --- a/examples/create_shipment.py +++ b/examples/create_shipment.py @@ -19,7 +19,7 @@ # Valid choices for this example are PDF, PNG GENERATE_IMAGE_TYPE = 'PDF' -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our shipment request. @@ -147,7 +147,18 @@ # This will show the reply to your shipment being sent. You can access the # attributes through the response attribute on the request object. This is # good to un-comment to see the variables returned by the Fedex reply. -print(shipment.response) +# print(shipment.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. Also see basic_sobject_to_dict, it's faster but lacks options. +# from fedex.tools.response_tools import sobject_to_dict +# response_dict = sobject_to_dict(shipment.response) +# response_dict['CompletedShipmentDetail']['CompletedPackageDetails'][0]['Label']['Parts'][0]['Image'] = '' +# print(response_dict) # Image is empty string for display purposes. + +# This will dump the response data dict to json. +# from fedex.tools.response_tools import sobject_to_json +# print(sobject_to_json(shipment.response)) # Here is the overall end result of the query. print("HighestSeverity: {}".format(shipment.response.HighestSeverity)) diff --git a/examples/delete_shipment.py b/examples/delete_shipment.py index bdaf756..ac65e15 100755 --- a/examples/delete_shipment.py +++ b/examples/delete_shipment.py @@ -7,8 +7,9 @@ from example_config import CONFIG_OBJ from fedex.services.ship_service import FedexDeleteShipmentRequest +from fedex.base_service import FedexError -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. @@ -21,7 +22,7 @@ del_request.DeletionControlType = "DELETE_ALL_PACKAGES" # The tracking number of the shipment to delete. -del_request.TrackingId.TrackingNumber = '794798682968' +del_request.TrackingId.TrackingNumber = '794798682968' # '111111111111' will also not delete # What kind of shipment the tracking number used. # Docs say this isn't required, but the WSDL won't validate without it. @@ -29,7 +30,25 @@ del_request.TrackingId.TrackingIdType = 'EXPRESS' # Fires off the request, sets the 'response' attribute on the object. -del_request.send_request() +try: + del_request.send_request() +except FedexError as e: + if 'Unable to retrieve record' in str(e): + print "WARNING: Unable to delete the shipment with the provided tracking number." + else: + print(e) # See the response printed out. -print(del_request.response) +# print(del_request.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.response_tools import basic_sobject_to_dict +# print(basic_sobject_to_dict(del_request.response)) + +# This will dump the response data dict to json. +# from fedex.tools.response_tools import sobject_to_json +# print(sobject_to_json(del_request.response)) + +# Here is the overall end result of the query. +print("HighestSeverity: {}".format(del_request.response.HighestSeverity)) diff --git a/examples/freight_rate_request.py b/examples/freight_rate_request.py index 390fef1..d354521 100644 --- a/examples/freight_rate_request.py +++ b/examples/freight_rate_request.py @@ -14,7 +14,7 @@ from example_config import CONFIG_OBJ from fedex.services.rate_service import FedexRateServiceRequest -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. @@ -114,17 +114,26 @@ # This will show the reply to your rate_request being sent. You can access the # attributes through the response attribute on the request object. This is # good to un-comment to see the variables returned by the FedEx reply. -print(rate_request.response) +# print(rate_request.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.response_tools import basic_sobject_to_dict +# print(basic_sobject_to_dict(rate_request.response)) + +# This will dump the response data dict to json. +# from fedex.tools.response_tools import sobject_to_json +# print(sobject_to_json(rate_request.response)) # Here is the overall end result of the query. -print("HighestSeverity:", rate_request.response.HighestSeverity) +print("HighestSeverity: {}".format(rate_request.response.HighestSeverity)) # RateReplyDetails can contain rates for multiple ServiceTypes if ServiceType was set to None for service in rate_request.response.RateReplyDetails: for detail in service.RatedShipmentDetails: for surcharge in detail.ShipmentRateDetail.Surcharges: if surcharge.SurchargeType == 'OUT_OF_DELIVERY_AREA': - print("%s: ODA rate_request charge {}".format(service.ServiceType, surcharge.Amount.Amount)) + print("{}: ODA rate_request charge {}".format(service.ServiceType, surcharge.Amount.Amount)) for rate_detail in service.RatedShipmentDetails: print("{}: Net FedEx Charge {} {}".format(service.ServiceType, diff --git a/examples/location_request.py b/examples/location_request.py index ab94834..bddfb9a 100644 --- a/examples/location_request.py +++ b/examples/location_request.py @@ -11,9 +11,9 @@ from example_config import CONFIG_OBJ from fedex.services.location_service import FedexSearchLocationRequest -from fedex.tools.response_tools import sobject_to_dict +from fedex.tools.conversion import sobject_to_dict -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. @@ -53,7 +53,12 @@ # This will convert the response to a python dict object. To # make it easier to work with. -print(sobject_to_dict(location_request.response)) +# from fedex.tools.response_tools import basic_sobject_to_dict +# print(basic_sobject_to_dict(location_request.response)) + +# This will dump the response data dict to json. +# from fedex.tools.response_tools import sobject_to_json +# print(sobject_to_json(location_request.response)) # Here is the overall end result of the query. print("HighestSeverity: {}".format(location_request.response.HighestSeverity)) @@ -85,7 +90,7 @@ if hasattr(location_detail, 'Attributes'): for attribute in location_detail.Attributes: - print "Attribute: {}".format(attribute) + print("Attribute: {}".format(attribute)) print("MapUrl {}".format(getattr(location_detail, 'MapUrl'))) diff --git a/examples/postal_inquiry.py b/examples/postal_inquiry.py index b8fb8e2..4676307 100755 --- a/examples/postal_inquiry.py +++ b/examples/postal_inquiry.py @@ -8,8 +8,9 @@ from example_config import CONFIG_OBJ from fedex.services.package_movement import PostalCodeInquiryRequest +from fedex.tools.conversion import sobject_to_dict -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # We're using the FedexConfig object from example_config.py in this dir. @@ -32,4 +33,18 @@ inquiry.send_request() # See the response printed out. -print(inquiry.response) +# print(inquiry.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.conversion import basic_sobject_to_dict +# print(basic_sobject_to_dict(inquiry.response)) + +# This will dump the response data dict to json. +# from fedex.tools.conversion import sobject_to_json +# print(sobject_to_json(inquiry.response)) + +# Here is the overall end result of the query. +print("HighestSeverity: {}".format(inquiry.response.HighestSeverity)) +print("ExpressFreightContractorDeliveryArea: {}".format(sobject_to_dict(inquiry.response.ExpressDescription))) +print("ExpressDescription: {}".format(sobject_to_dict(inquiry.response.ExpressFreightDescription))) diff --git a/examples/rate_request.py b/examples/rate_request.py index 2b1aed5..608f1cd 100644 --- a/examples/rate_request.py +++ b/examples/rate_request.py @@ -13,8 +13,9 @@ from example_config import CONFIG_OBJ from fedex.services.rate_service import FedexRateServiceRequest +from fedex.tools.conversion import sobject_to_dict -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our request. @@ -98,17 +99,36 @@ # good to un-comment to see the variables returned by the FedEx reply. # print(rate_request.response) +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.conversion import basic_sobject_to_dict +# print(basic_sobject_to_dict(rate_request.response)) + +# This will dump the response data dict to json. +# from fedex.tools.conversion import sobject_to_json +# print(sobject_to_json(rate_request.response)) + # Here is the overall end result of the query. -print("HighestSeverity:", rate_request.response.HighestSeverity) +print("HighestSeverity: {}".format(rate_request.response.HighestSeverity)) # RateReplyDetails can contain rates for multiple ServiceTypes if ServiceType was set to None for service in rate_request.response.RateReplyDetails: for detail in service.RatedShipmentDetails: for surcharge in detail.ShipmentRateDetail.Surcharges: if surcharge.SurchargeType == 'OUT_OF_DELIVERY_AREA': - print("%s: ODA rate_request charge %s" % (service.ServiceType, surcharge.Amount.Amount)) + print("{}: ODA rate_request charge {}".format(service.ServiceType, surcharge.Amount.Amount)) for rate_detail in service.RatedShipmentDetails: - print("%s: Net FedEx Charge %s %s" % (service.ServiceType, - rate_detail.ShipmentRateDetail.TotalNetFedExCharge.Currency, - rate_detail.ShipmentRateDetail.TotalNetFedExCharge.Amount)) + print("{}: Net FedEx Charge {} {}".format(service.ServiceType, + rate_detail.ShipmentRateDetail.TotalNetFedExCharge.Currency, + rate_detail.ShipmentRateDetail.TotalNetFedExCharge.Amount)) + +# Not sure if 'NOTE' checking should be put in base class. +# For now can check notifications manually. +# if notification.Severity == 'NOTE': +# self.logger.warning(FedexFailure(notification.Code, +# notification.Message)) +if rate_request.response.HighestSeverity == 'NOTE': + for notification in rate_request.response.Notifications: + if notification.Severity == 'NOTE': + print(sobject_to_dict(notification)) diff --git a/examples/service_availability_request.py b/examples/service_availability_request.py index 9fcfa23..5e17367 100644 --- a/examples/service_availability_request.py +++ b/examples/service_availability_request.py @@ -13,7 +13,7 @@ from example_config import CONFIG_OBJ from fedex.services.availability_commitment_service import FedexAvailabilityCommitmentRequest -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our service availability request. @@ -56,7 +56,16 @@ # This will show the reply to your avc_request being sent. You can access the # attributes through the response attribute on the request object. This is # good to un-comment to see the variables returned by the FedEx reply. -print(avc_request.response) +# print(avc_request.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.conversion import basic_sobject_to_dict +# print(basic_sobject_to_dict(avc_request.response)) + +# This will dump the response data dict to json. +# from fedex.tools.conversion import sobject_to_json +# print(basic_sobject_to_dict(avc_request.response)) # Here is the overall end result of the query. print("HighestSeverity: {}".format(avc_request.response.HighestSeverity)) diff --git a/examples/track_shipment.py b/examples/track_shipment.py index 2d64cad..00f84dd 100755 --- a/examples/track_shipment.py +++ b/examples/track_shipment.py @@ -8,7 +8,7 @@ from example_config import CONFIG_OBJ from fedex.services.track_service import FedexTrackRequest -# Set this to the INFO level to see the response from Fedex printed in stdout. +# Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # NOTE: TRACKING IS VERY ERRATIC ON THE TEST SERVERS. YOU MAY NEED TO USE @@ -50,6 +50,15 @@ # good to un-comment to see the variables returned by the FedEx reply. print(track.response) +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.conversion import basic_sobject_to_dict +# print(basic_sobject_to_dict(track.response)) + +# This will dump the response data dict to json. +# from fedex.tools.conversion import sobject_to_json +# print(basic_sobject_to_dict(track.response)) + # Look through the matches (there should only be one for a tracking number # query), and show a few details about each shipment. print("== Results ==") diff --git a/fedex/tools/conversion.py b/fedex/tools/conversion.py new file mode 100644 index 0000000..c1590cd --- /dev/null +++ b/fedex/tools/conversion.py @@ -0,0 +1,92 @@ +"""Response output conversion tools to help parse suds +response object output. +""" + +# This is the suds way of doing this, but its slower. +# For reference only. +# from suds.sudsobject import asdict +# from suds.sax.text import Text +# +# def response_to_dict(obj): +# """ Converts a suds object to a dictionary. +# :param obj: object +# :return: dictionary +# """ +# out = {} +# for k, v in asdict(obj).items(): # k = k.lower() +# if hasattr(v, '__keylist__'): +# out[k] = response_to_dict(v) +# elif isinstance(v, list): # tuple not used +# out[k] = [] +# for item in v: +# if hasattr(item, '__keylist__'): +# out[k].append(response_to_dict(item)) +# else: +# out[k].append( +# item.title() if isinstance(item, Text) else item) +# else: +# out[k] = v.title() if isinstance(v, Text) else v +# return out + + +def basic_sobject_to_dict(obj): + """Converts suds object to dict very quickly. + Does not serialize date time or normalize key case. + :param obj: suds object + :return: dict object + """ + if not hasattr(obj, '__keylist__'): + return obj + data = {} + fields = obj.__keylist__ + for field in fields: + val = getattr(obj, field) + if isinstance(val, list): + data[field] = [] + for item in val: + data[field].append(basic_sobject_to_dict(item)) + else: + data[field] = basic_sobject_to_dict(val) + return data + + +def sobject_to_dict(obj, key_to_lower=False, json_serialize=False): + """ + Converts a suds object to a dict. + :param json_serialize: If set, changes date and time types to iso string. + :param key_to_lower: If set, changes index key name to lower case. + :param obj: suds object + :return: dict object + """ + import datetime + + if not hasattr(obj, '__keylist__'): + if json_serialize and isinstance(obj, (datetime.datetime, datetime.time, datetime.date)): + return obj.isoformat() + else: + return obj + data = {} + fields = obj.__keylist__ + for field in fields: + val = getattr(obj, field) + if key_to_lower: + field = field.lower() + if isinstance(val, list): + data[field] = [] + for item in val: + data[field].append(sobject_to_dict(item, json_serialize=json_serialize)) + else: + data[field] = sobject_to_dict(val, json_serialize=json_serialize) + return data + + +def sobject_to_json(obj, key_to_lower=False): + """ + Converts a suds object to json. + :param obj: suds object + :param key_to_lower: If set, changes index key name to lower case. + :return: json object + """ + import json + data = sobject_to_dict(obj, key_to_lower=key_to_lower, json_serialize=True) + return json.dumps(data) diff --git a/fedex/tools/response_tools.py b/fedex/tools/response_tools.py deleted file mode 100644 index 96e2273..0000000 --- a/fedex/tools/response_tools.py +++ /dev/null @@ -1,52 +0,0 @@ -"""Response output conversion tools to help parse suds -response object output. -""" - -# This is the suds way of doing this, but its slower. -# For reference only. -# from suds.sudsobject import asdict -# from suds.sax.text import Text -# -# def response_to_dict(obj): -# """ Converts a suds object to a dictionary. -# :param obj: object -# :return: dictionary -# """ -# out = {} -# for k, v in asdict(obj).items(): # k = k.lower() -# if hasattr(v, '__keylist__'): -# out[k] = response_to_dict(v) -# elif isinstance(v, list): # tuple not used -# out[k] = [] -# for item in v: -# if hasattr(item, '__keylist__'): -# out[k].append(response_to_dict(item)) -# else: -# out[k].append( -# item.title() if isinstance(item, Text) else item) -# else: -# out[k] = v.title() if isinstance(v, Text) else v -# return out - - -def sobject_to_dict(obj, key_to_lower=False): - """ Converts a suds object to a dict. - :param key_to_lower: If set, changes index key name to lower case. - :param obj: suds object - :return: dict object - """ - if not hasattr(obj, '__keylist__'): - return obj - data = {} - fields = obj.__keylist__ - for field in fields: - val = getattr(obj, field) - if key_to_lower: - field = field.lower() - if isinstance(val, list): - data[field] = [] - for item in val: - data[field].append(sobject_to_dict(item)) - else: - data[field] = sobject_to_dict(val) - return data \ No newline at end of file diff --git a/tests/test_tools.py b/tests/test_tools.py new file mode 100644 index 0000000..e69de29 From 8c38bd671e58677a43b2c9057e89700d2f4d2f6a Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 00:04:32 -0500 Subject: [PATCH 09/65] added testing for conversion tools --- tests/test_tools.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/test_tools.py b/tests/test_tools.py index e69de29..4bed3c0 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -0,0 +1,44 @@ +""" +Test module for the Fedex Tools. +""" + +import unittest + +import sys + +sys.path.insert(0, '..') + +import fedex.config +import fedex.services.ship_service as service # Any request object will do. +import fedex.tools.conversion + + +class FedexToolsTests(unittest.TestCase): + """ + These tests verify that the fedex tools are working properly. + """ + + def test_conversion_tools(self): + # Empty config, since we are not actually sending anything + config = fedex.config.FedexConfig(key='', password='', + account_number='', meter_number='', + use_test_server=True) + + # We need a mock suds object, a request object or sub-object will do. + waybill_request = service.FedexProcessShipmentRequest(config) + obj = waybill_request.create_wsdl_object_of_type('ProcessShipmentRequest') + + # Test basic sobject to dict. + dict_obj = fedex.tools.conversion.basic_sobject_to_dict(obj) + assert type(dict_obj) == dict + + # Test with serialization and case conversion. + dict_obj = fedex.tools.conversion.sobject_to_dict(obj, key_to_lower=True, json_serialize=True) + assert type(dict_obj) == dict + + # JSON string object test + dict_obj = fedex.tools.conversion.sobject_to_json(obj) + assert dict_obj, "Expecting a JSON string object." + +if __name__ == "__main__": + unittest.main() From 8ac2e3898123624a60426908c9594fa380d45a9c Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 00:15:35 -0500 Subject: [PATCH 10/65] fix unit tests, update example readme --- examples/{README.txt => README.rst} | 7 +++++++ tests/test_location_service.py | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) rename examples/{README.txt => README.rst} (55%) diff --git a/examples/README.txt b/examples/README.rst similarity index 55% rename from examples/README.txt rename to examples/README.rst index 0e0cd95..29a7be7 100644 --- a/examples/README.txt +++ b/examples/README.rst @@ -1,5 +1,12 @@ python-fedex Examples ===================== + This directory contains a number of examples of how to use python-fedex. For these examples to work, you must open example_config.py and enter your testing account credentials there. + +To run all tests from bash, type: + + for f in *.py; do python "$f"; done + # Or use the below to only see response errors: + for f in *.py; do python "$f"; done | grep -i error \ No newline at end of file diff --git a/tests/test_location_service.py b/tests/test_location_service.py index a800cc7..48d2ffa 100644 --- a/tests/test_location_service.py +++ b/tests/test_location_service.py @@ -10,9 +10,9 @@ from fedex.services.location_service import FedexSearchLocationRequest # Common global config object for testing. -from common import get_test_config +from common import get_fedex_config -CONFIG_OBJ = get_test_config() +CONFIG_OBJ = get_fedex_config() @unittest.skipIf(not CONFIG_OBJ.account_number, "No credentials provided.") From 98c5f57eb3d7c1333377293d6ecba0fbf6c5fcab Mon Sep 17 00:00:00 2001 From: Rad Date: Mon, 18 Jan 2016 17:21:47 -0500 Subject: [PATCH 11/65] added next release changes --- CHANGES.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 8e827c7..876cda9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,15 @@ Change Log ========== +Next release +------------ + +* Added Location Service using v3 WSDL. (radzhome) +* Added examples and unit tests for Location Service. (radzhome) +* Updated certification process. (radzhome) +* Added warning logging for requests that come back with warning notes. (radzhome) + + 2.2.0 ----- From 8a01f542d11a2d0f6e4d52c928014cfe74933c2f Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 20:28:46 -0500 Subject: [PATCH 12/65] fixed imports, logging, added test for location service * made sure imports compatible when running tests with nosetests or straight python. * added basic minimal test for location service. * added default logging when using straight python to execute tests --- tests/test_address_validation_service.py | 3 ++- tests/test_availability_commitment_service.py | 3 ++- tests/test_config_object.py | 3 ++- tests/test_country_service.py | 3 ++- tests/test_location_service.py | 16 ++++++++++++---- tests/test_package_movement_service.py | 13 ++++++++++--- tests/test_rate_service.py | 3 ++- tests/test_ship_service.py | 3 ++- tests/test_tools.py | 3 ++- tests/test_track_service.py | 3 ++- 10 files changed, 38 insertions(+), 15 deletions(-) diff --git a/tests/test_address_validation_service.py b/tests/test_address_validation_service.py index a906454..fc7085c 100644 --- a/tests/test_address_validation_service.py +++ b/tests/test_address_validation_service.py @@ -10,7 +10,7 @@ from fedex.services.address_validation_service import FedexAddressValidationRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() @@ -41,4 +41,5 @@ def test_avs(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_availability_commitment_service.py b/tests/test_availability_commitment_service.py index dd7ac7b..3a4cd6b 100644 --- a/tests/test_availability_commitment_service.py +++ b/tests/test_availability_commitment_service.py @@ -10,7 +10,7 @@ from fedex.services.availability_commitment_service import FedexAvailabilityCommitmentRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() @@ -40,4 +40,5 @@ def test_track(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_config_object.py b/tests/test_config_object.py index 705b2b9..d255b52 100644 --- a/tests/test_config_object.py +++ b/tests/test_config_object.py @@ -3,7 +3,7 @@ """ import unittest - +import logging import sys sys.path.insert(0, '..') @@ -35,4 +35,5 @@ def test_fedex_config(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_country_service.py b/tests/test_country_service.py index 77bc358..b5449ff 100644 --- a/tests/test_country_service.py +++ b/tests/test_country_service.py @@ -10,7 +10,7 @@ from fedex.services.country_service import FedexValidatePostalRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() @@ -35,4 +35,5 @@ def test_postal_inquiry(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_location_service.py b/tests/test_location_service.py index 48d2ffa..948227a 100644 --- a/tests/test_location_service.py +++ b/tests/test_location_service.py @@ -3,17 +3,18 @@ """ import unittest - +import logging import sys sys.path.insert(0, '..') from fedex.services.location_service import FedexSearchLocationRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() +logging.getLogger('suds').setLevel(logging.ERROR) @unittest.skipIf(not CONFIG_OBJ.account_number, "No credentials provided.") class SearchLocationServiceTests(unittest.TestCase): @@ -32,13 +33,20 @@ def test_location_phone_search(self): location_request.Constraints.LocationTypesToInclude = ['FEDEX_AUTHORIZED_SHIP_CENTER'] - location_request.Address.PostalCode = '38119' - location_request.Address.CountryCode = 'US' + location_request.Address.PostalCode = 'M5V 1Z0' + location_request.Address.CountryCode = 'CA' location_request.send_request() assert location_request.response + def test_location_address_search(self): + # Test search by address, using minimum parameters + + location_request = FedexSearchLocationRequest(CONFIG_OBJ) + location_request.Address.PostalCode = '38119' + location_request.Address.CountryCode = 'US' if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_package_movement_service.py b/tests/test_package_movement_service.py index 3ac4e2f..e7c127d 100644 --- a/tests/test_package_movement_service.py +++ b/tests/test_package_movement_service.py @@ -6,11 +6,11 @@ import logging import sys -sys.path.insert(0, '..') +sys.path.insert(0, '../') from fedex.services.package_movement import PostalCodeInquiryRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() @@ -23,8 +23,14 @@ class PackageMovementServiceTests(unittest.TestCase): These tests verify that the package movement service WSDL is in good shape. """ + def setUp(self): + self.config_obj = get_fedex_config() + + def tearDown(self): + pass + def test_postal_inquiry(self): - inquiry = PostalCodeInquiryRequest(CONFIG_OBJ) + inquiry = PostalCodeInquiryRequest(self.config_obj) inquiry.PostalCode = '29631' inquiry.CountryCode = 'US' @@ -35,4 +41,5 @@ def test_postal_inquiry(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_rate_service.py b/tests/test_rate_service.py index 663394e..8646723 100644 --- a/tests/test_rate_service.py +++ b/tests/test_rate_service.py @@ -10,7 +10,7 @@ from fedex.services.rate_service import FedexRateServiceRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() @@ -56,4 +56,5 @@ def test_rate(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_ship_service.py b/tests/test_ship_service.py index 8673264..1f78dda 100644 --- a/tests/test_ship_service.py +++ b/tests/test_ship_service.py @@ -11,7 +11,7 @@ from fedex.services.ship_service import FedexDeleteShipmentRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() @@ -90,4 +90,5 @@ def test_create_delete_shipment(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_tools.py b/tests/test_tools.py index 4bed3c0..c66bbe4 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -3,7 +3,7 @@ """ import unittest - +import logging import sys sys.path.insert(0, '..') @@ -41,4 +41,5 @@ def test_conversion_tools(self): assert dict_obj, "Expecting a JSON string object." if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() diff --git a/tests/test_track_service.py b/tests/test_track_service.py index 780228a..5767619 100644 --- a/tests/test_track_service.py +++ b/tests/test_track_service.py @@ -10,7 +10,7 @@ from fedex.services.track_service import FedexTrackRequest # Common global config object for testing. -from common import get_fedex_config +from tests.common import get_fedex_config CONFIG_OBJ = get_fedex_config() @@ -50,4 +50,5 @@ def test_track(self): if __name__ == "__main__": + logging.basicConfig(stream=sys.stdout, level=logging.INFO) unittest.main() From 77bac4d7ead72bbde7597a38ff7e93c4ee60cbd0 Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 20:31:57 -0500 Subject: [PATCH 13/65] refactor variable names, add warn logging * function local variable names should not be camel cased, fixed to lower case with underscores. * added a warning logger when request returns with NOTE warning from fedex. --- fedex/base_service.py | 94 ++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/fedex/base_service.py b/fedex/base_service.py index 3ec99cb..4b2ab33 100755 --- a/fedex/base_service.py +++ b/fedex/base_service.py @@ -23,6 +23,7 @@ def __init__(self, **kwargs): self.kwargs = kwargs def marshalled(self, context): + # Removes the WSDL objects that do not have a value before sending. context.envelope = context.envelope.prune() def sending(self, context): @@ -106,9 +107,14 @@ def __init__(self, config_obj, wsdl_name, *args, **kwargs): self.logger = logging.getLogger('fedex') """@ivar: Python logger instance with name 'fedex'.""" + self.config_obj = config_obj """@ivar: The FedexConfig object to pull auth info from.""" + if not self._version_info: + self._version_info = {} + """#ivar: Set in each service class. Holds version info for the VersionId SOAP object.""" + # If the config object is set to use the test server, point # suds at the test server WSDL directory. if config_obj.use_test_server: @@ -149,19 +155,19 @@ def __set_web_authentication_detail(self): """ # Start of the authentication stuff. - WebAuthenticationCredential = self.client.factory.create('WebAuthenticationCredential') - WebAuthenticationCredential.Key = self.config_obj.key - WebAuthenticationCredential.Password = self.config_obj.password + web_authentication_credential = self.client.factory.create('WebAuthenticationCredential') + web_authentication_credential.Key = self.config_obj.key + web_authentication_credential.Password = self.config_obj.password # Encapsulates the auth credentials. - WebAuthenticationDetail = self.client.factory.create('WebAuthenticationDetail') - WebAuthenticationDetail.UserCredential = WebAuthenticationCredential + web_authentication_detail = self.client.factory.create('WebAuthenticationDetail') + web_authentication_detail.UserCredential = web_authentication_credential # Set Default ParentCredential - if hasattr(WebAuthenticationDetail, 'ParentCredential'): - WebAuthenticationDetail.ParentCredential = WebAuthenticationCredential + if hasattr(web_authentication_detail, 'ParentCredential'): + web_authentication_detail.ParentCredential = web_authentication_credential - self.WebAuthenticationDetail = WebAuthenticationDetail + self.WebAuthenticationDetail = web_authentication_detail def __set_client_detail(self, *args, **kwargs): """ @@ -169,28 +175,28 @@ def __set_client_detail(self, *args, **kwargs): related requests. """ - ClientDetail = self.client.factory.create('ClientDetail') - ClientDetail.AccountNumber = self.config_obj.account_number - ClientDetail.MeterNumber = self.config_obj.meter_number - ClientDetail.IntegratorId = self.config_obj.integrator_id - if hasattr(ClientDetail, 'Region'): - ClientDetail.Region = self.config_obj.express_region_code + client_detail = self.client.factory.create('ClientDetail') + client_detail.AccountNumber = self.config_obj.account_number + client_detail.MeterNumber = self.config_obj.meter_number + client_detail.IntegratorId = self.config_obj.integrator_id + if hasattr(client_detail, 'Region'): + client_detail.Region = self.config_obj.express_region_code client_language_code = kwargs.get('client_language_code', None) client_locale_code = kwargs.get('client_locale_code', None) - if hasattr(ClientDetail, 'Localization') and (client_language_code or client_locale_code): - Localization = self.client.factory.create('Localization') + if hasattr(client_detail, 'Localization') and (client_language_code or client_locale_code): + localization = self.client.factory.create('Localization') if client_language_code: - Localization.LanguageCode = client_language_code + localization.LanguageCode = client_language_code if client_locale_code: - Localization.LocaleCode = client_locale_code + localization.LocaleCode = client_locale_code - ClientDetail.Localization = Localization + client_detail.Localization = localization - self.ClientDetail = ClientDetail + self.ClientDetail = client_detail def __set_transaction_detail(self, *args, **kwargs): """ @@ -199,23 +205,23 @@ def __set_transaction_detail(self, *args, **kwargs): customer_transaction_id = kwargs.get('customer_transaction_id', None) if customer_transaction_id: - TransactionDetail = self.client.factory.create('TransactionDetail') - TransactionDetail.CustomerTransactionId = customer_transaction_id - self.logger.debug(TransactionDetail) - self.TransactionDetail = TransactionDetail + transaction_detail = self.client.factory.create('TransactionDetail') + transaction_detail.CustomerTransactionId = customer_transaction_id + self.logger.debug(transaction_detail) + self.TransactionDetail = transaction_detail 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'] - VersionId.Intermediate = self._version_info['intermediate'] - VersionId.Minor = self._version_info['minor'] - self.logger.debug(VersionId) - self.VersionId = VersionId + version_id = self.client.factory.create('VersionId') + version_id.ServiceId = self._version_info['service_id'] + version_id.Major = self._version_info['major'] + version_id.Intermediate = self._version_info['intermediate'] + version_id.Minor = self._version_info['minor'] + self.logger.debug(version_id) + self.VersionId = version_id def _prepare_wsdl_objects(self): """ @@ -251,17 +257,34 @@ def _check_response_for_request_errors(self): raise FedexError(notification.Code, notification.Message) + def _check_response_for_request_warnings(self): + """ + Override this in a service module to check for errors that are + specific to that module. For example, changing state/province based + on postal code in a Rate Service request. + """ + + if self.response.HighestSeverity == "NOTE": + for notification in self.response.Notifications: + if notification.Severity == "NOTE": + self.logger.warning(FedexFailure(notification.Code, + notification.Message)) + def create_wsdl_object_of_type(self, type_name): """ Creates and returns a WSDL object of the specified type. + :param type_name: specifies the object's type name from WSDL. """ return self.client.factory.create(type_name) def _assemble_and_send_request(self): """ - This method should be over-ridden on each sub-class. It assembles all required objects + This method should be over-ridden on each sub-class. + It assembles all required objects into the specific request object and calls send_request. + Objects that are not set will be pruned before sending + via GeneralSudsPlugin marshalled function. """ pass @@ -295,10 +318,15 @@ def send_request(self, send_function=None): # Check the response for general Fedex errors/failures that aren't # specific to any given WSDL/request. self.__check_response_for_fedex_error() + # Check the response for errors specific to the particular request. - # This is handled by an overridden method on the child object. + # This method can be overridden by a method on the child class object. self._check_response_for_request_errors() + # Check the response for errors specific to the particular request. + # This method can be overridden by a method on the child class object. + self._check_response_for_request_warnings() + # Debug output. self.logger.debug("== FEDEX QUERY RESULT ==") self.logger.debug(self.response) From b2ec87d4290213186286853d2a48e29f11642292 Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 20:33:13 -0500 Subject: [PATCH 14/65] added sortDetail object, added doc * Sort detail was added to be able to sort the query results for locations. * Added missing variable documentation. --- fedex/services/location_service.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/fedex/services/location_service.py b/fedex/services/location_service.py index 233b3d7..460dcb3 100644 --- a/fedex/services/location_service.py +++ b/fedex/services/location_service.py @@ -1,6 +1,6 @@ """ Location Service Module -================================= + This package contains the shipping methods defined by Fedex's LocationService WSDL file. Each is encapsulated in a class for easy access. For more details on each, refer to the respective class's @@ -13,8 +13,9 @@ class FedexSearchLocationRequest(FedexBaseService): """ This class allows you to figure out a FedEx location closest - to a specified location, based on location type. The response includes - location details like operating times, directions and a map link. + to a specified location criteria, based on location type. + The response includes location details like operating times, + directions and a map link and more. """ def __init__(self, config_obj, *args, **kwargs): @@ -32,14 +33,24 @@ def __init__(self, config_obj, *args, **kwargs): 'minor': '0' } - """@ivar: set default objects.""" + # Set default objects. self.Address = None + """@ivar: Holds the Address WSDL object.""" + self.PhoneNumber = None + """@ivar: Holds the PhoneNumber string object.""" + self.MultipleMatchesAction = None + """@ivar: Holds the MultipleMatchesActionType WSDL object.""" + self.Constraints = [] + """@ivar: Holds a list of SearchLocationConstraints WSDL objects.""" + self.LocationsSearchCriterion = None + """@ivar: Holds the LocationsSearchCriteriaType WSDL object.""" - """@ivar: Holds the WSDL object.""" + self.SortDetail = None + """@ivar: Holds the LocationSortDetail WSDL object.""" super(FedexSearchLocationRequest, self).__init__( self._config_obj, 'LocationsService_v3.wsdl', *args, **kwargs) @@ -48,9 +59,13 @@ def _prepare_wsdl_objects(self): """ Create the data structure and get it ready for the WSDL request. """ + + # Service defaults for objects that are required. self.MultipleMatchesAction = 'RETURN_ALL' self.Constraints = self.create_wsdl_object_of_type('SearchLocationConstraints') self.Address = self.create_wsdl_object_of_type('Address') + self.LocationsSearchCriterion = 'ADDRESS' + self.SortDetail = self.create_wsdl_object_of_type('LocationSortDetail') def _assemble_and_send_request(self): """ @@ -78,4 +93,5 @@ def _assemble_and_send_request(self): PhoneNumber=self.PhoneNumber, MultipleMatchesAction=self.MultipleMatchesAction, Constraints=self.Constraints, - Address=self.Address) + Address=self.Address, + SortDetail=self.SortDetail) From dce689f2c2c15a43e33502a1eec0912b9e7fd0f6 Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 20:34:49 -0500 Subject: [PATCH 15/65] added deprecation warning for packave movement --- fedex/services/package_movement.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/fedex/services/package_movement.py b/fedex/services/package_movement.py index 635a05d..6657f52 100755 --- a/fedex/services/package_movement.py +++ b/fedex/services/package_movement.py @@ -4,7 +4,8 @@ This package contains classes to check service availability, route, and postal codes. Defined by the PackageMovementInformationService WSDL file. """ -import logging +import warnings + from ..base_service import FedexBaseService, FedexError @@ -41,11 +42,22 @@ def __init__(self, config_obj, postal_code=None, country_code=None, *args, **kwa self._config_obj = config_obj # Holds version info for the VersionId SOAP object. - self._version_info = {'service_id': 'pmis', 'major': '4', - 'intermediate': '0', 'minor': '0'} + self._version_info = {'service_id': 'pmis', + 'major': '4', + 'intermediate': '0', + 'minor': '0'} + self.PostalCode = postal_code self.CountryCode = country_code + warnings.warn( + "DeprecationWarning: Package Movement Service has been deprecated; " + "please use Country Service for postal code validation requests or " + "Availability and Commitment Service for service availability " + "requests instead.", + DeprecationWarning + ) + # Call the parent FedexBaseService class for basic setup work. super(PostalCodeInquiryRequest, self).__init__(self._config_obj, 'PackageMovementInformationService_v4.wsdl', @@ -84,6 +96,7 @@ 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 # We get an exception like this when specifying an IntegratorId: From 504663f803e0e2ec3a8604566dedb98083b48293 Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 20:36:19 -0500 Subject: [PATCH 16/65] added more example detail for location service --- examples/location_request.py | 70 ++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/examples/location_request.py b/examples/location_request.py index bddfb9a..afe5313 100644 --- a/examples/location_request.py +++ b/examples/location_request.py @@ -1,8 +1,10 @@ #!/usr/bin/env python """ This example shows how to use the FedEx Location service. -The variables populated below represents the minimum required values. -You will need to fill all of these, or risk seeing a SchemaValidationError +The variables populated below represents minimum required values as +well as those that are optional. Read comments for details. +You will need to specify all required fields, or risk +seeing a SchemaValidationError exception thrown by suds. """ @@ -21,18 +23,49 @@ customer_transaction_id = "*** LocationService Request v3 using Python ***" # Optional transaction_id location_request = FedexSearchLocationRequest(CONFIG_OBJ, customer_transaction_id=customer_transaction_id) -# Specify the type of search and search criteria. -location_request.LocationsSearchCriterion = 'PHONE_NUMBER' -location_request.PhoneNumber = '4169297819' -location_request.MultipleMatchesAction = 'RETURN_ALL' +# Un-comment to specify the type of search and search criteria. +# Can be ADDRESS (default), GEOGRAPHIC_COORDINATES, or PHONE_NUMBER +# location_request.LocationsSearchCriterion = 'PHONE_NUMBER' -# Set constraints, see SearchLocationConstraints definition. -# For LocationTypesToInclude, see FedExLocationType definition. -location_request.Constraints.LocationTypesToInclude = ['FEDEX_SELF_SERVICE_LOCATION', - 'FEDEX_AUTHORIZED_SHIP_CENTER'] +# Un-comment when using PHONE_NUMBER search criterion. +# location_request.PhoneNumber = '4169297819' -location_request.Address.PostalCode = '38119' -location_request.Address.CountryCode = 'US' +# Un-comment when using GEOGRAPHIC_COORDINATES search criterion. +# location_request.GeographicCoordinates = '43.6357-79.5373' + +# Un-comment to specify how to handle multiple matches. +# Can be set to RETURN_ALL (default), RETURN_ERROR, or RETURN_FIRST +# location_request.MultipleMatchesAction = 'RETURN_FIRST' + + +# Un-comment to specify FedExLocationType constraint, see FedExLocationType definition. +# Can be set to FEDEX_AUTHORIZED_SHIP_CENTER, FEDEX_EXPRESS_STATION, FEDEX_FREIGHT_SERVICE_CENTER, +# FEDEX_GROUND_TERMINAL, FEDEX_HOME_DELIVERY_STATION, FEDEX_OFFICE, FEDEX_SELF_SERVICE_LOCATION, +# FEDEX_SHIPSITE, or FEDEX_SMART_POST_HUB +# location_request.Constraints.LocationTypesToInclude = ['FEDEX_SELF_SERVICE_LOCATION', +# 'FEDEX_AUTHORIZED_SHIP_CENTER'] + +# Un-comment to to set a maximum radius for location query. +# This really can narrow down the location results but is not required. +location_request.Constraints.RadiusDistance.Value = 1.5 +location_request.Constraints.RadiusDistance.Units = "KM" # KM or MI + +# Un-comment to specify supported redirect to hold services. Only +# supported by certain countries,from testing only US is supported. +# Can be FEDEX_EXPRESS, FEDEX_GROUND, or FEDEX_GROUND_HOME_DELIVERY +# location_request.Constraints.SupportedRedirectToHoldServices = "FEDEX_GROUND" + +# Required even if using phone number search +location_request.Address.PostalCode = 'M5V 1Z0' +location_request.Address.CountryCode = 'CA' + +# Un-comment to set sort criteria. By default Matching locations sorted by +# DISTANCE and LOWEST_TO_HIGHEST if no sort criteria is specified. +# Crieterion can be LATEST_EXPRESS_DROPOFF_TIME, LATEST_GROUND_DROPOFF_TIME, +# LOCATION_TYPE or DISTANCE (default) +# Order can be LOWEST_TO_HIGHEST (default) or HIGHEST_TO_LOWEST +# location_request.SortDetail.Criterion = 'LATEST_GROUND_DROPOFF_TIME' +# location_request.SortDetail.Order = 'LOWEST_TO_HIGHEST' # If you'd like to see some documentation on the ship service WSDL, un-comment # this line. (Spammy). @@ -66,12 +99,11 @@ print("ResultsReturned: {}".format(location_request.response.ResultsReturned)) result = location_request.response.AddressToLocationRelationships[0] -print("MatchedAddress: {}, {} Residential: {}".format(result.MatchedAddress.PostalCode, - result.MatchedAddress.CountryCode, - result.MatchedAddress.Residential)) +print("MatchedAddress: {}, {} Residential: {}".format(getattr(result.MatchedAddress, 'PostalCode', ''), + getattr(result.MatchedAddress, 'CountryCode', ''), + getattr(result.MatchedAddress, 'Residential', ''))) print("MatchedAddressGeographicCoordinates: {}".format(result.MatchedAddressGeographicCoordinates.strip("/"))) -# Locations sorted by closest found to furthest. locations = result.DistanceAndLocationDetails for location in locations: print("Distance: {}{}".format(location.Distance.Value, location.Distance.Units)) @@ -85,14 +117,14 @@ contact_and_address = sobject_to_dict(contact_and_address) print("LocationContactAndAddress Dict: {}".format(contact_and_address)) - print("GeographicCoordinates {}".format(getattr(location_detail, 'GeographicCoordinates'))) - print("LocationType {}".format(getattr(location_detail, 'LocationType'))) + print("GeographicCoordinates {}".format(getattr(location_detail, 'GeographicCoordinates', ''))) + print("LocationType {}".format(getattr(location_detail, 'LocationType', ''))) if hasattr(location_detail, 'Attributes'): for attribute in location_detail.Attributes: print("Attribute: {}".format(attribute)) - print("MapUrl {}".format(getattr(location_detail, 'MapUrl'))) + print("MapUrl {}".format(getattr(location_detail, 'MapUrl', ''))) if hasattr(location_detail, 'NormalHours'): for open_time in location_detail.NormalHours: From a6b7c5b28cc0417c4c5ac423d1a8a3ed7ff85b2b Mon Sep 17 00:00:00 2001 From: radzhome Date: Mon, 18 Jan 2016 20:49:05 -0500 Subject: [PATCH 17/65] pep-8 pycharm pass, force deprecation for movement service * pep-8 pass on the entire package * force deprecation warning for python 2.7 * rename package movement to deprecated status * promote country service for postal validation --- examples/country_postal_inquiry.py | 57 ------------------ examples/postal_inquiry.py | 58 ++++++++++--------- examples/postal_inquiry_deprecated.py | 52 +++++++++++++++++ examples/rate_request.py | 6 +- examples/track_shipment.py | 3 +- fedex/base_service.py | 1 - fedex/services/address_validation_service.py | 14 ++--- .../availability_commitment_service.py | 22 +++---- fedex/services/country_service.py | 20 +++---- fedex/services/location_service.py | 22 +++---- fedex/services/package_movement.py | 10 ++-- fedex/services/rate_service.py | 14 ++--- fedex/services/ship_service.py | 36 ++++++------ fedex/services/track_service.py | 16 ++--- fedex/tools/conversion.py | 1 + tests/test_package_movement_service.py | 3 + 16 files changed, 168 insertions(+), 167 deletions(-) delete mode 100755 examples/country_postal_inquiry.py create mode 100755 examples/postal_inquiry_deprecated.py diff --git a/examples/country_postal_inquiry.py b/examples/country_postal_inquiry.py deleted file mode 100755 index 9ea4fc9..0000000 --- a/examples/country_postal_inquiry.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python -""" -ValidatePostalRequest classes are used to validate and receive additional -information about postal codes. -""" -import logging -from example_config import CONFIG_OBJ -from fedex.services.country_service import FedexValidatePostalRequest - -# Set this to the INFO level to see the response from Fedex printed in stdout. -logging.basicConfig(level=logging.INFO) - -# We're using the FedexConfig object from example_config.py in this dir. -customer_transaction_id = "*** ValidatePostal Request v4 using Python ***" # Optional transaction_id -inquiry = FedexValidatePostalRequest(CONFIG_OBJ, customer_transaction_id=customer_transaction_id) -inquiry.Address.PostalCode = '29631' -inquiry.Address.CountryCode = 'US' -inquiry.Address.StreetLines = ['104 Knox Road'] -inquiry.Address.City = 'Clemson' -inquiry.Address.StateOrProvinceCode = 'SC' - -# If you'd like to see some documentation on the country service WSDL, un-comment -# this line. (Spammy). -# print(inquiry.client) - -# Un-comment this to see your complete, ready-to-send request as it stands -# before it is actually sent. This is useful for seeing what values you can -# change. -# print(inquiry.CarrierCode) -# print(inquiry.Address) -# print(inquiry.ShipDateTime) -# print(inquiry.CheckForMismatch) -# print(inquiry.RoutingCode) - -# Fires off the request, sets the 'response' attribute on the object. -inquiry.send_request() - -# See the response printed out. -print(inquiry.response) - -# Here is the overall end result of the query. -print("HighestSeverity: {}".format(inquiry.response.HighestSeverity)) -print("") - -print("State/Province: {}".format(inquiry.response.PostalDetail.StateOrProvinceCode)) -print("City First Initial: {}".format(inquiry.response.PostalDetail.CityFirstInitials)) -print("Clean Postal Code: {}".format(inquiry.response.PostalDetail.CleanedPostalCode)) - -for loc_description in inquiry.response.PostalDetail.LocationDescriptions: - print("Location ID: {}".format(loc_description.LocationId)) - print("Location No.: {}".format(loc_description.LocationNumber)) - print("Country Code: {}".format(loc_description.CountryCode)) - print("Postal Code: {}".format(loc_description.PostalCode)) - print("Service Area: {}".format(loc_description.ServiceArea)) - print("Airport ID: {}".format(loc_description.AirportId)) - print("FedEx Europe First Origin: {}".format(loc_description.FedExEuropeFirstOrigin)) - diff --git a/examples/postal_inquiry.py b/examples/postal_inquiry.py index 4676307..844c7e8 100755 --- a/examples/postal_inquiry.py +++ b/examples/postal_inquiry.py @@ -1,24 +1,25 @@ #!/usr/bin/env python """ -PostalCodeInquiryRequest classes are used to validate and receive additional +ValidatePostalRequest classes are used to validate and receive additional information about postal codes. """ import logging -import sys - from example_config import CONFIG_OBJ -from fedex.services.package_movement import PostalCodeInquiryRequest -from fedex.tools.conversion import sobject_to_dict +from fedex.services.country_service import FedexValidatePostalRequest -# Un-comment to see the response from Fedex printed in stdout. -logging.basicConfig(stream=sys.stdout, level=logging.INFO) +# Set this to the INFO level to see the response from Fedex printed in stdout. +logging.basicConfig(level=logging.INFO) # We're using the FedexConfig object from example_config.py in this dir. -inquiry = PostalCodeInquiryRequest(CONFIG_OBJ) -inquiry.PostalCode = '29631' -inquiry.CountryCode = 'US' - -# If you'd like to see some documentation on the ship service WSDL, un-comment +customer_transaction_id = "*** ValidatePostal Request v4 using Python ***" # Optional transaction_id +inquiry = FedexValidatePostalRequest(CONFIG_OBJ, customer_transaction_id=customer_transaction_id) +inquiry.Address.PostalCode = '29631' +inquiry.Address.CountryCode = 'US' +inquiry.Address.StreetLines = ['104 Knox Road'] +inquiry.Address.City = 'Clemson' +inquiry.Address.StateOrProvinceCode = 'SC' + +# If you'd like to see some documentation on the country service WSDL, un-comment # this line. (Spammy). # print(inquiry.client) @@ -26,25 +27,30 @@ # before it is actually sent. This is useful for seeing what values you can # change. # print(inquiry.CarrierCode) -# print(inquiry.ClientDetail) -# print(inquiry.TransactionDetail) +# print(inquiry.Address) +# print(inquiry.ShipDateTime) +# print(inquiry.CheckForMismatch) +# print(inquiry.RoutingCode) # Fires off the request, sets the 'response' attribute on the object. inquiry.send_request() # See the response printed out. -# print(inquiry.response) - -# This will convert the response to a python dict object. To -# make it easier to work with. -# from fedex.tools.conversion import basic_sobject_to_dict -# print(basic_sobject_to_dict(inquiry.response)) - -# This will dump the response data dict to json. -# from fedex.tools.conversion import sobject_to_json -# print(sobject_to_json(inquiry.response)) +print(inquiry.response) # Here is the overall end result of the query. print("HighestSeverity: {}".format(inquiry.response.HighestSeverity)) -print("ExpressFreightContractorDeliveryArea: {}".format(sobject_to_dict(inquiry.response.ExpressDescription))) -print("ExpressDescription: {}".format(sobject_to_dict(inquiry.response.ExpressFreightDescription))) +print("") + +print("State/Province: {}".format(inquiry.response.PostalDetail.StateOrProvinceCode)) +print("City First Initial: {}".format(inquiry.response.PostalDetail.CityFirstInitials)) +print("Clean Postal Code: {}".format(inquiry.response.PostalDetail.CleanedPostalCode)) + +for loc_description in inquiry.response.PostalDetail.LocationDescriptions: + print("Location ID: {}".format(loc_description.LocationId)) + print("Location No.: {}".format(loc_description.LocationNumber)) + print("Country Code: {}".format(loc_description.CountryCode)) + print("Postal Code: {}".format(loc_description.PostalCode)) + print("Service Area: {}".format(loc_description.ServiceArea)) + print("Airport ID: {}".format(loc_description.AirportId)) + print("FedEx Europe First Origin: {}".format(loc_description.FedExEuropeFirstOrigin)) diff --git a/examples/postal_inquiry_deprecated.py b/examples/postal_inquiry_deprecated.py new file mode 100755 index 0000000..e721a51 --- /dev/null +++ b/examples/postal_inquiry_deprecated.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +""" +PostalCodeInquiryRequest classes are used to validate and receive additional +information about postal codes. +""" +import logging +import sys +import warnings +from example_config import CONFIG_OBJ +from fedex.services.package_movement import PostalCodeInquiryRequest +from fedex.tools.conversion import sobject_to_dict + +# Un-comment to see the response from Fedex printed in stdout. +logging.basicConfig(stream=sys.stdout, level=logging.INFO) + +warnings.simplefilter('always', DeprecationWarning) # Show deprecation on this module in py2.7. + +# We're using the FedexConfig object from example_config.py in this dir. +inquiry = PostalCodeInquiryRequest(CONFIG_OBJ) +inquiry.PostalCode = '29631' +inquiry.CountryCode = 'US' + +# If you'd like to see some documentation on the ship service WSDL, un-comment +# this line. (Spammy). +# print(inquiry.client) + +# Un-comment this to see your complete, ready-to-send request as it stands +# before it is actually sent. This is useful for seeing what values you can +# change. +# print(inquiry.CarrierCode) +# print(inquiry.ClientDetail) +# print(inquiry.TransactionDetail) + +# Fires off the request, sets the 'response' attribute on the object. +inquiry.send_request() + +# See the response printed out. +# print(inquiry.response) + +# This will convert the response to a python dict object. To +# make it easier to work with. +# from fedex.tools.conversion import basic_sobject_to_dict +# print(basic_sobject_to_dict(inquiry.response)) + +# This will dump the response data dict to json. +# from fedex.tools.conversion import sobject_to_json +# print(sobject_to_json(inquiry.response)) + +# Here is the overall end result of the query. +print("HighestSeverity: {}".format(inquiry.response.HighestSeverity)) +print("ExpressFreightContractorDeliveryArea: {}".format(sobject_to_dict(inquiry.response.ExpressDescription))) +print("ExpressDescription: {}".format(sobject_to_dict(inquiry.response.ExpressFreightDescription))) diff --git a/examples/rate_request.py b/examples/rate_request.py index 608f1cd..bdc1975 100644 --- a/examples/rate_request.py +++ b/examples/rate_request.py @@ -123,11 +123,7 @@ rate_detail.ShipmentRateDetail.TotalNetFedExCharge.Currency, rate_detail.ShipmentRateDetail.TotalNetFedExCharge.Amount)) -# Not sure if 'NOTE' checking should be put in base class. -# For now can check notifications manually. -# if notification.Severity == 'NOTE': -# self.logger.warning(FedexFailure(notification.Code, -# notification.Message)) +# Check for warnings, this is also logged by the base class. if rate_request.response.HighestSeverity == 'NOTE': for notification in rate_request.response.Notifications: if notification.Severity == 'NOTE': diff --git a/examples/track_shipment.py b/examples/track_shipment.py index 00f84dd..c393050 100755 --- a/examples/track_shipment.py +++ b/examples/track_shipment.py @@ -70,7 +70,8 @@ print("Status Description: {}".format(match.StatusDetail.Description)) if hasattr(match, 'StatusDetail.AncillaryDetails'): print("Status AncillaryDetails Reason: {}".format(match.StatusDetail.AncillaryDetails[-1].Reason)) - print("Status AncillaryDetails Description: {}".format(match.StatusDetail.AncillaryDetails[-1].ReasonDescription)) + print("Status AncillaryDetails Description: {}" + "".format(match.StatusDetail.AncillaryDetails[-1].ReasonDescription)) if hasattr(match, 'ServiceCommitMessage'): print("Commit Message: {}".format(match.ServiceCommitMessage)) if hasattr(match, 'Notification'): diff --git a/fedex/base_service.py b/fedex/base_service.py index 4b2ab33..10564f5 100755 --- a/fedex/base_service.py +++ b/fedex/base_service.py @@ -17,7 +17,6 @@ class GeneralSudsPlugin(MessagePlugin): def __init__(self, **kwargs): - self.request_logger = logging.getLogger('fedex.request') self.response_logger = logging.getLogger('fedex.response') self.kwargs = kwargs diff --git a/fedex/services/address_validation_service.py b/fedex/services/address_validation_service.py index 014ecbd..2f68bdf 100644 --- a/fedex/services/address_validation_service.py +++ b/fedex/services/address_validation_service.py @@ -37,7 +37,7 @@ def __init__(self, config_obj, *args, **kwargs): """@ivar: Holds the AddressToValidate WSDL object.""" # Call the parent FedexBaseService class for basic setup work. super(FedexAddressValidationRequest, self).__init__( - self._config_obj, 'AddressValidationService_v4.wsdl', *args, **kwargs) + self._config_obj, 'AddressValidationService_v4.wsdl', *args, **kwargs) def _prepare_wsdl_objects(self): """ @@ -63,12 +63,12 @@ def _assemble_and_send_request(self): self.logger.debug(self.VersionId) # Fire off the query. return self.client.service.addressValidation( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - InEffectAsOfTimestamp=datetime.datetime.now(), - AddressesToValidate=self.AddressesToValidate) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + InEffectAsOfTimestamp=datetime.datetime.now(), + AddressesToValidate=self.AddressesToValidate) def add_address(self, address_item): """ diff --git a/fedex/services/availability_commitment_service.py b/fedex/services/availability_commitment_service.py index e2bc8b8..ab8a398 100644 --- a/fedex/services/availability_commitment_service.py +++ b/fedex/services/availability_commitment_service.py @@ -58,7 +58,7 @@ def __init__(self, config_obj, *args, **kwargs): # Exception: binding 'ns:ValidationAvailabilityAndCommitmentServiceSoapBinding', not-found super(FedexAvailabilityCommitmentRequest, self).__init__( - self._config_obj, 'AvailabilityAndCommitmentService_v4.wsdl', *args, **kwargs) + self._config_obj, 'AvailabilityAndCommitmentService_v4.wsdl', *args, **kwargs) def _prepare_wsdl_objects(self): """ @@ -88,13 +88,13 @@ def _assemble_and_send_request(self): self.logger.debug(self.VersionId) # Fire off the query. return self.client.service.serviceAvailability( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - Origin=self.Origin, - Destination=self.Destination, - ShipDate=self.ShipDate, - CarrierCode=self.CarrierCode, - Service=self.Service, - Packaging=self.Packaging) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + Origin=self.Origin, + Destination=self.Destination, + ShipDate=self.ShipDate, + CarrierCode=self.CarrierCode, + Service=self.Service, + Packaging=self.Packaging) diff --git a/fedex/services/country_service.py b/fedex/services/country_service.py index 8a92a0c..5f71cca 100644 --- a/fedex/services/country_service.py +++ b/fedex/services/country_service.py @@ -48,7 +48,7 @@ def __init__(self, config_obj, *args, **kwargs): """@ivar: Holds the CheckForMismatch boolean objects.""" super(FedexValidatePostalRequest, self).__init__( - self._config_obj, 'CountryService_v4.wsdl', *args, **kwargs) + self._config_obj, 'CountryService_v4.wsdl', *args, **kwargs) def _prepare_wsdl_objects(self): """ @@ -77,12 +77,12 @@ def _assemble_and_send_request(self): self.logger.debug(self.VersionId) # Fire off the query. return self.client.service.validatePostal( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - Address=self.Address, - ShipDateTime=self.ShipDateTime, - CarrierCode=self.CarrierCode, - CheckForMismatch=self.CheckForMismatch, - RoutingCode=self.RoutingCode) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + Address=self.Address, + ShipDateTime=self.ShipDateTime, + CarrierCode=self.CarrierCode, + CheckForMismatch=self.CheckForMismatch, + RoutingCode=self.RoutingCode) diff --git a/fedex/services/location_service.py b/fedex/services/location_service.py index 460dcb3..bdd08ff 100644 --- a/fedex/services/location_service.py +++ b/fedex/services/location_service.py @@ -53,7 +53,7 @@ def __init__(self, config_obj, *args, **kwargs): """@ivar: Holds the LocationSortDetail WSDL object.""" super(FedexSearchLocationRequest, self).__init__( - self._config_obj, 'LocationsService_v3.wsdl', *args, **kwargs) + self._config_obj, 'LocationsService_v3.wsdl', *args, **kwargs) def _prepare_wsdl_objects(self): """ @@ -85,13 +85,13 @@ def _assemble_and_send_request(self): self.logger.debug(self.VersionId) # Fire off the query. return self.client.service.searchLocations( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - LocationsSearchCriterion=self.LocationsSearchCriterion, - PhoneNumber=self.PhoneNumber, - MultipleMatchesAction=self.MultipleMatchesAction, - Constraints=self.Constraints, - Address=self.Address, - SortDetail=self.SortDetail) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + LocationsSearchCriterion=self.LocationsSearchCriterion, + PhoneNumber=self.PhoneNumber, + MultipleMatchesAction=self.MultipleMatchesAction, + Constraints=self.Constraints, + Address=self.Address, + SortDetail=self.SortDetail) diff --git a/fedex/services/package_movement.py b/fedex/services/package_movement.py index 6657f52..3ff4f55 100755 --- a/fedex/services/package_movement.py +++ b/fedex/services/package_movement.py @@ -51,11 +51,11 @@ def __init__(self, config_obj, postal_code=None, country_code=None, *args, **kwa self.CountryCode = country_code warnings.warn( - "DeprecationWarning: Package Movement Service has been deprecated; " - "please use Country Service for postal code validation requests or " - "Availability and Commitment Service for service availability " - "requests instead.", - DeprecationWarning + "Package Movement Service has been deprecated; " + "please use Country Service for postal code validation requests or " + "Availability and Commitment Service for service availability " + "requests instead.", + DeprecationWarning ) # Call the parent FedexBaseService class for basic setup work. diff --git a/fedex/services/rate_service.py b/fedex/services/rate_service.py index c1cf821..a4ca5f0 100644 --- a/fedex/services/rate_service.py +++ b/fedex/services/rate_service.py @@ -36,7 +36,7 @@ def __init__(self, config_obj, *args, **kwargs): """@ivar: Holds the RequestedShipment WSDL object including the shipper, recipient and shipt time.""" # Call the parent FedexBaseService class for basic setup work. super(FedexRateServiceRequest, self).__init__( - self._config_obj, 'RateService_v18.wsdl', *args, **kwargs) + self._config_obj, 'RateService_v18.wsdl', *args, **kwargs) self.ClientDetail.Region = config_obj.express_region_code """@ivar: Holds the express region code from the config object.""" @@ -100,12 +100,12 @@ def _assemble_and_send_request(self): # Fire off the query. return self.client.service.getRates( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - RequestedShipment=self.RequestedShipment, - ReturnTransitAndCommit=self.ReturnTransitAndCommit) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + RequestedShipment=self.RequestedShipment, + ReturnTransitAndCommit=self.ReturnTransitAndCommit) def add_package(self, package_item): """ diff --git a/fedex/services/ship_service.py b/fedex/services/ship_service.py index a650af6..43b9767 100644 --- a/fedex/services/ship_service.py +++ b/fedex/services/ship_service.py @@ -39,7 +39,7 @@ def __init__(self, config_obj, *args, **kwargs): """@ivar: Holds the RequestedShipment WSDL object.""" # Call the parent FedexBaseService class for basic setup work. super(FedexProcessShipmentRequest, self).__init__( - self._config_obj, 'ShipService_v17.wsdl', *args, **kwargs) + self._config_obj, 'ShipService_v17.wsdl', *args, **kwargs) def _prepare_wsdl_objects(self): """ @@ -124,11 +124,11 @@ def _assemble_and_send_validation_request(self): # Fire off the query. return self.client.service.validateShipment( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - RequestedShipment=self.RequestedShipment) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + RequestedShipment=self.RequestedShipment) def _assemble_and_send_request(self): """ @@ -140,11 +140,11 @@ def _assemble_and_send_request(self): # Fire off the query. return self.client.service.processShipment( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - RequestedShipment=self.RequestedShipment) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + RequestedShipment=self.RequestedShipment) def add_package(self, package_item): """ @@ -208,10 +208,10 @@ def _assemble_and_send_request(self): client = self.client # Fire off the query. return client.service.deleteShipment( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - ShipTimestamp=datetime.datetime.now(), - TrackingId=self.TrackingId, - DeletionControl=self.DeletionControlType) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + ShipTimestamp=datetime.datetime.now(), + TrackingId=self.TrackingId, + DeletionControl=self.DeletionControlType) diff --git a/fedex/services/track_service.py b/fedex/services/track_service.py index 8888a72..14c5e71 100644 --- a/fedex/services/track_service.py +++ b/fedex/services/track_service.py @@ -54,7 +54,7 @@ def __init__(self, config_obj, *args, **kwargs): # Call the parent FedexBaseService class for basic setup work. super(FedexTrackRequest, self).__init__( - self._config_obj, 'TrackService_v10.wsdl', *args, **kwargs) + self._config_obj, 'TrackService_v10.wsdl', *args, **kwargs) self.IncludeDetailedScans = False def _prepare_wsdl_objects(self): @@ -85,7 +85,7 @@ def _check_response_for_request_errors(self): if notification.Severity == "ERROR": if "Invalid tracking number" in notification.Message: raise FedexInvalidTrackingNumber( - notification.Code, notification.Message) + notification.Code, notification.Message) else: raise FedexError(notification.Code, notification.Message) @@ -100,9 +100,9 @@ def _assemble_and_send_request(self): client = self.client # Fire off the query. return client.service.track( - WebAuthenticationDetail=self.WebAuthenticationDetail, - ClientDetail=self.ClientDetail, - TransactionDetail=self.TransactionDetail, - Version=self.VersionId, - SelectionDetails=self.SelectionDetails, - ProcessingOptions=self.ProcessingOptions) + WebAuthenticationDetail=self.WebAuthenticationDetail, + ClientDetail=self.ClientDetail, + TransactionDetail=self.TransactionDetail, + Version=self.VersionId, + SelectionDetails=self.SelectionDetails, + ProcessingOptions=self.ProcessingOptions) diff --git a/fedex/tools/conversion.py b/fedex/tools/conversion.py index c1590cd..615e7bc 100644 --- a/fedex/tools/conversion.py +++ b/fedex/tools/conversion.py @@ -2,6 +2,7 @@ response object output. """ + # This is the suds way of doing this, but its slower. # For reference only. # from suds.sudsobject import asdict diff --git a/tests/test_package_movement_service.py b/tests/test_package_movement_service.py index e7c127d..e1c0165 100644 --- a/tests/test_package_movement_service.py +++ b/tests/test_package_movement_service.py @@ -5,6 +5,9 @@ import unittest import logging import sys +import warnings + +warnings.simplefilter('always', DeprecationWarning) # Show deprecation on this module in py2.7. sys.path.insert(0, '../') from fedex.services.package_movement import PostalCodeInquiryRequest From 35ee320932db5a0b7409f8f9c30f87c6bb6a2140 Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Mon, 18 Jan 2016 22:10:53 -0800 Subject: [PATCH 18/65] Updating python-fedex url --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f17fa62..5e5e499 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ long_description=LONG_DESCRIPTION, author='Gregory Taylor', author_email='gtaylor@gc-taylor.com', - url='https://github.com/gtaylor/python-fedex', + url='https://github.com/python-fedex-devs/python-fedex', download_url='http://pypi.python.org/pypi/fedex/', packages=['fedex', 'fedex.services', 'fedex.printers'], package_dir={'fedex': 'fedex'}, From c8325c5d792ae059830fbd41c26cc5143f83a387 Mon Sep 17 00:00:00 2001 From: Rad Date: Tue, 19 Jan 2016 01:24:23 -0500 Subject: [PATCH 19/65] added todos, updated authors --- README.rst | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 433bf82..d8307d4 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Python FedEx SOAP API Module ============================ -:Author: Greg Taylor +:Author: Python FedEx Developers :License: BSD :Status: Stable @@ -22,7 +22,7 @@ The easiest way is via pip or easy_install:: Quick Start ----------- -Edit the example_config.py file in examples with your fedex credentials +Edit the `example_config.py` file in `examples/` with your fedex credentials and run any of the provided examples. Documentation @@ -37,10 +37,10 @@ Support ------- Head over to https://github.com/gtaylor/python-fedex/issues -and submit an issue if you have any problems or questions. Due to this -package's quasi-maintained state, most problems are going to require -investigation or a submitted pull request by someone other than -Greg Taylor. +and submit an issue if you have any problems or questions. +Most problems are going to require investigation or a submitted +pull request by someone from the Python FedEx Developers organization. +To contribute a new feature or service, feel free to create a pull request. Fedex Support and Documentation ------------------------------- @@ -48,10 +48,17 @@ Fedex Support and Documentation Fedex Support Email: websupport@fedex.com Developer Portal: http://www.fedex.com/us/developer/ +Todos +----- + * Read the docs documentation + * Travis test integration + * Increase validation + * Remove deprecated services + Legal ----- -Copyright (C) 2015 Gregory Taylor +Copyright (C) 2016 Python FedEx Developers This software is licensed under the BSD License. From ac1e1d483038a442d40a2b257e7c79154b26b9e9 Mon Sep 17 00:00:00 2001 From: radzhome Date: Tue, 19 Jan 2016 01:47:12 -0500 Subject: [PATCH 20/65] update authors, keywoards --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 5e5e499..fb8e192 100755 --- a/setup.py +++ b/setup.py @@ -14,13 +14,13 @@ 'Topic :: Software Development :: Libraries :: Python Modules' ] -KEYWORDS = 'fedex soap suds wrapper' +KEYWORDS = 'fedex soap suds wrapper rate location ship service' setup(name='fedex', version=fedex.VERSION, description='Fedex Web Services API wrapper.', long_description=LONG_DESCRIPTION, - author='Gregory Taylor', + author='Python Fedex Developers', author_email='gtaylor@gc-taylor.com', url='https://github.com/python-fedex-devs/python-fedex', download_url='http://pypi.python.org/pypi/fedex/', From 5f98867a0197e36c6d0693e75047530857fa6f55 Mon Sep 17 00:00:00 2001 From: Rad Date: Tue, 19 Jan 2016 01:55:58 -0500 Subject: [PATCH 21/65] add travis build passing --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index d8307d4..0eed30f 100644 --- a/README.rst +++ b/README.rst @@ -5,6 +5,9 @@ Python FedEx SOAP API Module :License: BSD :Status: Stable +.. image:: https://travis-ci.org/python-fedex-devs/python-fedex.svg?branch=master + :target: https://travis-ci.org/python-fedex-devs/python-fedex + What is it? ----------- From ccaea5939779d72c5954b596da4a1b1c9f909f1e Mon Sep 17 00:00:00 2001 From: Rad Date: Tue, 19 Jan 2016 02:06:23 -0500 Subject: [PATCH 22/65] added pypi and requires badges --- README.rst | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 0eed30f..fd7c80b 100644 --- a/README.rst +++ b/README.rst @@ -1,13 +1,20 @@ Python FedEx SOAP API Module ============================ +.. image:: https://badge.fury.io/py/fedex.svg + :target: https://badge.fury.io/py/fedex + +.. image:: https://travis-ci.org/python-fedex-devs/python-fedex.svg?branch=master + :target: https://travis-ci.org/python-fedex-devs/python-fedex + +.. image:: https://requires.io/github/python-fedex-devs/python-fedex/requirements.svg?branch=master + :target: https://requires.io/github/python-fedex-devs/python-fedex/requirements/?branch=master + :alt: Requirements Status + :Author: Python FedEx Developers :License: BSD :Status: Stable -.. image:: https://travis-ci.org/python-fedex-devs/python-fedex.svg?branch=master - :target: https://travis-ci.org/python-fedex-devs/python-fedex - What is it? ----------- From 439fee2707d82daf2c09b7b6f439121c5cef9104 Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Tue, 19 Jan 2016 20:30:47 -0800 Subject: [PATCH 23/65] Re-adding attributions to the README --- README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index fd7c80b..56fa101 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,8 @@ Python FedEx SOAP API Module :target: https://requires.io/github/python-fedex-devs/python-fedex/requirements/?branch=master :alt: Requirements Status -:Author: Python FedEx Developers +:Author: Greg Taylor +:Maintainer: Python FedEx Developers :License: BSD :Status: Stable @@ -68,6 +69,7 @@ Todos Legal ----- +Copyright (C) 2008-2015 Greg Taylor Copyright (C) 2016 Python FedEx Developers This software is licensed under the BSD License. From 7a41c6aeab2807bef055851b04b27a1cecb4725c Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Tue, 19 Jan 2016 20:34:15 -0800 Subject: [PATCH 24/65] Re-adding myself as the original author in setup.py, setting Python Fedex Devs as the current maintainer. --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index fb8e192..d9f360d 100755 --- a/setup.py +++ b/setup.py @@ -20,8 +20,9 @@ version=fedex.VERSION, description='Fedex Web Services API wrapper.', long_description=LONG_DESCRIPTION, - author='Python Fedex Developers', + author='Greg Taylor', author_email='gtaylor@gc-taylor.com', + maintainer='Python Fedex Developers', url='https://github.com/python-fedex-devs/python-fedex', download_url='http://pypi.python.org/pypi/fedex/', packages=['fedex', 'fedex.services', 'fedex.printers'], From ebff31a7bd5452fef310e00cc03452087b4f5eac Mon Sep 17 00:00:00 2001 From: radzhome Date: Fri, 29 Jan 2016 14:45:06 -0500 Subject: [PATCH 25/65] updated documentation for v2.3 --- doc_source/README.rst | 12 + docs/{2.2.0 => 2.3.0}/api-objects.txt | 49 ++ docs/{2.2.0 => 2.3.0}/class-tree.html | 8 +- docs/{2.2.0 => 2.3.0}/crarr.png | Bin docs/{2.2.0 => 2.3.0}/epydoc.css | 0 docs/{2.2.0 => 2.3.0}/epydoc.js | 0 docs/{2.2.0 => 2.3.0}/fedex-module.html | 13 +- docs/{2.2.0 => 2.3.0}/fedex-pysrc.html | 4 +- .../fedex.base_service-module.html | 2 +- .../fedex.base_service-pysrc.html | 586 +++++++++--------- ...x.base_service.FedexBaseService-class.html | 185 ++++-- ...rvice.FedexBaseServiceException-class.html | 2 +- .../fedex.base_service.FedexError-class.html | 4 +- ...fedex.base_service.FedexFailure-class.html | 2 +- ....base_service.GeneralSudsPlugin-class.html | 8 +- ...e_service.SchemaValidationError-class.html | 2 +- .../{2.2.0 => 2.3.0}/fedex.config-module.html | 2 +- docs/{2.2.0 => 2.3.0}/fedex.config-pysrc.html | 2 +- .../fedex.config.FedexConfig-class.html | 2 +- .../fedex.printers-module.html | 2 +- .../fedex.printers-pysrc.html | 2 +- .../fedex.printers.unix-module.html | 2 +- .../fedex.printers.unix-pysrc.html | 2 +- ...inters.unix.DirectDevicePrinter-class.html | 2 +- .../fedex.services-module.html | 3 +- .../fedex.services-pysrc.html | 2 +- ...ces.address_validation_service-module.html | 2 +- ...ices.address_validation_service-pysrc.html | 19 +- ...e.FedexAddressValidationRequest-class.html | 8 +- ...vailability_commitment_service-module.html | 2 +- ...availability_commitment_service-pysrc.html | 27 +- ...exAvailabilityCommitmentRequest-class.html | 8 +- ...fedex.services.country_service-module.html | 2 +- .../fedex.services.country_service-pysrc.html | 25 +- ...vice.FedexValidatePostalRequest-class.html | 8 +- ...edex.services.location_service-module.html | 163 +++++ ...fedex.services.location_service-pysrc.html | 223 +++++++ ...vice.FedexSearchLocationRequest-class.html | 425 +++++++++++++ ...edex.services.package_movement-module.html | 2 +- ...fedex.services.package_movement-pysrc.html | 210 ++++--- ...nt.FedexInvalidPostalCodeFormat-class.html | 2 +- ...ovement.FedexPostalCodeNotFound-class.html | 2 +- ...vement.PostalCodeInquiryRequest-class.html | 8 +- .../fedex.services.rate_service-module.html | 2 +- .../fedex.services.rate_service-pysrc.html | 19 +- ...service.FedexRateServiceRequest-class.html | 8 +- .../fedex.services.ship_service-module.html | 2 +- .../fedex.services.ship_service-pysrc.html | 42 +- ...vice.FedexDeleteShipmentRequest-class.html | 8 +- ...ice.FedexProcessShipmentRequest-class.html | 8 +- .../fedex.services.track_service-module.html | 2 +- .../fedex.services.track_service-pysrc.html | 21 +- ...vice.FedexInvalidTrackingNumber-class.html | 2 +- ...track_service.FedexTrackRequest-class.html | 8 +- docs/2.3.0/fedex.tools-module.html | 154 +++++ docs/2.3.0/fedex.tools-pysrc.html | 112 ++++ docs/2.3.0/fedex.tools.conversion-module.html | 291 +++++++++ docs/2.3.0/fedex.tools.conversion-pysrc.html | 205 ++++++ docs/{2.2.0 => 2.3.0}/frames.html | 0 docs/{2.2.0 => 2.3.0}/help.html | 2 +- docs/{2.2.0 => 2.3.0}/identifier-index.html | 157 +++-- docs/{2.2.0 => 2.3.0}/index.html | 0 docs/{2.2.0 => 2.3.0}/module-tree.html | 9 +- docs/{2.2.0 => 2.3.0}/redirect.html | 2 +- docs/{2.2.0 => 2.3.0}/toc-everything.html | 16 +- docs/{2.2.0 => 2.3.0}/toc-fedex-module.html | 0 .../toc-fedex.base_service-module.html | 0 .../toc-fedex.config-module.html | 0 .../toc-fedex.printers-module.html | 0 .../toc-fedex.printers.unix-module.html | 0 .../toc-fedex.services-module.html | 0 ...ces.address_validation_service-module.html | 0 ...vailability_commitment_service-module.html | 0 ...fedex.services.country_service-module.html | 0 ...edex.services.location_service-module.html | 33 + ...edex.services.package_movement-module.html | 0 ...oc-fedex.services.rate_service-module.html | 0 ...oc-fedex.services.ship_service-module.html | 0 ...c-fedex.services.track_service-module.html | 0 docs/2.3.0/toc-fedex.tools-module.html | 31 + .../toc-fedex.tools.conversion-module.html | 35 ++ docs/{2.2.0 => 2.3.0}/toc.html | 7 +- 82 files changed, 2596 insertions(+), 614 deletions(-) create mode 100644 doc_source/README.rst rename docs/{2.2.0 => 2.3.0}/api-objects.txt (81%) rename docs/{2.2.0 => 2.3.0}/class-tree.html (95%) rename docs/{2.2.0 => 2.3.0}/crarr.png (100%) rename docs/{2.2.0 => 2.3.0}/epydoc.css (100%) rename docs/{2.2.0 => 2.3.0}/epydoc.js (100%) rename docs/{2.2.0 => 2.3.0}/fedex-module.html (94%) rename docs/{2.2.0 => 2.3.0}/fedex-pysrc.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service-pysrc.html (69%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service.FedexBaseService-class.html (83%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service.FedexBaseServiceException-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service.FedexError-class.html (93%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service.FedexFailure-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service.GeneralSudsPlugin-class.html (98%) rename docs/{2.2.0 => 2.3.0}/fedex.base_service.SchemaValidationError-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.config-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.config-pysrc.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.config.FedexConfig-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.printers-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.printers-pysrc.html (98%) rename docs/{2.2.0 => 2.3.0}/fedex.printers.unix-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.printers.unix-pysrc.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.printers.unix.DirectDevicePrinter-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services-module.html (96%) rename docs/{2.2.0 => 2.3.0}/fedex.services-pysrc.html (98%) rename docs/{2.2.0 => 2.3.0}/fedex.services.address_validation_service-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.address_validation_service-pysrc.html (89%) rename docs/{2.2.0 => 2.3.0}/fedex.services.address_validation_service.FedexAddressValidationRequest-class.html (96%) rename docs/{2.2.0 => 2.3.0}/fedex.services.availability_commitment_service-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.availability_commitment_service-pysrc.html (89%) rename docs/{2.2.0 => 2.3.0}/fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest-class.html (96%) rename docs/{2.2.0 => 2.3.0}/fedex.services.country_service-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.country_service-pysrc.html (88%) rename docs/{2.2.0 => 2.3.0}/fedex.services.country_service.FedexValidatePostalRequest-class.html (96%) create mode 100644 docs/2.3.0/fedex.services.location_service-module.html create mode 100644 docs/2.3.0/fedex.services.location_service-pysrc.html create mode 100644 docs/2.3.0/fedex.services.location_service.FedexSearchLocationRequest-class.html rename docs/{2.2.0 => 2.3.0}/fedex.services.package_movement-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.package_movement-pysrc.html (77%) rename docs/{2.2.0 => 2.3.0}/fedex.services.package_movement.FedexInvalidPostalCodeFormat-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.package_movement.FedexPostalCodeNotFound-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.package_movement.PostalCodeInquiryRequest-class.html (95%) rename docs/{2.2.0 => 2.3.0}/fedex.services.rate_service-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.rate_service-pysrc.html (92%) rename docs/{2.2.0 => 2.3.0}/fedex.services.rate_service.FedexRateServiceRequest-class.html (96%) rename docs/{2.2.0 => 2.3.0}/fedex.services.ship_service-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.ship_service-pysrc.html (91%) rename docs/{2.2.0 => 2.3.0}/fedex.services.ship_service.FedexDeleteShipmentRequest-class.html (96%) rename docs/{2.2.0 => 2.3.0}/fedex.services.ship_service.FedexProcessShipmentRequest-class.html (97%) rename docs/{2.2.0 => 2.3.0}/fedex.services.track_service-module.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.track_service-pysrc.html (90%) rename docs/{2.2.0 => 2.3.0}/fedex.services.track_service.FedexInvalidTrackingNumber-class.html (99%) rename docs/{2.2.0 => 2.3.0}/fedex.services.track_service.FedexTrackRequest-class.html (95%) create mode 100644 docs/2.3.0/fedex.tools-module.html create mode 100644 docs/2.3.0/fedex.tools-pysrc.html create mode 100644 docs/2.3.0/fedex.tools.conversion-module.html create mode 100644 docs/2.3.0/fedex.tools.conversion-pysrc.html rename docs/{2.2.0 => 2.3.0}/frames.html (100%) rename docs/{2.2.0 => 2.3.0}/help.html (99%) rename docs/{2.2.0 => 2.3.0}/identifier-index.html (89%) rename docs/{2.2.0 => 2.3.0}/index.html (100%) rename docs/{2.2.0 => 2.3.0}/module-tree.html (91%) rename docs/{2.2.0 => 2.3.0}/redirect.html (78%) rename docs/{2.2.0 => 2.3.0}/toc-everything.html (81%) rename docs/{2.2.0 => 2.3.0}/toc-fedex-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.base_service-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.config-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.printers-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.printers.unix-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.services-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.services.address_validation_service-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.services.availability_commitment_service-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.services.country_service-module.html (100%) create mode 100644 docs/2.3.0/toc-fedex.services.location_service-module.html rename docs/{2.2.0 => 2.3.0}/toc-fedex.services.package_movement-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.services.rate_service-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.services.ship_service-module.html (100%) rename docs/{2.2.0 => 2.3.0}/toc-fedex.services.track_service-module.html (100%) create mode 100644 docs/2.3.0/toc-fedex.tools-module.html create mode 100644 docs/2.3.0/toc-fedex.tools.conversion-module.html rename docs/{2.2.0 => 2.3.0}/toc.html (84%) diff --git a/doc_source/README.rst b/doc_source/README.rst new file mode 100644 index 0000000..29a7be7 --- /dev/null +++ b/doc_source/README.rst @@ -0,0 +1,12 @@ +python-fedex Examples +===================== + +This directory contains a number of examples of how to use python-fedex. For +these examples to work, you must open example_config.py and enter your +testing account credentials there. + +To run all tests from bash, type: + + for f in *.py; do python "$f"; done + # Or use the below to only see response errors: + for f in *.py; do python "$f"; done | grep -i error \ No newline at end of file diff --git a/docs/2.2.0/api-objects.txt b/docs/2.3.0/api-objects.txt similarity index 81% rename from docs/2.2.0/api-objects.txt rename to docs/2.3.0/api-objects.txt index 481e5c8..59c36d7 100644 --- a/docs/2.2.0/api-objects.txt +++ b/docs/2.3.0/api-objects.txt @@ -17,6 +17,8 @@ fedex.services.availability_commitment_service fedex.services.availability_commi fedex.services.availability_commitment_service.__package__ fedex.services.availability_commitment_service-module.html#__package__ fedex.services.country_service fedex.services.country_service-module.html fedex.services.country_service.__package__ fedex.services.country_service-module.html#__package__ +fedex.services.location_service fedex.services.location_service-module.html +fedex.services.location_service.__package__ fedex.services.location_service-module.html#__package__ fedex.services.package_movement fedex.services.package_movement-module.html fedex.services.package_movement.__package__ fedex.services.package_movement-module.html#__package__ fedex.services.rate_service fedex.services.rate_service-module.html @@ -25,10 +27,18 @@ fedex.services.ship_service fedex.services.ship_service-module.html fedex.services.ship_service.__package__ fedex.services.ship_service-module.html#__package__ fedex.services.track_service fedex.services.track_service-module.html fedex.services.track_service.__package__ fedex.services.track_service-module.html#__package__ +fedex.tools fedex.tools-module.html +fedex.tools.__package__ fedex.tools-module.html#__package__ +fedex.tools.conversion fedex.tools.conversion-module.html +fedex.tools.conversion.basic_sobject_to_dict fedex.tools.conversion-module.html#basic_sobject_to_dict +fedex.tools.conversion.sobject_to_json fedex.tools.conversion-module.html#sobject_to_json +fedex.tools.conversion.sobject_to_dict fedex.tools.conversion-module.html#sobject_to_dict +fedex.tools.conversion.__package__ fedex.tools.conversion-module.html#__package__ fedex.base_service.FedexBaseService fedex.base_service.FedexBaseService-class.html fedex.base_service.FedexBaseService.__check_response_for_fedex_error fedex.base_service.FedexBaseService-class.html#__check_response_for_fedex_error fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.base_service.FedexBaseService.__set_web_authentication_detail fedex.base_service.FedexBaseService-class.html#__set_web_authentication_detail fedex.base_service.FedexBaseService._prepare_wsdl_objects fedex.base_service.FedexBaseService-class.html#_prepare_wsdl_objects fedex.base_service.FedexBaseService.__init__ fedex.base_service.FedexBaseService-class.html#__init__ @@ -36,6 +46,7 @@ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseServi fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseService-class.html#ClientDetail fedex.base_service.FedexBaseService._assemble_and_send_request fedex.base_service.FedexBaseService-class.html#_assemble_and_send_request fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.base_service.FedexBaseService.create_wsdl_object_of_type fedex.base_service.FedexBaseService-class.html#create_wsdl_object_of_type fedex.base_service.FedexBaseService.response fedex.base_service.FedexBaseService-class.html#response @@ -84,6 +95,7 @@ fedex.printers.unix.DirectDevicePrinter.__init__ fedex.printers.unix.DirectDevic fedex.services.address_validation_service.FedexAddressValidationRequest fedex.services.address_validation_service.FedexAddressValidationRequest-class.html fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.address_validation_service.FedexAddressValidationRequest._prepare_wsdl_objects fedex.services.address_validation_service.FedexAddressValidationRequest-class.html#_prepare_wsdl_objects fedex.services.address_validation_service.FedexAddressValidationRequest.__init__ fedex.services.address_validation_service.FedexAddressValidationRequest-class.html#__init__ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj @@ -91,6 +103,7 @@ fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseSer fedex.services.address_validation_service.FedexAddressValidationRequest._assemble_and_send_request fedex.services.address_validation_service.FedexAddressValidationRequest-class.html#_assemble_and_send_request fedex.services.address_validation_service.FedexAddressValidationRequest.AddressesToValidate fedex.services.address_validation_service.FedexAddressValidationRequest-class.html#AddressesToValidate fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.services.address_validation_service.FedexAddressValidationRequest.add_address fedex.services.address_validation_service.FedexAddressValidationRequest-class.html#add_address fedex.base_service.FedexBaseService.create_wsdl_object_of_type fedex.base_service.FedexBaseService-class.html#create_wsdl_object_of_type @@ -103,11 +116,13 @@ fedex.services.availability_commitment_service.FedexAvailabilityCommitmentReques fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest.Destination fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest-class.html#Destination fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest.CarrierCode fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest-class.html#CarrierCode +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest._prepare_wsdl_objects fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest-class.html#_prepare_wsdl_objects fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest.__init__ fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest-class.html#__init__ fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseService-class.html#ClientDetail fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest._assemble_and_send_request fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest-class.html#_assemble_and_send_request fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest.ShipDate fedex.services.availability_commitment_service.FedexAvailabilityCommitmentRequest-class.html#ShipDate fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail @@ -121,6 +136,7 @@ fedex.services.country_service.FedexValidatePostalRequest fedex.services.country fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request fedex.services.country_service.FedexValidatePostalRequest.CarrierCode fedex.services.country_service.FedexValidatePostalRequest-class.html#CarrierCode +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.country_service.FedexValidatePostalRequest._prepare_wsdl_objects fedex.services.country_service.FedexValidatePostalRequest-class.html#_prepare_wsdl_objects fedex.services.country_service.FedexValidatePostalRequest.__init__ fedex.services.country_service.FedexValidatePostalRequest-class.html#__init__ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj @@ -130,12 +146,35 @@ fedex.services.country_service.FedexValidatePostalRequest.RoutingCode fedex.serv fedex.services.country_service.FedexValidatePostalRequest.ShipDateTime fedex.services.country_service.FedexValidatePostalRequest-class.html#ShipDateTime fedex.services.country_service.FedexValidatePostalRequest.Address fedex.services.country_service.FedexValidatePostalRequest-class.html#Address fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.base_service.FedexBaseService.create_wsdl_object_of_type fedex.base_service.FedexBaseService-class.html#create_wsdl_object_of_type fedex.base_service.FedexBaseService.response fedex.base_service.FedexBaseService-class.html#response fedex.services.country_service.FedexValidatePostalRequest.CheckForMismatch fedex.services.country_service.FedexValidatePostalRequest-class.html#CheckForMismatch fedex.base_service.FedexBaseService.VersionId fedex.base_service.FedexBaseService-class.html#VersionId fedex.base_service.FedexBaseService._check_response_for_request_errors fedex.base_service.FedexBaseService-class.html#_check_response_for_request_errors +fedex.services.location_service.FedexSearchLocationRequest fedex.services.location_service.FedexSearchLocationRequest-class.html +fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail +fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info +fedex.services.location_service.FedexSearchLocationRequest._prepare_wsdl_objects fedex.services.location_service.FedexSearchLocationRequest-class.html#_prepare_wsdl_objects +fedex.services.location_service.FedexSearchLocationRequest.__init__ fedex.services.location_service.FedexSearchLocationRequest-class.html#__init__ +fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj +fedex.services.location_service.FedexSearchLocationRequest.MultipleMatchesAction fedex.services.location_service.FedexSearchLocationRequest-class.html#MultipleMatchesAction +fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseService-class.html#ClientDetail +fedex.services.location_service.FedexSearchLocationRequest._assemble_and_send_request fedex.services.location_service.FedexSearchLocationRequest-class.html#_assemble_and_send_request +fedex.services.location_service.FedexSearchLocationRequest.Address fedex.services.location_service.FedexSearchLocationRequest-class.html#Address +fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings +fedex.services.location_service.FedexSearchLocationRequest.LocationsSearchCriterion fedex.services.location_service.FedexSearchLocationRequest-class.html#LocationsSearchCriterion +fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail +fedex.services.location_service.FedexSearchLocationRequest.PhoneNumber fedex.services.location_service.FedexSearchLocationRequest-class.html#PhoneNumber +fedex.base_service.FedexBaseService.create_wsdl_object_of_type fedex.base_service.FedexBaseService-class.html#create_wsdl_object_of_type +fedex.base_service.FedexBaseService.response fedex.base_service.FedexBaseService-class.html#response +fedex.services.location_service.FedexSearchLocationRequest.Constraints fedex.services.location_service.FedexSearchLocationRequest-class.html#Constraints +fedex.base_service.FedexBaseService.VersionId fedex.base_service.FedexBaseService-class.html#VersionId +fedex.services.location_service.FedexSearchLocationRequest.SortDetail fedex.services.location_service.FedexSearchLocationRequest-class.html#SortDetail +fedex.base_service.FedexBaseService._check_response_for_request_errors fedex.base_service.FedexBaseService-class.html#_check_response_for_request_errors fedex.services.package_movement.FedexInvalidPostalCodeFormat fedex.services.package_movement.FedexInvalidPostalCodeFormat-class.html fedex.base_service.FedexBaseServiceException.__str__ fedex.base_service.FedexBaseServiceException-class.html#__str__ fedex.base_service.FedexBaseServiceException.__unicode__ fedex.base_service.FedexBaseServiceException-class.html#__unicode__ @@ -147,12 +186,14 @@ fedex.base_service.FedexBaseServiceException.__init__ fedex.base_service.FedexBa fedex.services.package_movement.PostalCodeInquiryRequest fedex.services.package_movement.PostalCodeInquiryRequest-class.html fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.package_movement.PostalCodeInquiryRequest._prepare_wsdl_objects fedex.services.package_movement.PostalCodeInquiryRequest-class.html#_prepare_wsdl_objects fedex.services.package_movement.PostalCodeInquiryRequest.__init__ fedex.services.package_movement.PostalCodeInquiryRequest-class.html#__init__ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseService-class.html#ClientDetail fedex.services.package_movement.PostalCodeInquiryRequest._assemble_and_send_request fedex.services.package_movement.PostalCodeInquiryRequest-class.html#_assemble_and_send_request fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.base_service.FedexBaseService.create_wsdl_object_of_type fedex.base_service.FedexBaseService-class.html#create_wsdl_object_of_type fedex.base_service.FedexBaseService.response fedex.base_service.FedexBaseService-class.html#response @@ -161,12 +202,14 @@ fedex.services.package_movement.PostalCodeInquiryRequest._check_response_for_req fedex.services.rate_service.FedexRateServiceRequest fedex.services.rate_service.FedexRateServiceRequest-class.html fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.rate_service.FedexRateServiceRequest._prepare_wsdl_objects fedex.services.rate_service.FedexRateServiceRequest-class.html#_prepare_wsdl_objects fedex.services.rate_service.FedexRateServiceRequest.__init__ fedex.services.rate_service.FedexRateServiceRequest-class.html#__init__ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseService-class.html#ClientDetail fedex.services.rate_service.FedexRateServiceRequest._assemble_and_send_request fedex.services.rate_service.FedexRateServiceRequest-class.html#_assemble_and_send_request fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.services.rate_service.FedexRateServiceRequest.RequestedShipment fedex.services.rate_service.FedexRateServiceRequest-class.html#RequestedShipment fedex.base_service.FedexBaseService.create_wsdl_object_of_type fedex.base_service.FedexBaseService-class.html#create_wsdl_object_of_type @@ -177,12 +220,14 @@ fedex.base_service.FedexBaseService._check_response_for_request_errors fedex.bas fedex.services.ship_service.FedexDeleteShipmentRequest fedex.services.ship_service.FedexDeleteShipmentRequest-class.html fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.ship_service.FedexDeleteShipmentRequest._prepare_wsdl_objects fedex.services.ship_service.FedexDeleteShipmentRequest-class.html#_prepare_wsdl_objects fedex.services.ship_service.FedexDeleteShipmentRequest.__init__ fedex.services.ship_service.FedexDeleteShipmentRequest-class.html#__init__ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseService-class.html#ClientDetail fedex.services.ship_service.FedexDeleteShipmentRequest._assemble_and_send_request fedex.services.ship_service.FedexDeleteShipmentRequest-class.html#_assemble_and_send_request fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.services.ship_service.FedexDeleteShipmentRequest.DeletionControlType fedex.services.ship_service.FedexDeleteShipmentRequest-class.html#DeletionControlType fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.services.ship_service.FedexDeleteShipmentRequest.TrackingId fedex.services.ship_service.FedexDeleteShipmentRequest-class.html#TrackingId @@ -193,6 +238,7 @@ fedex.base_service.FedexBaseService._check_response_for_request_errors fedex.bas fedex.services.ship_service.FedexProcessShipmentRequest fedex.services.ship_service.FedexProcessShipmentRequest-class.html fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.ship_service.FedexProcessShipmentRequest._prepare_wsdl_objects fedex.services.ship_service.FedexProcessShipmentRequest-class.html#_prepare_wsdl_objects fedex.services.ship_service.FedexProcessShipmentRequest.__init__ fedex.services.ship_service.FedexProcessShipmentRequest-class.html#__init__ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj @@ -200,6 +246,7 @@ fedex.services.ship_service.FedexProcessShipmentRequest.send_validation_request fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseService-class.html#ClientDetail fedex.services.ship_service.FedexProcessShipmentRequest._assemble_and_send_request fedex.services.ship_service.FedexProcessShipmentRequest-class.html#_assemble_and_send_request fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.services.ship_service.FedexProcessShipmentRequest._assemble_and_send_validation_request fedex.services.ship_service.FedexProcessShipmentRequest-class.html#_assemble_and_send_validation_request fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.services.ship_service.FedexProcessShipmentRequest.RequestedShipment fedex.services.ship_service.FedexProcessShipmentRequest-class.html#RequestedShipment @@ -215,6 +262,7 @@ fedex.base_service.FedexBaseServiceException.__init__ fedex.base_service.FedexBa fedex.services.track_service.FedexTrackRequest fedex.services.track_service.FedexTrackRequest-class.html fedex.base_service.FedexBaseService.TransactionDetail fedex.base_service.FedexBaseService-class.html#TransactionDetail fedex.base_service.FedexBaseService.send_request fedex.base_service.FedexBaseService-class.html#send_request +fedex.base_service.FedexBaseService._version_info fedex.base_service.FedexBaseService-class.html#_version_info fedex.services.track_service.FedexTrackRequest._prepare_wsdl_objects fedex.services.track_service.FedexTrackRequest-class.html#_prepare_wsdl_objects fedex.services.track_service.FedexTrackRequest.__init__ fedex.services.track_service.FedexTrackRequest-class.html#__init__ fedex.base_service.FedexBaseService.config_obj fedex.base_service.FedexBaseService-class.html#config_obj @@ -222,6 +270,7 @@ fedex.base_service.FedexBaseService.ClientDetail fedex.base_service.FedexBaseSer fedex.services.track_service.FedexTrackRequest._assemble_and_send_request fedex.services.track_service.FedexTrackRequest-class.html#_assemble_and_send_request fedex.base_service.FedexBaseService.logger fedex.base_service.FedexBaseService-class.html#logger fedex.services.track_service.FedexTrackRequest.SelectionDetails fedex.services.track_service.FedexTrackRequest-class.html#SelectionDetails +fedex.base_service.FedexBaseService._check_response_for_request_warnings fedex.base_service.FedexBaseService-class.html#_check_response_for_request_warnings fedex.services.track_service.FedexTrackRequest.ProcessingOptions fedex.services.track_service.FedexTrackRequest-class.html#ProcessingOptions fedex.base_service.FedexBaseService.WebAuthenticationDetail fedex.base_service.FedexBaseService-class.html#WebAuthenticationDetail fedex.base_service.FedexBaseService.create_wsdl_object_of_type fedex.base_service.FedexBaseService-class.html#create_wsdl_object_of_type diff --git a/docs/2.2.0/class-tree.html b/docs/2.3.0/class-tree.html similarity index 95% rename from docs/2.2.0/class-tree.html rename to docs/2.3.0/class-tree.html index eb3afb7..1fc76eb 100644 --- a/docs/2.2.0/class-tree.html +++ b/docs/2.3.0/class-tree.html @@ -59,7 +59,7 @@

Class Hierarchy

Plugin base.
  • suds.plugin.MessagePlugin: - The base class for suds soap message plugins. + The base class for suds SOAP message plugins.
    • fedex.base_service.GeneralSudsPlugin
    • @@ -131,6 +131,10 @@

      Class Hierarchy

      This class allows you to get the shipping charges for a particular address. +
    • fedex.services.location_service.FedexSearchLocationRequest: + This class allows you to figure out a FedEx location closest to a + specified location criteria, based on location type. +
    • fedex.services.track_service.FedexTrackRequest: This class allows you to track shipments by providing a tracking number or other identifying features. @@ -177,7 +181,7 @@

      Class Hierarchy

      @@ -196,7 +203,7 @@

      Getting Support

        - VERSION = '2.2.0' + VERSION = '2.3.0' @@ -233,7 +240,7 @@

      Getting Support

      @@ -165,23 +171,24 @@

      Identifier Index

      (in fedex.services.availability_commitment_service) - + - + - +

      D

      +

      L

      + + + + + + + + + +

      M

      @@ -254,18 +273,25 @@

      Identifier Index

      - - + + - + + + + + + @@ -273,10 +299,11 @@

      Identifier Index

      + - @@ -311,106 +338,114 @@

      Identifier Index

      __check_response_for_fedex_error()
      (in FedexBaseService) -__package__
      -(in fedex.printers.unix) -_assemble_and_send_request()
      -(in PostalCodeInquiryRequest) - - -__init__()
      -(in FedexBaseService) -__package__
      -(in fedex.services) +__package__
      +(in fedex.services.address_validation_service) _assemble_and_send_request()
      (in FedexRateServiceRequest) -__init__()
      -(in FedexBaseServiceException) -__package__
      -(in fedex.services.address_validation_service) +__init__()
      +(in FedexBaseService) +__package__
      +(in fedex.services.availability_commitment_service) _assemble_and_send_request()
      (in FedexDeleteShipmentRequest) -__init__()
      -(in GeneralSudsPlugin) -__package__
      -(in fedex.services.availability_commitment_service) +__init__()
      +(in FedexBaseServiceException) +__package__
      +(in fedex.services.country_service) _assemble_and_send_request()
      (in FedexProcessShipmentRequest) -__init__()
      -(in SchemaValidationError) -__package__
      -(in fedex.services.country_service) +__init__()
      +(in GeneralSudsPlugin) +__package__
      +(in fedex.services.location_service) _assemble_and_send_request()
      (in FedexTrackRequest) -__init__()
      -(in FedexConfig) +__init__()
      +(in SchemaValidationError) __package__
      (in fedex.services.package_movement) _assemble_and_send_validation_request()
      (in FedexProcessShipmentRequest) -__init__()
      -(in DirectDevicePrinter) +__init__()
      +(in FedexConfig) __package__
      (in fedex.services.rate_service) _check_response_for_request_errors()
      (in FedexBaseService) -__init__()
      -(in FedexAddressValidationRequest) +__init__()
      +(in DirectDevicePrinter) __package__
      (in fedex.services.ship_service) _check_response_for_request_errors()
      (in PostalCodeInquiryRequest) -__init__()
      -(in FedexAvailabilityCommitmentRequest) +__init__()
      +(in FedexAddressValidationRequest) __package__
      (in fedex.services.track_service) _check_response_for_request_errors()
      (in FedexTrackRequest) +__init__()
      +(in FedexAvailabilityCommitmentRequest) +__package__
      +(in fedex.tools) +_check_response_for_request_warnings()
      +(in FedexBaseService) + + __init__()
      (in FedexValidatePostalRequest) -__set_client_detail()
      -(in FedexBaseService) +__package__
      +(in fedex.tools.conversion) _prepare_wsdl_objects()
      (in FedexBaseService) +__init__()
      +(in FedexSearchLocationRequest) +__set_client_detail()
      +(in FedexBaseService) +_prepare_wsdl_objects()
      +(in FedexAddressValidationRequest) + + __init__()
      (in PostalCodeInquiryRequest) __set_transaction_detail()
      (in FedexBaseService) -_prepare_wsdl_objects()
      -(in FedexAddressValidationRequest) +_prepare_wsdl_objects()
      +(in FedexAvailabilityCommitmentRequest) __init__()
      (in FedexRateServiceRequest) __set_version_id()
      (in FedexBaseService) -_prepare_wsdl_objects()
      -(in FedexAvailabilityCommitmentRequest) +_prepare_wsdl_objects()
      +(in FedexValidatePostalRequest) __init__()
      (in FedexDeleteShipmentRequest) __set_web_authentication_detail()
      (in FedexBaseService) -_prepare_wsdl_objects()
      -(in FedexValidatePostalRequest) +_prepare_wsdl_objects()
      +(in FedexSearchLocationRequest) __init__()
      @@ -460,6 +495,20 @@

      Identifier Index

      _print_base64()
      (in DirectDevicePrinter) + +__package__
      +(in fedex.printers.unix) +_assemble_and_send_request()
      +(in FedexSearchLocationRequest) +  + + +__package__
      +(in fedex.services) +_assemble_and_send_request()
      +(in PostalCodeInquiryRequest) +  + @@ -489,7 +538,7 @@

      Identifier Index

      \s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
      ", "
      " ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "
      ", "
      " ], + tr: [ 2, "", "
      " ], + col: [ 2, "", "
      " ], + td: [ 3, "", "
      " ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
      ", "
      " ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
      " && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "