2
See http://www.usps.com/webtools/htm/Address-Information.htm for complete documentation of the API
7
from xml.etree import ElementTree as ET
9
from elementtree import ElementTree as ET
11
def utf8urlencode(data):
13
for key, value in data.iteritems():
14
ret[key] = value.encode('utf8')
15
return urllib.urlencode(ret)
17
def dicttoxml(dictionary, parent, tagname, attributes=None):
18
element = ET.SubElement(parent, tagname)
19
if attributes: #USPS likes things in a certain order!
20
for key in attributes:
21
ET.SubElement(element, key).text = dictionary.get(key, '')
23
for key, value in dictionary.iteritems():
24
ET.SubElement(element, key).text = value
27
def xmltodict(element):
29
for item in element.getchildren():
30
ret[item.tag] = item.text
33
class USPSXMLError(Exception):
34
def __init__(self, element):
35
self.info = xmltodict(element)
36
super(USPSXMLError, self).__init__(self.info['Description'])
38
class USPSAddressService(object):
44
def __init__(self, url):
47
def submit_xml(self, xml):
48
data = {'XML':ET.tostring(xml),
50
response = urllib2.urlopen(self.url, utf8urlencode(data))
51
root = ET.parse(response).getroot()
52
if root.tag == 'Error':
53
raise USPSXMLError(root)
54
error = root.find('.//Error')
56
raise USPSXMLError(error)
59
def parse_xml(self, xml):
61
for item in xml.getchildren():#xml.findall(self.SERVICE_NAME+'Response'):
62
items.append(xmltodict(item))
65
def make_xml(self, userid, addresses):
66
root = ET.Element(self.SERVICE_NAME+'Request')
67
root.attrib['USERID'] = userid
69
for address_dict in addresses:
70
address_xml = dicttoxml(address_dict, root, self.CHILD_XML_NAME, self.PARAMETERS)
71
address_xml.attrib['ID'] = str(index)
75
def execute(self, userid, addresses):
76
xml = self.make_xml(userid, addresses)
77
return self.parse_xml(self.submit_xml(xml))
79
class AddressValidate(USPSAddressService):
80
SERVICE_NAME = 'AddressValidate'
81
CHILD_XML_NAME = 'Address'
83
PARAMETERS = ['FirmName',
91
class ZipCodeLookup(USPSAddressService):
92
SERVICE_NAME = 'ZipCodeLookup'
93
CHILD_XML_NAME = 'Address'
95
PARAMETERS = ['FirmName',
101
class CityStateLookup(USPSAddressService):
102
SERVICE_NAME = 'CityStateLookup'
103
CHILD_XML_NAME = 'ZipCode'
104
API = 'CityStateLookup'
105
PARAMETERS = ['Zip5',]