Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python A Social Network with Flask Takin' Names Flask-WTF Forms

Andy Hughes
Andy Hughes
8,478 Points

what about phone numbers?

Ok so I'm attempting to build a web app to put my Python skills to the test and I've already hit a problem that's making me question my ability to do even the basics! :(

In ALL of the Python/Flask/Peewee videos I've watched on here, where people have been using forms, no one has talked about phone numbers. Please correct me if I'm wrong.

So in my user registration I need them to supply a UK phone number. But I can immediately see a problem with this. If I use a standard CharField, they can enter their phone number in any number of different ways (07777-777-777, +44777-777-777, +44777777777).

If I am going to store this number in a database then my thinking is that I need to "standardize" the input (to E.164 was my thinking). Only I have no idea how!

I found out about the "phonenumbers" library based on the Google one. It looks like it would do the job and so I imported it, played around with some code and until just this minute I was getting errors. However, I've just run the below code and it returned an output of True. But I don't know what that means!

Does it mean that new_number has been checked as a valid GB phone number and because it is, it's returning True? I'm still just too new to know what I'm looking at.

If I'm correct and the function does return a valid phone number, can I

def Phone():
    my_number = '+4407808765066'
    clean_phone = phonenumbers.parse(my_number, "GB")
    new_number = phonenumbers.is_valid_number(clean_phone)
    print ('new_number')

It would be really useful to include this in the Python forms video as I can see it being a very common user registration requirement. I literally can't find it anywhere on Youtube either.

1 Answer

def Phone():
    my_number = '+4407808765066' # Sets my_number to a constant
    clean_phone = phonenumbers.parse(my_number, "GB") # Parses my_number or throws a phonenumbers.phonenumberutil.NumberParseException
    new_number = phonenumbers.is_valid_number(clean_phone) # Sets the value of new_number to True if clean_phone is a valid phone number and False otherwise
    print ('new_number') # Prints the string 'new_number'
    # returns None

If you want to pass a different phone number to your function each time, you could change my_number to be a parameter, changing the first line of the function to def Phone(my_number):. To return the phone number formatted as E164, you could put return phonenumbers.format_number(clean_phone, phonenumbers.PhoneNumberFormat.E164) as the last line of the function. You might also want to catch any exceptions by putting the code inside the function within a try-except block.

Andy Hughes
Andy Hughes
8,478 Points

jb30 - Thank you jb. 1) already caught the string print (schoolboy error!) 2) My plan is to call the parameter from a form input just like you suggest. I just want to test the code in isolation first. :)

So i've played around a bit and my code now looks like this:

my_number = "07112223334" # this will be the input from a form
clean_phone = phonenumbers.parse(my_number, "GB")  # Strips the int dialling code and leading zero
cleaner_phone = phonenumbers.is_valid_number(clean_phone) # checks validity of the number (against what I'm not entirely sure! I'm assuming it's UK standard)
print(cleaner_phone)

So this returns True. I have tried changing the number to non UK variations, which return False. So on the face of it, this looks like most of what I want to do I think. Two things I still need to figure out, is how to make it work for both GB and IE (Northern Ireland) phone numbers. Also, what value to add into the database. At the moment, I'm thinking I can just use the value in clean_phone?

Absolutely agree, I still need to deal with errors/exceptions. Will try that once I can get the code producing a correct result. :)

Thanks for the support.

Storing the value in clean_phone seems reasonable. If you are dealing with actual user phone numbers, you might be more concerned about data protection and want to encrypt the database.

To allow for both 'GB' and 'IE' numbers, you could try

clean_phone = phonenumbers.parse(my_number)
if phonenumbers.is_valid_number(clean_phone):
  region_code = phonenumbers.phonenumberutil.region_code_for_number(clean_phone)
  if region_code in ['GB', 'IE']:
    return clean_phone
return None