GeoIP2 (Maxmind) Wrapper Module

Various helper functions for use with Maxmind’s GeoIP2 Library

Getting started with our GeoIP2 wrapper

Basic Usage:

>>> from privex.helpers import geoip
>>> res = geoip.geolocate_ip('185.130.44.5')
>>> print(f"Country: {res.country} || Code: {res.country_code} || City: {res.city}")
Country: Sweden || Code: SE || City: Stockholm
>>> print(f"ISP: {res.as_name} || AS Num: {res.as_number}")
ISP: Privex Inc. || AS Num: 210083 || Network: 185.130.44.0/24

If your application won’t need to touch the GeoIP database for a while, you should call cleanup() to close the GeoIP2 databases to save memory:

>>> geoip.cleanup

Using the GeoIP2 geoip_manager() context manager

Alternatively, you can use the context manager geoip_manager() which will automatically call cleanup() at the end of a with block:

>>> with geoip.geoip_manager():
...     res = geoip.geolocate_ip('2a07:e00::333')
...     print(f"Postcode: {res['postcode']} || Lat: {res.get('lat', 'unknown')} || Long: {res.long}")
...
Postcode: 173 11 || Lat: 59.3333 || Long: 18.05

Accessing the underlying geoip2 library instances

If our wrappers don’t provide certain features you need, you can easily access the raw GeoIP2 reader instances.

With our context manager

Accessing geoip2.database.Reader via the context manager:

>>> import geoip2.models
>>> with geoip.geoip_manager('city') as geo:
...     data: geoip2.models.City = geo.city('95.216.3.171')
...     print('Continent:', data.continent.names.get('en'), 'Time Zone:', data.location.time_zone)
Continent: Europe Time Zone: Europe/Helsinki

Directly, via the privex.helpers.plugin module

Accessing geoip2.database.Reader via the plugin module:

>>> from privex.helpers import plugin
>>> geo = plugin.get_geoip('asn')
>>> as_data: geoip2.models.ASN = geo.asn('95.216.3.171')
>>> print(f"{as_data.autonomous_system_organization} (ASN: {as_data.autonomous_system_number})")
'Hetzner Online GmbH (ASN: 24940)'
>>> # To close the ASN database properly when you're done, call 'plugin.close_geoip' with 'asn'
>>> plugin.close_geoip('asn')
True

Copyright:

    +===================================================+
    |                 © 2020 Privex Inc.                |
    |               https://www.privex.io               |
    +===================================================+
    |                                                   |
    |        Originally Developed by Privex Inc.        |
    |        License: X11 / MIT                         |
    |                                                   |
    |        Core Developer(s):                         |
    |                                                   |
    |          (+)  Chris (@someguy123) [Privex]        |
    |          (+)  Kale (@kryogenic) [Privex]          |
    |                                                   |
    +===================================================+

Copyright 2020     Privex Inc.   ( https://www.privex.io )
class privex.helpers.geoip.GeoIPResult(country: str = None, country_code: str = None, city: str = None, postcode: str = None, as_number: int = None, as_name: str = None, ip_address: str = None, network: str = None, long: int = None, lat: int = None, geoasn_data: geoip2.models.ASN = None, geocity_data: geoip2.models.City = None)[source]
as_name

The numeric AS number identifying the ISP / Organisation the IP belongs to, e.g. 210083

as_number

The string name of the ISP / Organisation the IP belongs to, e.g. Privex Inc.

city

Full English city name where this IP is based, e.g. Stockholm

country

Full English country name where this IP is based, e.g. Sweden

country_code

Two letter ISO country code representing the country where this IP is based, e.g. SE

geoasn_data

The raw object returned by geoip2.database.Reader.asn()

geocity_data

The raw object returned by geoip2.database.Reader.city()

ip_address

The IP address the result is for

lat

An estimated latitude (part of co-ordinates) where the IP is based

long

An estimated longitude (part of co-ordinates) where the IP is based

network

The network the IP belongs to, e.g. 185.130.44.0/22

postcode

Estimated Postcode / ZIP code where the IP is located e.g. 173 11

privex.helpers.geoip.cleanup_geoip(geo_type: str = None)

With no arguments, closes and removes GeoIP city + asn + country from thread store.

With the first argument geo_type specified (either ‘city’, ‘asn’ or ‘country’), only that specific GeoIP2 instance will be closed and removed from the thread store.

privex.helpers.geoip.geolocate_ip(addr: Union[str, ipaddress.IPv4Address, ipaddress.IPv6Address], throw=True) → Optional[privex.helpers.geoip.GeoIPResult][source]

Looks up the IPv4/IPv6 address addr against GeoIP2 City + ASN, and returns a GeoIPResult containing the GeoIP data.

Usage:

>>> g = geolocate_ip('2a07:e00::333')
>>> print(g.city, g.country, g.country_code, g.as_number, g.as_name, sep='      ')
Stockholm       Sweden  SE      210083  Privex Inc.
>>> g = geolocate_ip('8.8.4.4')
None    United States   US      15169   Google LLC
Parameters
  • addr (IP_OR_STR) – An IPv4 or IPv6 address to geo-locate

  • throw (bool) – (Default: True) If True, will raise GeoIPAddressNotFound if an IP address isn’t found in the GeoIP database. If False, will simply return None if it’s not found.

Raises
  • GeoIPAddressNotFound – When throw is True and addr can’t be found in a GeoIP database.

  • ValueError – When addr is not a valid IP address.

Return Optional[GeoIPResult] res

A GeoIPResult containing the GeoIP data for the IP - or None if throw is False, and the IP address wasn’t found in the database.

privex.helpers.geoip.geolocate_ips(*addrs, throw=False) → Generator[Tuple[str, Optional[privex.helpers.geoip.GeoIPResult]], None, None][source]

Same as geolocate_ip() but accepts multiple IP addresses, and returns the results as a generator.

Usage:

>>> for ip, g in geolocate_ips('185.130.44.5', '8.8.4.4', '2a07:e00::333'):
...     print(f"{ip:<20} -> {str(g.city):<15} {str(g.country):<15} ({g.as_number} {g.as_name})")
185.130.44.5         -> Stockholm       Sweden          (210083 Privex Inc.)
8.8.4.4              -> None            United States   (15169 Google LLC)
2a07:e00::333        -> Stockholm       Sweden          (210083 Privex Inc.)
>>> data = dict(geolocate_ips('185.130.44.5', '8.8.4.4', '2a07:e00::333'))
>>> data['8.8.4.4'].country
'United States'
>>> data['2a07:e00::333'].as_name
'Privex Inc.'
Parameters
  • addrs (IP_OR_STR) – One or more IPv4 or IPv6 addresses to geo-locate

  • throw (bool) – (Default: True) If True, will raise GeoIPAddressNotFound if an IP address isn’t found in the GeoIP database. If False, will simply return None if it’s not found.

Raises
  • GeoIPAddressNotFound – When throw is True and one of the addrs can’t be found in a GeoIP database.

  • ValueError – When throw is True and one of the addrs is not a valid IP address.

Return Tuple[str, Optional[GeoIPResult]] res

A generator which returns tuples containing the matching IP address, and the GeoIPResult object containing the GeoIP data for the IP - or None if throw is False, and the IP address wasn’t found in the database.

GeoIP Module Functions

Functions

cleanup([geo_type])

With no arguments, closes and removes GeoIP city + asn + country from thread store.

cleanup_geoip([geo_type])

With no arguments, closes and removes GeoIP city + asn + country from thread store.

geoip_manager([geo_type])

geolocate_ip(addr[, throw])

Looks up the IPv4/IPv6 address addr against GeoIP2 City + ASN, and returns a GeoIPResult containing the GeoIP data.

geolocate_ips(*addrs[, throw])

Same as geolocate_ip() but accepts multiple IP addresses, and returns the results as a generator.

GeoIP Module Classes

Classes

GeoIPResult(country, country_code, city, …)