Exemple #1
0
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("***********************************")
Exemple #2
0
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("")
Exemple #3
0
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("***********************************")
Exemple #4
0
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("")