In this tutorial, we will be using geoip2 to find a geolocation of any IP Address.

geoip2 is a Python package provided by Maxmind. Two different products are offered with the geoip2 package. First is a web service. This is a pay per use product. You will need to sign up for a User ID and license key to use this. Second, there is a free version in which the database will be downloaded and stored locally. The free version is what we’ll be covering here.

For starters, we will need to install the package:

mkdir ip_geolocation
cd ip_geolocation
pip install geoip2

Once installed, we need to download the database from the Maxmind website:

Maxmind City Lite Database Download

Download and unzip using the terminal:

wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
tar -xzf GeoLite2-City.tar.gz

When unzipped, you will see a folder with a date appended to it (i.e. GeoLite2-City_20180206). Since this database is updated periodically, future downloads will have a different folder name. In this folder, the file we’re interested in is GeoLite2-City.mmdb, which is the database.

In order to read from this database, we’ll need to create a new Python file and import the geoip2 package.

Create the file:

touch geoip_lookup.py

Import the package:

import geoip2.database

Next, we will create a new reader variable and use that to open the database:

reader = geoip2.database.Reader('./GeoLite2-City_20180206/GeoLite2-City.mmdb')

Next, given an IP address, we can get the IP geolocation info.

response = reader.city('98.155.130.10')

Now that we have the geolocation contained in the response variable, we can print the data we’re looking for:

print(response.country.iso_code)  # US
print(response.subdivisions.most_specific.name)  # Hawaii
print(response.subdivisions.most_specific.iso_code)  # HI
print(response.city.name)  # Kailua
print(response.postal.code)  # 96734

reader.close()

Notice that “subdivisions” is what contains the state info.

Maxmind also follows the standards set by International Organization for Standardization (ISO), which is reflected in the iso_code properties. More info regarding country ISO codes can be found here.

Final note: other databases and a web service (mentioned earlier) are provided by Maxmind. The paid alternatives are generally more accurate and updated more frequently.

Here is the contents of the full script:

import geoip2.database

reader = geoip2.database.Reader('./GeoLite2-City_20180206/GeoLite2-City.mmdb')

response = reader.city('98.155.130.10')
print(response.country.iso_code)
print(response.subdivisions.most_specific.name)
print(response.subdivisions.most_specific.iso_code)
print(response.city.name)
print(response.postal.code)

reader.close()

Posted in