Validating an IP Address and Getting Geolocation Information With Python

Last Updated Apr 25, 2022
Elizabeth (Lizzie) Shipton

Lizzie is a Full Stack Engineer at Udacity and freelance technical content writer. She has experience working with Node, GraphQL, Postgres, React and Sass.

Every device that is connected to the internet is identified with a unique string of numbers called an IP address. IP stands for “Internet Protocol,” and refers to a set of rules that govern one part of how data is sent around the internet. IP addresses, combined with DNS resolution, are how information gets from one computer to another.

If you’re building an app using Python or a Python framework like Django or Flask, you may at some point need to determine if a user's IP is a valid IP address. IP address validation is useful for a number of things, like preventing fraud or providing targeted location services to your users.

Don't reinvent the wheel.
Abstract's APIs are production-ready now.

Abstract's suite of API's are built to save you time. You don't need to be an expert in email validation, IP geolocation, etc. Just focus on writing code that's actually valuable for your app or business, and we'll handle the rest.

Get started for free

IPv4 vs IPv6

Before we dive into validation, let’s quickly talk about the two types of IP addresses you’ll come across. For the purposes of this tutorial, we’ll focus on analyzing and using IPv4 addresses, since that’s still the most commonly used and understood format.

IPv4

The IP addresses you’re probably familiar with are the IPv4 version addresses. An IPv4 address looks like a four-part string of numbers separated by periods:


32.253.431.175

Each number in the four-part string can range from 0 to 255, and is an 8-bit field that represents one byte of the IP address. This makes the complete IP a 32-bit (4 x 8 bits) address space, which provides enough combinations for 4.3 billion unique addresses.

IPv6

IPv6 is a new format of IP address that looks slightly different from IPv4. An IPv6 address looks like this:


3002:0bd6:0000:0000:0000:ee00:0033:6778

Note that it uses a combination of alphanumeric characters, and has twice the number of available spaces that an IPv4 address has. It is a 128-bit address space and allows for a lot more unique address combinations. Whereas IPv4 allows for 4.3 billion unique addresses, IPv6 provides enough space for 2^128 unique addresses. That’s 1028 times as many addresses as IPv4!

Why Do We Need IPv6?

Even though IPv4 is called “version 4” it is actually the first version of IP ever created and has been around since the invention of the internet. Back in those days, engineers couldn’t have imagined that 4.3 billion unique addresses wouldn’t be enough to handle our needs—but here we are in 2022 with about 4.29 billion addresses already used up by various smartphones, laptops, and tablets.

IPv6 provides enough space that we should theoretically never run out of space for new addresses.

How to Validate IP Address in Python

In this tutorial, we’ll cover a couple of the easiest ways to determine that an IP address is valid using Python. We’ll also learn how to use a valid IP address to determine the user’s location using the AbstractAPI IP Geolocation API. 

Validate an IP Address Using the Python ipaddress() module

Python ships with a handy module called ipaddress that can be used to parse IP addresses, tell you their type and other information about them, and perform basic arithmetic on IP addresses. It does not tell you explicitly that an address is a valid IP address, but with some custom logic we can use it as such. 

This is the most robust and secure way of validating an IP address in Python. The module supports both IPv4 and IPv6 addresses.

To use the ipaddress module, first import it into your Python code.


import ipaddress

Next, call the .ip_address() method on the ipaddress class, passing it an IP string.


ipaddress.ip_address("127.0.0.1")

If the IP string passed is a valid IPv4 address or valid IPv6 address, the ipaddress module will use the string to create a new IP address object. If the string passed is not a valid IP address, the ipaddress module will throw a value error. Let’s run the code above with an invalid IP and look at the output in the terminal.


ipaddress.ip_address("this is not an IP address")

...traceback most recent call
>>> raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
>>> ValueError: "this is not an IP address" does not appear to be an IPv4 or IPv6 address

The ipaddress module is not actually validating our IP address. It’s attempting to use the provided string to create a Python IP address object. To use this logic to validate an IP, we need to create our own IP validation function.


import ipaddress
def validate_ip_address(ip_string):
   try:
       ip_object = ipaddress.ip_address(ip_string)
       print("The IP address '{ip_object}' is valid.")
   except ValueError:
       print("The IP address '{ip_string}' is not valid")

validate_ip_address("127.0.0.1")

>>> The IP address "127.0.0.1" is valid.

The ipaddress module works for IPv6 addresses as well as IPv4 addresses:


validate_ip_address("2001:0db8:75a2:0000:0000:8a2e:0340:5625")

>>> The IP address "2001:0db8:75a2:0000:0000:8a2e:0340:5625" is valid.

Validate an IP Using Python and Regex

Another way to validate an IP address is by using your own custom regex to check the shape of the provided IP string. Python provides a library called re for parsing and matching Regex.

This method is less robust that using the ipaddress module, and requires more code on our end to check that the string is not only the right shape, but that the values in it are between 0 and 255. You’ll also need two write two separate functions to check an IPv4 address vs an IPv6 address, as IPv6 addresses have a difference shape.

In this tutorial, we’ll cover IPv4.

First, we’ll create a Regex string that matches an IPv4 address. There are a few ways to write this, but a nice, clear way to do it is the following:


"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"

Let’s break down the components of this expression. 


[0-9]

The first group of characters indicates that we’re looking for a numeric character between 0 and 9


{1,3}

Next, the numbers between the curly braces tell the Regex parser that we’re looking for as few as one or as many as three instances of the previous character set. Since our previous character set was a number from 0 to 9, this tells the parser that we’re looking for a set of 1-3 numeric characters.


\.

This tells the parser to look for the . character. In Regex, the . character is a special character that means “any character.” We have to escape the  .  with a backslash to tell the parser that we’re looking for a literal  . and not “any character.”

Those three components make up one byte of an IP address (for example, 192.) Now, we simply repeat this string four times (omitting the final period.)

To use our Regex string, we need to import the Python re module. Next, we’ll use the .match() method from the module to match a string input against our Regex expression. 


import re
match = re.match(r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", "127.0.0.1")
print(match)

>>> <re.Match object; span=(0, 9), match='127.0.0.1'>

 If the string is a match, re will use it to create a Match object with information about the span of the match, and the string that was matched. Since we don’t need all that info, we’ll cast the response to a boolean.


print(bool(match))

>>> True

This is fine, but what if the user inputs a string that includes a 3-digit number greater than 255? Currently, our Regex matcher would return True even though that is not a valid IPv4 address. So we need to do one other check on our string to make sure that all of the numbers in it are between 0 and 255.

Here’s what our complete validation function using Regex looks like with that check included:


def validate_ip_regex(ip_address):
   match = re.match(
       r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", "127.0.0.1", ip_address)
  
   if not bool(match):
       print(f"The IP address {ip_address} is not valid")
       return False

   bytes = ip_address.split(".")
  
   for ip_byte in bytes:
       if int(ip_byte) < 0 or int(ip_byte) > 255:
           print(f"The IP address {ip_address} is not valid")
           return False
   print(f"The IP address {ip_address} is valid")
   return True

How to Find a User’s Location Using AbstractAPI's IP Geolocation API

Once you’re sure you have a valid IP address, you can use that IP address to determine the user’s geographical location. This is useful for doing things like serving assets in the correct language, verifying that a user’s request is not fraudulent, and showing the user’s location on a map.

To find out the user’s geolocation from their IP, we’ll use the AbstractAPI IP Geolocation API. This simple REST API accepts an IP address string and returns a JSON object with information about the IP address, including location, device information, carrier information and more.

Getting Started With the API

Acquire an API Key

  1. Navigate to the API documentation page. You’ll see an example of the API’s JSON response object to the right, and a blue “Get Started” button to the left.

  1. Click the “Get Started” button. If you’ve never used AbstractAPI before, Yyu’ll be taken to a page where you’re asked to input your email and create a password. If you have used Abstract before, you may be asked to log in.

  1. Once you’ve signed up or logged in, you’ll land on the API’s homepage where you should see options for documentation, pricing and support, along with your API key and tabs to view test code for supported languages.

Making an IP Geolocation Request With Python

Your API key is all you need to get geolocation information for an IP address. AbstractAPI provides some example code in several languages to get you started. Plugging the code to make the request into our python app is simple. Let’s add a new function to take the IP address we just validated, and send it to the API.

  1. Select the “Python” tab on the AbstractAPI Geolocation API tester page. You’ll see a code snippet in the text box.

  1. Copy the code snippet and paste it into a new function called get_geolocation_info. This will be where we handle the logic for sending and receiving our requests to AbstractAPI.

import requests
def get_geolocation_info(validated_ip_address):
   try:
       response = requests.get(
      "https://ipgeolocation.abstractapi.com/v1/?api_key=YOUR_API_KEY&ip_address={validated_ip_address}")
       print(response.content)
   except requests.exceptions.RequestException as api_error:
       print(f"There was an error contacting the Geolocation API: {api_error}")
       raise SystemExit(api_error)

Here, we use the Python requests library to send a GET request to the AbstractAPI Geolocation API url, including our API key and the IP address as querystring parameters. When the JSON response comes back, we simply print the content, but in a real app you would access the response object fields and use the information in your app.

Let’s clean up the function a bit to come in line with best practices.


api_url = "https: // ipgeolocation.abstractapi.com/v1/"
api_key = YOUR_API_KEY

def get_geolocation_info(validated_ip_address):
   params = {
       'api_key': api_key,
       'ip_address': validated_ip_address
   }
  try:
      response = requests.get(api_url, params=params)
      print(response.content)
  except requests.exceptions.RequestException as api_error:
      print(f"There was an error contacting the Geolocation API: {api_error}")
      raise SystemExit(api_error)

The response that AbstractAPI sends (which is printed when we call print(response.content) looks like this:


{
    "ip_address": "XXX.XX.XXX.X",
    "city": "City Name",
    "city_geoname_id": ID_NUMBER,
    "region": "Region",
    "region_iso_code": "JAL",
    "region_geoname_id": GEONAME_ID,
    "postal_code": "postalcode",
    "country": "Country",
    "country_code": "CC",
    "country_geoname_id": GEONAME_ID,
    "country_is_eu": false,
    "continent": "North America",
    "continent_code": "NA",
    "continent_geoname_id": GEONAME_ID,
    "longitude": longitude,
    "latitude": latitude,
    "security": {
        "is_vpn": false
    },
    "timezone": {
        "name": "America/Timezone",
        "abbreviation": "ABBR",
        "gmt_offset": -5,
        "current_time": "15:52:08",
        "is_dst": true
    },
    "flag": {
        "emoji": "🇺🇸",
        "unicode": "U+1F1F2 U+1F1FD",
        "png": "https://static.abstractapi.com/country-flags/US_flag.png",
        "svg": "https://static.abstractapi.com/country-flags/US_flag.svg"
    },
    "currency": {
        "currency_name": "Dollar",
        "currency_code": "USD"
    },
    "connection": {
        "autonomous_system_number": NUMBER,
        "autonomous_system_organization": "System Org.",
        "connection_type": "Cellular",
        "isp_name": "Isp",
        "organization_name": "Org."
    }
}

Note: identifying information has been redacted.

Now we can write a single function that uses our Regex validation function to validate the IP and then sends it to the Geolocation API using our geolocation request function.


def validate_ip_and_get_geolocation(ip_address):
   is_valid_ip = validate_ip_regex(ip_address)
   if is_valid_ip:
       get_geolocation_info(ip_address)

Conclusion

In this article, we learned what an IP address is, the difference between IPv4 and IPv6 addresses, how to validate an IP address using the Python ipaddress module and using Regex, and how to get geolocation info for an IP address using the AbstractAPI Geolocation API.

FAQs

How do I find my IP address?

You can easily view your current IP address by visiting https://whatismyipaddress.com/. This site gives clear information about your device’s current IP address, as well as fairly accurate geolocation information. 

Your device Settings should also tell you your IP address. On a Macbook, open System Preferences > Network > Select either WiFi or Ethernet, depending on your connection. Your IP address will be displayed next to the list of network preferences.

Similar steps for finding your IP address on a smartphone or laptop can be found by googling.

How do I determine a location from an IP address?

There are several ways to find a user’s location from their IP address. The easiest way is to use a dedicated geolocation API, such as AbstractAPI’s IP Geolocation API. You can also look at the logs view of your web server if you have access to it. If you run a website and use Google Analytics, the Google Search Console gives you access to basic user location information like country and state. 

Why should I care about my IP address?

Honestly, you don’t really need to. However, you should know that when you browse the internet, your IP address is used by apps and websites to get information about your device, location, and other things. Your IP address is just one way that sites have of tracking you. If you don’t want websites to be able to identify you, consider using a VPN to hide your IP information.

Get the location of any IP with an up-to-date API serving data for city, region, and country.

Get started for free
Get the location of any IP with an up-to-date API serving data for city, region, and country.
Get started