Python port of Google's libphonenumber library for parsing, formatting, storing and validating international phone numbers
—
Essential phone number operations that form the foundation of all phone number processing. These functions handle parsing phone numbers from various string formats, formatting them for different output contexts, and validating their correctness.
Converts phone number strings into structured PhoneNumber objects, handling various input formats and regional contexts.
def parse(number: str, region: str | None = None, keep_raw_input: bool = False, numobj: PhoneNumber | None = None) -> PhoneNumber:
"""
Parse a phone number string and return a PhoneNumber object.
Parameters:
- number: Phone number string to parse
- region: Default region code (e.g., "US", "GB") for parsing numbers without country codes
- keep_raw_input: Whether to store raw input for reformatting (enables format_in_original_format)
- numobj: Existing PhoneNumber to populate (optional)
Returns:
PhoneNumber object representing the parsed number
Raises:
NumberParseException: If the number cannot be parsed
"""Usage Examples:
# Parse international number with country code
phone = phonenumbers.parse("+442083661177")
# Parse national number with region context
phone = phonenumbers.parse("020 8366 1177", "GB")
# Parse with raw input retention for original formatting
phone = phonenumbers.parse("(650) 253-2222", "US", keep_raw_input=True)
# Handle parsing errors
try:
phone = phonenumbers.parse("invalid", "US")
except phonenumbers.NumberParseException as e:
print(f"Parsing failed: {e}")Converts PhoneNumber objects to formatted strings in various standard formats.
def format_number(numobj: PhoneNumber, num_format: int) -> str:
"""
Format a phone number using the specified format.
Parameters:
- numobj: PhoneNumber object to format
- num_format: Format type (PhoneNumberFormat.E164, INTERNATIONAL, NATIONAL, RFC3966)
Returns:
Formatted phone number string
"""
def format_by_pattern(numobj: PhoneNumber, number_format: int, user_defined_formats: list[NumberFormat]) -> str:
"""
Format using custom user-defined formatting patterns.
Parameters:
- numobj: PhoneNumber object to format
- number_format: Base format type
- user_defined_formats: List of custom NumberFormat patterns
Returns:
Formatted phone number string using custom patterns
"""
def format_in_original_format(numobj: PhoneNumber, region_calling_from: str) -> str:
"""
Format in the same style as the original input (requires keep_raw_input=True during parsing).
Parameters:
- numobj: PhoneNumber object (must have raw_input preserved)
- region_calling_from: Region code for formatting context
Returns:
Phone number formatted to match original input style
"""Usage Examples:
phone = phonenumbers.parse("+442083661177")
# Different format types
e164 = phonenumbers.format_number(phone, phonenumbers.PhoneNumberFormat.E164)
# "+442083661177"
international = phonenumbers.format_number(phone, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
# "+44 20 8366 1177"
national = phonenumbers.format_number(phone, phonenumbers.PhoneNumberFormat.NATIONAL)
# "020 8366 1177"
rfc3966 = phonenumbers.format_number(phone, phonenumbers.PhoneNumberFormat.RFC3966)
# "tel:+44-20-8366-1177"
# Original format preservation
phone = phonenumbers.parse("(650) 253-2222", "US", keep_raw_input=True)
original = phonenumbers.format_in_original_format(phone, "US")
# "(650) 253-2222"Specialized formatting for international dialing and mobile contexts.
def format_out_of_country_calling_number(numobj: PhoneNumber, region_calling_from: str) -> str:
"""
Format for calling from one country to another.
Parameters:
- numobj: PhoneNumber to format
- region_calling_from: Region code where the call originates
Returns:
Number formatted for international dialing from the specified region
"""
def format_number_for_mobile_dialing(numobj: PhoneNumber, region_calling_from: str, with_formatting: bool) -> str:
"""
Format for mobile dialing from specified region.
Parameters:
- numobj: PhoneNumber to format
- region_calling_from: Region code for mobile dialing context
- with_formatting: Whether to include spacing and punctuation
Returns:
Number formatted for mobile dialing
"""
def format_out_of_country_keeping_alpha_chars(numobj: PhoneNumber, region_calling_from: str) -> str:
"""
Format for international calling while preserving alphabetic characters.
Parameters:
- numobj: PhoneNumber with potential alpha characters
- region_calling_from: Region code for calling context
Returns:
Formatted number preserving letters (e.g., 1-800-FLOWERS)
"""National formatting with carrier-specific prefixes.
def format_national_number_with_carrier_code(numobj: PhoneNumber, carrier_code: str) -> str:
"""
Format in national format with specified carrier code.
Parameters:
- numobj: PhoneNumber to format
- carrier_code: Carrier access code to include
Returns:
National format with carrier code prefix
"""
def format_national_number_with_preferred_carrier_code(numobj: PhoneNumber, fallback_carrier_code: str) -> str:
"""
Format in national format using preferred carrier code or fallback.
Parameters:
- numobj: PhoneNumber (may have preferred_domestic_carrier_code set)
- fallback_carrier_code: Carrier code to use if none preferred
Returns:
National format with preferred or fallback carrier code
"""Comprehensive validation functions for checking phone number correctness and possibility.
def is_valid_number(numobj: PhoneNumber) -> bool:
"""
Check if number is valid and can be used for connecting calls.
Parameters:
- numobj: PhoneNumber to validate
Returns:
True if the number is valid for calling
"""
def is_valid_number_for_region(numobj: PhoneNumber, region_code: str) -> bool:
"""
Check if number is valid for the specified region.
Parameters:
- numobj: PhoneNumber to validate
- region_code: Region code to validate against
Returns:
True if the number is valid in the specified region
"""
def is_possible_number(numobj: PhoneNumber) -> bool:
"""
Check if number could be a valid phone number (length-based check).
Parameters:
- numobj: PhoneNumber to check
Returns:
True if the number has valid length characteristics
"""
def is_possible_number_for_type(numobj: PhoneNumber, numtype: int) -> bool:
"""
Check if number is possible for the specified type.
Parameters:
- numobj: PhoneNumber to check
- numtype: PhoneNumberType value to check against
Returns:
True if the number could be valid for the specified type
"""
def is_possible_number_with_reason(numobj: PhoneNumber) -> int:
"""
Check possibility and return detailed reason.
Parameters:
- numobj: PhoneNumber to validate
Returns:
ValidationResult value indicating why number may not be possible
"""
def is_possible_number_for_type_with_reason(numobj: PhoneNumber, numtype: int) -> int:
"""
Check possibility for specific type and return detailed reason.
Parameters:
- numobj: PhoneNumber to validate
- numtype: PhoneNumberType value to check against
Returns:
ValidationResult value for the specific number type
"""
def is_possible_number_string(number: str, region_dialing_from: str) -> bool:
"""
Check if number string could be possible from given region without full parsing.
Parameters:
- number: Phone number string
- region_dialing_from: Region code for parsing context
Returns:
True if the string could represent a valid phone number
"""Usage Examples:
phone = phonenumbers.parse("+442083661177")
# Basic validation
is_valid = phonenumbers.is_valid_number(phone) # True
is_possible = phonenumbers.is_possible_number(phone) # True
# Regional validation
is_valid_uk = phonenumbers.is_valid_number_for_region(phone, "GB") # True
is_valid_us = phonenumbers.is_valid_number_for_region(phone, "US") # False
# Type-specific validation
is_possible_mobile = phonenumbers.is_possible_number_for_type(
phone, phonenumbers.PhoneNumberType.MOBILE
)
# Detailed validation reasons
reason = phonenumbers.is_possible_number_with_reason(phone)
if reason == phonenumbers.ValidationResult.IS_POSSIBLE:
print("Number is possible")
elif reason == phonenumbers.ValidationResult.TOO_SHORT:
print("Number is too short")
# Quick string validation
is_possible_str = phonenumbers.is_possible_number_string("020 8366 1177", "GB")Determine the type and classification of phone numbers.
def number_type(numobj: PhoneNumber) -> int:
"""
Determine the type of phone number.
Parameters:
- numobj: PhoneNumber to classify
Returns:
PhoneNumberType value (FIXED_LINE, MOBILE, TOLL_FREE, etc.)
"""Usage Examples:
phone = phonenumbers.parse("+442083661177")
num_type = phonenumbers.number_type(phone)
if num_type == phonenumbers.PhoneNumberType.FIXED_LINE:
print("This is a landline number")
elif num_type == phonenumbers.PhoneNumberType.MOBILE:
print("This is a mobile number")
elif num_type == phonenumbers.PhoneNumberType.TOLL_FREE:
print("This is a toll-free number")
# Check for specific types
mobile_phone = phonenumbers.parse("+447700123456")
is_mobile = phonenumbers.number_type(mobile_phone) == phonenumbers.PhoneNumberType.MOBILECompare phone numbers to determine if they represent the same number.
def is_number_match(num1: PhoneNumber | str, num2: PhoneNumber | str) -> int:
"""
Compare two numbers and return MatchType indicating similarity level.
Parameters:
- num1: First number (PhoneNumber object or string)
- num2: Second number (PhoneNumber object or string)
Returns:
MatchType value indicating the level of match
"""Usage Examples:
phone1 = phonenumbers.parse("+442083661177")
phone2 = phonenumbers.parse("020 8366 1177", "GB")
match_result = phonenumbers.is_number_match(phone1, phone2)
if match_result == phonenumbers.MatchType.EXACT_MATCH:
print("Numbers are exactly the same")
elif match_result == phonenumbers.MatchType.NSN_MATCH:
print("National significant numbers match")
elif match_result == phonenumbers.MatchType.NO_MATCH:
print("Numbers don't match")
# Can also compare strings directly
match_result = phonenumbers.is_number_match("+442083661177", "020 8366 1177")Utility functions for extracting and modifying phone number components.
def national_significant_number(numobj: PhoneNumber) -> str:
"""
Extract national significant number as string.
Parameters:
- numobj: PhoneNumber to extract from
Returns:
National significant number without country code
"""
def truncate_too_long_number(numobj: PhoneNumber) -> bool:
"""
Truncate number that's too long to make it valid.
Parameters:
- numobj: PhoneNumber to potentially truncate (modified in place)
Returns:
True if the number was modified, False otherwise
"""
def length_of_geographical_area_code(numobj: PhoneNumber) -> int:
"""
Get length of geographical area code.
Parameters:
- numobj: PhoneNumber to analyze
Returns:
Length of area code in digits, 0 if no area code
"""
def length_of_national_destination_code(numobj: PhoneNumber) -> int:
"""
Get length of national destination code.
Parameters:
- numobj: PhoneNumber to analyze
Returns:
Length of national destination code in digits
"""Install with Tessl CLI
npx tessl i tessl/pypi-phonenumbers