Skip to content

Commit 75bcf6b

Browse files
committed
Merged pull request #4 from cuker/master.
address validation
2 parents 95ac0f6 + e1214a9 commit 75bcf6b

File tree

2 files changed

+57
-27
lines changed

2 files changed

+57
-27
lines changed

examples/address_validation.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,46 @@ class can handle up to 100 addresses for validation.
1212

1313
# This is the object that will be handling our tracking request.
1414
# We're using the FedexConfig object from example_config.py in this dir.
15-
address = FedexAddressValidationRequest(CONFIG_OBJ)
15+
connection = FedexAddressValidationRequest(CONFIG_OBJ)
1616

17-
address1 = address.create_wsdl_object_of_type('AddressToValidate')
17+
# The AddressValidationOptions are created with default values of None, which
18+
# will cause WSDL validation errors. To make things work, each option needs to
19+
# be explicitly set or deleted.
20+
21+
## Set the flags we want to True (or a value).
22+
connection.AddressValidationOptions.CheckResidentialStatus = True
23+
connection.AddressValidationOptions.VerifyAddresses = True
24+
connection.AddressValidationOptions.RecognizeAlternateCityNames = True
25+
connection.AddressValidationOptions.MaximumNumberOfMatches = 3
26+
27+
## Delete the flags we don't want.
28+
del connection.AddressValidationOptions.ConvertToUpperCase
29+
del connection.AddressValidationOptions.ReturnParsedElements
30+
31+
## *Accuracy fields can be TIGHT, EXACT, MEDIUM, or LOOSE. Or deleted.
32+
connection.AddressValidationOptions.StreetAccuracy = 'LOOSE'
33+
del connection.AddressValidationOptions.DirectionalAccuracy
34+
del connection.AddressValidationOptions.CompanyNameAccuracy
35+
36+
## Create some addresses to validate
37+
address1 = connection.create_wsdl_object_of_type('AddressToValidate')
1838
address1.CompanyName = 'International Paper'
1939
address1.Address.StreetLines = ['155 Old Greenville Hwy', 'Suite 103']
2040
address1.Address.City = 'Clemson'
2141
address1.Address.StateOrProvinceCode = 'SC'
2242
address1.Address.PostalCode = 29631
2343
address1.Address.CountryCode = 'US'
2444
address1.Address.Residential = False
45+
connection.add_address(address1)
46+
47+
address2 = connection.create_wsdl_object_of_type('AddressToValidate')
48+
address2.Address.StreetLines = ['320 S Cedros', '#200']
49+
address2.Address.City = 'Solana Beach'
50+
address2.Address.StateOrProvinceCode = 'CA'
51+
address2.Address.PostalCode = 92075
52+
address2.Address.CountryCode = 'US'
53+
connection.add_address(address2)
2554

26-
address.add_address(address1)
27-
address.send_request()
28-
print address.response
55+
## Send the request and print the response
56+
connection.send_request()
57+
print connection.response

fedex/base_service.py

100644100755
Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
class FedexBaseServiceException(Exception):
1515
"""
16-
Exception: Serves as the base exception that other service-related
16+
Exception: Serves as the base exception that other service-related
1717
exception objects are sub-classed from.
1818
"""
1919
def __init__(self, error_code, value):
@@ -23,10 +23,10 @@ def __unicode__(self):
2323
return "%s (Error code: %s)" % (repr(self.value), self.error_code)
2424
def __str__(self):
2525
return self.__unicode__()
26-
26+
2727
class FedexFailure(FedexBaseServiceException):
2828
"""
29-
Exception: The request could not be handled at this time. This is generally
29+
Exception: The request could not be handled at this time. This is generally
3030
a server problem.
3131
"""
3232
pass
@@ -51,7 +51,7 @@ class FedexBaseService(object):
5151
of the common SOAP objects created via suds and populates them with
5252
values from a L{FedexConfig} object, along with keyword arguments
5353
via L{__init__}.
54-
54+
5555
@note: This object should never be used directly, use one of the included
5656
sub-classes.
5757
"""
@@ -60,7 +60,7 @@ def __init__(self, config_obj, wsdl_name, *args, **kwargs):
6060
This constructor should only be called by children of the class. As is
6161
such, only the optional keyword arguments caught by C{**kwargs} will
6262
be documented.
63-
63+
6464
@type customer_transaction_id: L{str}
6565
@keyword customer_transaction_id: A user-specified identifier to
6666
differentiate this transaction from others. This value will be
@@ -70,21 +70,21 @@ def __init__(self, config_obj, wsdl_name, *args, **kwargs):
7070
"""@ivar: Python logger instance with name 'fedex'."""
7171
self.config_obj = config_obj
7272
"""@ivar: The FedexConfig object to pull auth info from."""
73-
73+
7474
# If the config object is set to use the test server, point
7575
# suds at the test server WSDL directory.
7676
if config_obj.use_test_server:
7777
self.logger.info("Using test server.")
78-
self.wsdl_path = os.path.join(config_obj.wsdl_path,
78+
self.wsdl_path = os.path.join(config_obj.wsdl_path,
7979
'test_server_wsdl', wsdl_name)
8080
else:
8181
self.logger.info("Using production server.")
8282
self.wsdl_path = os.path.join(config_obj.wsdl_path, wsdl_name)
8383

8484
self.client = Client('file://%s' % self.wsdl_path)
85-
85+
8686
#print self.client
87-
87+
8888
self.VersionId = None
8989
"""@ivar: Holds details on the version numbers of the WSDL."""
9090
self.WebAuthenticationDetail = None
@@ -98,13 +98,13 @@ def __init__(self, config_obj, wsdl_name, *args, **kwargs):
9898
you can pull."""
9999
self.TransactionDetail = None
100100
"""@ivar: Holds customer-specified transaction IDs."""
101-
101+
102102
self.__set_web_authentication_detail()
103103
self.__set_client_detail()
104104
self.__set_version_id()
105105
self.__set_transaction_detail(*args, **kwargs)
106106
self._prepare_wsdl_objects()
107-
107+
108108
def __set_web_authentication_detail(self):
109109
"""
110110
Sets up the WebAuthenticationDetail node. This is required for all
@@ -114,12 +114,12 @@ def __set_web_authentication_detail(self):
114114
WebAuthenticationCredential = self.client.factory.create('WebAuthenticationCredential')
115115
WebAuthenticationCredential.Key = self.config_obj.key
116116
WebAuthenticationCredential.Password = self.config_obj.password
117-
117+
118118
# Encapsulates the auth credentials.
119119
WebAuthenticationDetail = self.client.factory.create('WebAuthenticationDetail')
120120
WebAuthenticationDetail.UserCredential = WebAuthenticationCredential
121121
self.WebAuthenticationDetail = WebAuthenticationDetail
122-
122+
123123
def __set_client_detail(self):
124124
"""
125125
Sets up the ClientDetail node, which is required for all shipping
@@ -129,9 +129,10 @@ def __set_client_detail(self):
129129
ClientDetail.AccountNumber = self.config_obj.account_number
130130
ClientDetail.MeterNumber = self.config_obj.meter_number
131131
ClientDetail.IntegratorId = self.config_obj.integrator_id
132-
ClientDetail.Region = self.config_obj.express_region_code
132+
if hasattr(ClientDetail, 'Region'):
133+
ClientDetail.Region = self.config_obj.express_region_code
133134
self.ClientDetail = ClientDetail
134-
135+
135136
def __set_transaction_detail(self, *args, **kwargs):
136137
"""
137138
Checks kwargs for 'customer_transaction_id' and sets it if present.
@@ -142,7 +143,7 @@ def __set_transaction_detail(self, *args, **kwargs):
142143
TransactionDetail.CustomerTransactionId = customer_transaction_id
143144
self.logger.debug(TransactionDetail)
144145
self.TransactionDetail = TransactionDetail
145-
146+
146147
def __set_version_id(self):
147148
"""
148149
Pulles the versioning info for the request from the child request.
@@ -154,15 +155,15 @@ def __set_version_id(self):
154155
VersionId.Minor = self._version_info['minor']
155156
self.logger.debug(VersionId)
156157
self.VersionId = VersionId
157-
158+
158159
def __prepare_wsdl_objects(self):
159160
"""
160161
This method should be over-ridden on each sub-class. It instantiates
161162
any of the required WSDL objects so the user can just print their
162163
__str__() methods and see what they need to fill in.
163164
"""
164165
pass
165-
166+
166167
def __check_response_for_fedex_error(self):
167168
"""
168169
This checks the response for general Fedex errors that aren't related
@@ -173,7 +174,7 @@ def __check_response_for_fedex_error(self):
173174
if notification.Severity == "FAILURE":
174175
raise FedexFailure(notification.Code,
175176
notification.Message)
176-
177+
177178
def _check_response_for_request_errors(self):
178179
"""
179180
Override this in each service module to check for errors that are
@@ -185,7 +186,7 @@ def _check_response_for_request_errors(self):
185186
if notification.Severity == "ERROR":
186187
raise FedexError(notification.Code,
187188
notification.Message)
188-
189+
189190
def create_wsdl_object_of_type(self, type_name):
190191
"""
191192
Creates and returns a WSDL object of the specified type.
@@ -223,7 +224,7 @@ def send_request(self, send_function=None):
223224
# Check the response for errors specific to the particular request.
224225
# This is handled by an overridden method on the child object.
225226
self._check_response_for_request_errors()
226-
227+
227228
# Debug output.
228229
self.logger.debug("== FEDEX QUERY RESULT ==")
229-
self.logger.debug(self.response)
230+
self.logger.debug(self.response)

0 commit comments

Comments
 (0)