1

I'm trying to take a UK mobile phone number input from a web form and use Python to clean it into a E.164 format, then validate it, before entering it into a database.

The library I'm trying to use is "Phonenumbers" and the code I'm experimenting with so far is:

def Phone():
    my_number = '+4407808765066'
    clean_phone = phonenumbers.parse(my_number, "GB")
    cleaner_phone = phonenumbers.format_number(clean_phone, 
    phonenumbers.PhoneNumberFormat.E164)
    valid = phonenumbers.is_possible_number(cleaner_phone)
    print(cleaner_phone)

Just working through the logic, my expectation is that it should take the contents of my_number variable, format it through into the clean_phone variable, then format it to E.164 standard before passing it to the validation and return the output to valid. The print statement is for me to see the output.

Everything looks to work ok if I comment out the valid variable line. As soon as I uncomment it, I get an error (see below).

Traceback (most recent call last):
  File "phone_test.py", line 14, in <module>
    Phone()
  File "phone_test.py", line 10, in Phone
    valid = phonenumbers.is_possible_number(cleaner_phone)
  File "D:\Dropbox\Coding Projects\learner_driver_app\env\lib\site-packages\phonenumbers\phonenumberutil.py", line 2257, in is_possible_number      
    result = is_possible_number_with_reason(numobj)
  File "D:\Dropbox\Coding Projects\learner_driver_app\env\lib\site-packages\phonenumbers\phonenumberutil.py", line 2358, in is_possible_number_with_reason
    return is_possible_number_for_type_with_reason(numobj, PhoneNumberType.UNKNOWN)
  File "D:\Dropbox\Coding Projects\learner_driver_app\env\lib\site-packages\phonenumbers\phonenumberutil.py", line 2393, in is_possible_number_for_type_with_reason
    national_number = national_significant_number(numobj)
  File "D:\Dropbox\Coding Projects\learner_driver_app\env\lib\site-packages\phonenumbers\phonenumberutil.py", line 1628, in national_significant_number
    if numobj.italian_leading_zero:
AttributeError: 'str' object has no attribute 'italian_leading_zero'

Where am I going wrong?

  • Are you sure the phone number stored in my_number is a a valid number? – 0x263A Nov 11 '21 at 15:54
  • it should be, it's the standard international format for a Uk mobile......as far as i'm aware :) – andyhughes73 Nov 12 '21 at 00:56
  • According to [Wikipedia](https://en.wikipedia.org/wiki/Telephone_numbers_in_the_United_Kingdom#Format) phone numbers in the UK go up to 10 digits in length and can be preceded by a two digit country code. Your number, "44 0780 876506 6" appears to have an extra digit. (not from the UK or a phone number expert, just speculating) – 0x263A Nov 12 '21 at 01:04
  • @0x263A - The number is definitely UK valid mobile. I'm sure the code strips the +44 and 0 first, then it re-adds the +44 back to make it an E.164 format number. So that bit works fine as of testing it last night. What I then realised, is that the final part "is_valid_number" is actually a boolean. I think that's why it's throwing the string error. I'd still like to use the "validity" check but I don't know how to get from the previous output to a boolean output? – andyhughes73 Nov 12 '21 at 09:17

2 Answers2

5

Your my_number is a variable of type str (string), thus the last line of your error). The string class does not know the attribute national_number.
Reading through their examples on GitHub, I suspect you need to pass your string through the parse() function first before you can use functions from the library.

def phone_parser():
    my_number = '+4407811111111'
    number_parsed = phonenumbers.parse(my_number, None)  # this is new
    clean_phone = phonenumbers.format_number(number_parsed, 
    phonenumbers.PhoneNumberFormat.E164)
    return clean_phone

The None in parse() may be replaced by a country code if it is known. Otherwise, it will try to figure it out but may fail.

Edit to account for more information in the original question:
Apparently phonenumbers.format_number() returns a string, therefore you have to re-parse the number again to get an object of type phonenumbers.phonenumber.PhoneNumber (you can check the type of objects with type(my_object)). After that, your code will return True.

Zhymabek Roman
  • 35
  • 2
  • 11
white
  • 601
  • 3
  • 8
0

You can't use the format_number function with a string as argument, it expects a PhoneNumber object.

You can get one by using the parse function.

See https://github.com/daviddrysdale/python-phonenumbers/tree/dev/python#example-usage

mkrieger1
  • 19,194
  • 5
  • 54
  • 65