Skip to content

Instantly share code, notes, and snippets.

@seanmckaybeck
Created July 18, 2017 10:44
Show Gist options
  • Save seanmckaybeck/25cba1a8e959e5be3d8a9d0b8c7b4250 to your computer and use it in GitHub Desktop.
Save seanmckaybeck/25cba1a8e959e5be3d8a9d0b8c7b4250 to your computer and use it in GitHub Desktop.
"""
PoC for address verification via USPS API
Docs: https://www.usps.com/business/web-tools-apis/address-information-api.htm#_Toc487629493
"""
import argparse
from bs4 import BeautifulSoup
import requests
OUTER_TEMPLATE = '''<?xml version="1.0" encoding="UTF-8" ?>
<AddressValidateRequest USERID="{}">
<Revision>1</Revision>
{}
</AddressValidateRequest>'''
# note that addr1 and 2 are swapped in the USPS API from the standard definition, because why not?
ADDRESS_TEMPLATE = '''<Address ID="{}">
<Address1>{}</Address1>
<Address2>{}</Address2>
<City>{}</City>
<State>{}</State>
<Zip5>{}</Zip5>
<Zip4></Zip4>
</Address>'''
URL = "http://production.shippingapis.com/ShippingAPI.dll?API=Verify&XML={}"
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--user-id", required=True, help="Your USPS user ID is required")
return parser.parse_args()
def main():
args = get_args()
example = {"addr2": "", "addr1": "6406 Ivy Lane", "city": "Greenbelt", "state": "MD", "zip": ""}
addr = ADDRESS_TEMPLATE.format(0, example["addr2"], example["addr1"], example["city"], example["state"], example["zip"])
xml = OUTER_TEMPLATE.format(args.user_id, addr)
r = requests.get(URL.format(xml))
soup = BeautifulSoup(r.content, "xml")
line1 = soup.find("Address2").text
city = soup.find("City").text
state = soup.find("State").text
zip5 = soup.find("Zip5").text
zip4 = soup.find("Zip4").text
formatted_addr = f"{line1}\n{city}, {state} {zip5}-{zip4}"
print(formatted_addr)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment