google-i18n-address

repository·master·Indexed 41 days ago

https://github.com/mirumee/google-i18n-address

A Python package providing tools for international address validation, normalization, latinization, and formatting based on Google's i18n address database. Version 3.1.1 includes utilities such as normalize_address for canonicalization, format_address for postal regulation compliance, and get_validation_rules for building dynamic address forms.

Tokens
3K
Snippets
9
Records
13
Agent score
50%

What's inside google-i18n-address

  1. Integrate with Django Forms

    master

    You can integrate i18naddress into a Django forms.Form by overriding the clean() method. Use get_validation_rules to provide context-aware error messages (like postal code examples) and normalize_address to ensure the cleaned_data contains the canonical address format.

    from django import forms
    from i18naddress import InvalidAddressError, normalize_address, get_validation_rules
    
    class AddressForm(forms.Form):
        # ... field definitions ...
    
        def clean(self):
            clean_data = super(AddressForm, self).clean()
            validation_rules = get_validation_rules(clean_data)
            try:
                valid_address = normalize_address(clean_data)
            except InvalidAddressError as e:
                errors = e.errors
                valid_address = None
                for field, error_code in errors.items():
                    if field == 'postal_code':
                        examples = validation_rules.postal_code_examples
                        msg = f'Invalid value, use format like {examples}'
                    else:
                        msg = self.ERROR_MESSAGES.get(error_code, 'Invalid field')
                    self.add_error(field, msg)
            return valid_address or clean_data
  2. Validate and normalize addresses with `normalize_address`

    master

    Use normalize_address(address_dict) to check if an address is valid and convert it to its canonical form (suitable for storage and mailing labels).

    If the address is invalid, it raises an InvalidAddressError. You can access the specific validation errors via the .errors attribute of the exception, which returns a dictionary mapping field names to error codes (e.g., 'required' or 'invalid').

    from i18naddress import InvalidAddressError, normalize_address
    
    try:
        # Example of a valid address
        address = normalize_address({
            'country_code': 'US',
            'country_area': 'California',
            'city': 'Mountain View',
            'postal_code': '94043',
            'street_address': '1600 Amphitheatre Pkwy'
        })
        print(address)
    except InvalidAddressError as e:
        # Example of handling errors
        print(e.errors)
  3. Retrieve validation rules for address forms with `get_validation_rules`

    master

    To build dynamic address forms, use get_validation_rules(address_dict) to obtain a ValidationRules object for a specific country or region. This object contains metadata required to construct a compliant form, including:

    • allowed_fields: Fields that can be included in the form.
    • required_fields: Fields that must be present.
    • upper_fields: Fields that should be converted to uppercase.
    • country_area_choices: A list of valid regions/provinces/states.
    • postal_code_matchers: Regex patterns for validating postal codes.
    • postal_code_examples: Example strings for user guidance.
    • address_format: The template for formatting the address.
    from i18naddress import get_validation_rules
    
    # Get rules for US California
    rules = get_validation_rules({'country_code': 'US', 'country_area': 'CA'})
    print(rules.required_fields)
    print(rules.country_area_choices)
  4. Get a Latinized version of an address with `latinize_address`

    master

    The latinize_address(address_dict) function returns a verbose, Latinized version of an address. This is useful for full-text search indexing or displaying foreign addresses in a more accessible format for non-native speakers.

    Note: The normalized form (from normalize_address) should still be used for database storage and printing labels. latinize_address also expands abbreviations (e.g., converting 'CA' to 'California').

    from i18naddress import latinize_address
    
    address = {
        'country_code': 'CN',
        'country_area': '云南省',
        'postal_code': '677400',
        'city': '临沧市',
        'city_area': '凤庆县',
        'street_address': '中关村东路1号'
    }
    print(latinize_address(address))
  5. Format addresses for delivery with `format_address`

    master

    Use format_address(address_dict, latin=False) to generate a string formatted according to the destination country's postal regulations.

    • By default, it uses the local script (e.g., Chinese characters for China).
    • Setting latin=True produces a Latin-friendly version of the address.
    from i18naddress import format_address
    
    address = {
        'country_code': 'CN',
        'country_area': '云南省',
        'postal_code': '677400',
        'city': '临沧市',
        'city_area': '凤庆县',
        'street_address': '中关村东路1号'
    }
    
    # Local format
    print(format_address(address))
    
    # Latin-friendly format
    print(format_address(address, latin=True))
  6. Reference: Recognized Address Fields

    master

    The following fields are recognized by the package for address dictionaries:

    • country_code: Two-letter ISO 3166-1 country code.
    • country_area: Designation of a region, province, or state (supports official names, abbreviations, translations, and Latin transliterations).
    • city: City or town name.
    • city_area: Sublocality like a district.
    • street_address: The street address (can be multiline).
    • postal_code: Postal code or zip code.
    • sorting_code: A sorting code.
    • name: A person's name.
    • company_name: A name of a company or organization.
  7. Get address field order with `get_field_order()`

    master

    Use get_field_order(address, latin=False) to retrieve the expected sequence of address form fields as a list of lists. This is useful for dynamically generating UI forms that match the required input order for a specific country.

    Example for Poland (PL): [[u'name'], [u'company_name'], [u'street_address'], [u'postal_code', u'city']]

    from i18naddress import get_field_order
    
    address = {"country_code": "PL"}
    order = get_field_order(address)
    # Returns: [['name'], ['company_name'], ['street_address'], ['postal_code', 'city']]
  8. Latinize an address with `latinize_address()`

    master

    Use latinize_address(address, normalized=False) to convert administrative areas (like cities or states) to their Latinized names (e.g., converting local script names to Latin characters).

    • address: The address dictionary to process.
    • normalized: If False (default), the function first calls normalize_address() on the input. If True, it assumes the address is already normalized.

    This is particularly useful for international shipping where labels must be readable in Latin script.

    from i18naddress import latinize_address
    
    address = {
        "country_code": "JP",
        "city": "東京都"
    }
    
    # This will attempt to find the Latinized name for the city
    latinized = latinize_address(address)
    print(latinized["city"]) # e.g., 'Tokyo'
  9. Retrieve validation rules with `get_validation_rules()`

    master

    Use get_validation_rules(address) to get a ValidationRules object containing all metadata for a specific country and address context. This includes:

    • allowed_fields: Fields valid for this country.
    • required_fields: Fields that must be present.
    • address_format: The template string for formatting.
    • postal_code_matchers: A list of compiled regex patterns for validating postal codes.
    • country_area_choices, city_choices, etc.: Lists of valid administrative area names.
  10. Load raw validation data with `load_validation_data()`

    master

    Use load_validation_data(country_code="all") to directly load the underlying JSON validation data for a specific country.

    • country_code: The ISO country code (e.g., 'us', 'fr'). Use 'all' to load the general database.
    • Returns: A dictionary containing the raw validation data for that country.

    Note: This function is a lower-level utility compared to get_validation_rules().

  11. Normalize an address with `normalize_address()`

    master

    Use normalize_address(address) to clean and validate an address dictionary. This function performs several tasks:

    • Converts country_code to uppercase.
    • Validates the country_code exists in the database.
    • Normalizes country_area, city, and city_area against allowed choices.
    • Validates the postal_code against country-specific regex matchers.
    • Converts fields marked as upper_fields to uppercase.
    • Removes fields that are not in the allowed_fields list for that country.

    If validation fails, it raises an InvalidAddressError containing a dictionary of errors (e.g., {'postal_code': 'invalid', 'city': 'required'}).

    from i18naddress import normalize_address, InvalidAddressError
    
    address = {
        "country_code": "us",
        "postal_code": "90210",
        "city": "Beverly Hills",
        "street_address": "90210 Wilshire Blvd"
    }
    
    try:
        normalized = normalize_address(address)
        print(normalized)
    except InvalidAddressError as e:
        print(f"Errors: {e.errors}")
  12. Format an address with `format_address()`

    master

    Use format_address(address, latin=False) to convert an address dictionary into a human-readable, multi-line string based on the country's specific formatting rules.

    • address: A dictionary containing address components.
    • latin: If True, uses the address_latin_format (Latinized version) instead of the default address_format.

    The resulting string includes the formatted address lines followed by the country name.

    from i18naddress import format_address
    
    address = {
        "country_code": "US",
        "street_address": "123 Main St",
        "city": "New York",
        "postal_code": "10001"
    }
    
    formatted = format_address(address)
    print(formatted)