def run(): auth_id = os.environ[ 'SMARTY_AUTH_ID'] # We recommend storing your keys in environment variables auth_token = os.environ['SMARTY_AUTH_TOKEN'] credentials = StaticCredentials(auth_id, auth_token) client = ClientBuilder(credentials).build_us_zipcode_api_client() batch = Batch() batch.add(Lookup()) batch[ 0].zipcode = "12345" # A Lookup may have a ZIP Code, city and state, or city, state, and ZIP Code batch.add(Lookup()) batch[1].city = "Phoenix" batch[1].state = "Arizona" batch.add(Lookup("cupertino", "CA", "95014")) # You can also set these with arguments assert len(batch) == 3 try: client.send_batch(batch) except exceptions.SmartyException as err: print(err) return for i, lookup in enumerate(batch): result = lookup.result print("Lookup {}:\n".format(i)) if result.status is not None: print("Status: " + result.status) print("Reason: " + result.reason) continue cities = result.cities print("{} City and State match(es):".format(len(cities))) for city in cities: print("City: " + city.city) print("State: " + city.state) print("Mailable City: {}".format(city.mailable_city)) print("") zipcodes = result.zipcodes print("{} ZIP Code match(es):".format(len(zipcodes))) for zipcode in zipcodes: print("ZIP Code: " + zipcode.zipcode) print("County: " + zipcode.county_name) print("Latitude: {}".format(zipcode.latitude)) print("Longitude: {}".format(zipcode.longitude)) print("") print("***********************************")
def run(): auth_id = os.environ[ 'SMARTY_AUTH_ID'] # We recommend storing your keys in environment variables auth_token = os.environ['SMARTY_AUTH_TOKEN'] credentials = StaticCredentials(auth_id, auth_token) client = ClientBuilder(credentials).build_us_street_api_client() batch = Batch() batch.add(Lookup()) batch[0].street = "1600 amphitheatre parkway" batch[0].city = "Mountain view" batch[0].state = "california" batch.add(Lookup( "1 Rosedale, Baltimore, Maryland")) # Freeform addresses work too. batch[ 1].candidates = 10 # Allows up to ten possible matches to be returned (default is 1). batch.add(Lookup("123 Bogus Street, Pretend Lake, Oklahoma")) batch.add(Lookup()) batch[3].street = "1 Infinite Loop" batch[ 3].zipcode = "95014" # You can just input the street and ZIP if you want. assert len(batch) == 4 try: client.send_batch(batch) except exceptions.SmartyException as err: print(err) return for i, lookup in enumerate(batch): candidates = lookup.result if len(candidates) == 0: print("Address {} is invalid.\n".format(i)) continue print( "Address {} is valid. (There is at least one candidate)".format(i)) for candidate in candidates: components = candidate.components metadata = candidate.metadata print("\nCandidate {} : ".format(candidate.candidate_index)) print("Delivery line 1: {}".format(candidate.delivery_line_1)) print("Last line: {}".format(candidate.last_line)) print("ZIP Code: {}-{}".format(components.zipcode, components.plus4_code)) print("County: {}".format(metadata.county_name)) print("Latitude: {}".format(metadata.latitude)) print("Longitude: {}".format(metadata.longitude)) print("")
def run(): auth_id = "Your SmartyStreets Auth ID here" auth_token = "Your SmartyStreets Auth Token here" # We recommend storing your secret keys in environment variables instead---it's safer! # auth_id = os.environ['SMARTY_AUTH_ID'] # auth_token = os.environ['SMARTY_AUTH_TOKEN'] credentials = StaticCredentials(auth_id, auth_token) client = ClientBuilder(credentials).build_us_zipcode_api_client() batch = Batch() # Documentation for input fields can be found at: # https://smartystreets.com/docs/us-zipcode-api#input-fields batch.add(ZIPCodeLookup()) batch[0].input_id = "011889998819991197253" # Optional ID from your system batch[ 0].zipcode = "12345" # A Lookup may have a ZIP Code, city and state, or city, state, and ZIP Code batch.add(ZIPCodeLookup()) batch[1].city = "Phoenix" batch[1].state = "Arizona" batch.add(ZIPCodeLookup("cupertino", "CA", "95014")) # You can also set these with arguments assert len(batch) == 3 try: client.send_batch(batch) except exceptions.SmartyException as err: print(err) return for i, lookup in enumerate(batch): result = lookup.result print("Lookup {}:\n".format(i)) if result.status is not None: print("Status: " + result.status) print("Reason: " + result.reason) continue cities = result.cities print("{} City and State match(es):".format(len(cities))) for city in cities: print("City: " + city.city) print("State: " + city.state) print("Mailable City: {}".format(city.mailable_city)) print("") zipcodes = result.zipcodes print("{} ZIP Code match(es):".format(len(zipcodes))) for zipcode in zipcodes: print("ZIP Code: " + zipcode.zipcode) print("County: " + zipcode.county_name) print("Latitude: {}".format(zipcode.latitude)) print("Longitude: {}".format(zipcode.longitude)) print("") print("***********************************")
class SmartyAddressService(AddressService): """ Class represents Smarty Streets implementation of AddressService class. It provides address validatation and forward geocoding in one request. """ MAX_ADDRESSES_PER_REQUEST = 100 #100 is limit set by Smarty API def __init__(self): self.client = None self.num_addresses_processed = 0 self.__total_addresses_in_request_list = 0 self.__is_address_list_processed = False def load_config(self, config_file): """Resonsible for loading configs and setting up client""" config = configparser.ConfigParser() config.read(config_file) auth_id = config.get('SMARTY STREETS', 'auth_id') auth_token = config.get('SMARTY STREETS', 'auth_token') api_credentials = StaticCredentials(auth_id, auth_token) self.client = ClientBuilder( api_credentials).build_us_street_api_client() def send_request(self, params, address_data): """Responsible for sending request to service""" try: # Stream considered a batch of one self.client.send_batch(address_data) return address_data except exceptions.SmartyException as err: print(err) return def validate(self, params, address_input_data): """ Reponsible for validating input addresses in stream or batch form. returns a list containing a single Address object for stream input and multiple for batch input. """ processed_address_list = [] # check avoids redundancy for combined 'forward geocode and validate' # option as API does both by default if self.__is_address_list_processed: processed_address_list = address_input_data else: request_list = self.__prepare_smarty_request_list( address_input_data) processed_address_list = self.__process_smarty_request_list( request_list, address_input_data) self.__is_address_list_processed = True print(f'< {self.num_addresses_processed} addresses processed >') return processed_address_list def forward_geocode(self, params, address_input_data): """ Reponsible for forward geocoding input addresses in stream or batch form. returns a list containing a single Address object for stream input and multiple for batch input. """ processed_address_list = [] # check avoids redundancy for combined 'forward geocode and validate' # option as API does both by default if self.__is_address_list_processed: processed_address_list = address_input_data else: request_list = self.__prepare_smarty_request_list( address_input_data) processed_address_list = self.__process_smarty_request_list( request_list, address_input_data) self.__is_address_list_processed = True print(f'< {self.num_addresses_processed} addresses processed >') return processed_address_list ############ Smarty Specific Processing Helpers ############ def __prepare_smarty_request_list(self, address_list): """ Returns a list of requests each containing SmartyAddressService.MAX_ADDRESSES_PER_REQUEST address input strings. Input Address strings are converted smarty street Lookup objects. The request list is a list of batch partitions, smarty street Batch objects, which serves as the overall address batch. """ single_request_batch_partition = Batch() addresses_per_request = 0 request_list = [] for address in address_list: if addresses_per_request == SmartyAddressService.MAX_ADDRESSES_PER_REQUEST: request_list.append(single_request_batch_partition) single_request_batch_partition = Batch() addresses_per_request = 0 single_request_batch_partition.add(Lookup(address.input_string)) self.__total_addresses_in_request_list += 1 addresses_per_request += 1 if addresses_per_request > 0: request_list.append(single_request_batch_partition) return request_list # TODO: python boolean or string for is_valid parameter? def __process_smarty_request_list(self, request_list, address_input_data): """ Process request list through smarty streets API and assign response to corresponding address objects. Each individual request contains SmartyAddressService.MAX_ADDRESSES_PER_REQUEST address Lookups, which are assigned candidate addresses by their api. This function chooses the top candidate is chosen and assigns desired fields to our address objects. If no candidates are found, the address is invalid. """ assert ( len(address_input_data) == self.__total_addresses_in_request_list) processed_address_list = [] address_iterator = iter(address_input_data) for unprocessed_request in request_list: params = {} processed_request = self.send_request(params, unprocessed_request) for lookup in processed_request: candidates = lookup.result address = next(address_iterator) if len(candidates) == 0: address.is_valid = False # TODO: add invalid addresses to list here else: address.longitude = candidates[0].metadata.longitude address.latitude = candidates[0].metadata.latitude address.line_1 = candidates[0].delivery_line_1 address.line_2 = candidates[0].last_line address.is_valid = True self.num_addresses_processed += 1 processed_address_list.append(address) return processed_address_list
def run(): auth_id = "Your SmartyStreets Auth ID here" auth_token = "Your SmartyStreets Auth Token here" # We recommend storing your secret keys in environment variables instead---it's safer! # auth_id = os.environ['SMARTY_AUTH_ID'] # auth_token = os.environ['SMARTY_AUTH_TOKEN'] credentials = StaticCredentials(auth_id, auth_token) client = ClientBuilder(credentials).build_us_street_api_client() batch = Batch() # Documentation for input fields can be found at: # https://smartystreets.com/docs/us-street-api#input-fields batch.add(StreetLookup()) batch[0].input_id = "24601" # Optional ID from your system batch[0].addressee = "John Doe" batch[0].street = "1600 amphitheatre parkway" batch[0].street2 = "closet under the stairs" batch[0].secondary = "APT 2" batch[0].urbanization = "" # Only applies to Puerto Rico addresses batch[0].lastline = "Mountain view, california" batch[0].candidates = 5 batch[0].match = "invalid" # "invalid" is the most permissive match, # this will always return at least one result even if the address is invalid. # Refer to the documentation for additional Match Strategy options. batch.add(StreetLookup( "1 Rosedale, Baltimore, Maryland")) # Freeform addresses work too. batch[ 1].candidates = 10 # Allows up to ten possible matches to be returned (default is 1). batch.add(StreetLookup("123 Bogus Street, Pretend Lake, Oklahoma")) batch.add(StreetLookup()) batch[3].input_id = "8675309" batch[3].street = "1 Infinite Loop" batch[ 3].zipcode = "95014" # You can just input the street and ZIP if you want. batch[3].candidates = 1 assert len(batch) == 4 try: client.send_batch(batch) except exceptions.SmartyException as err: print(err) return for i, lookup in enumerate(batch): candidates = lookup.result if len(candidates) == 0: print("Address {} is invalid.\n".format(i)) continue print( "Address {} is valid. (There is at least one candidate)".format(i)) for candidate in candidates: components = candidate.components metadata = candidate.metadata print("\nCandidate {} : ".format(candidate.candidate_index)) print("Delivery line 1: {}".format(candidate.delivery_line_1)) print("Last line: {}".format(candidate.last_line)) print("ZIP Code: {}-{}".format(components.zipcode, components.plus4_code)) print("County: {}".format(metadata.county_name)) print("Latitude: {}".format(metadata.latitude)) print("Longitude: {}".format(metadata.longitude)) print("")