Skip to content
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ before_install:
- "if [[ $RUN_SNYK && $SNYK_TOKEN ]]; then sudo apt-get install -y nodejs; npm install -g snyk; fi"
install:
- pip install -r requirements.txt
- pip install requests_mock coveralls
- pip install mocket coveralls
- |
if [[ $RUN_LINTER ]]; then
pip install --upgrade pylint black mypy
Expand Down
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ History

* IMPORTANT: Python 2.7 and 3.5 support has been dropped. Python 3.6 or greater
is required.
* Asyncio support has been added for web service requests. To make async
requests, use ``geoip.webservice.AsyncClient``.
* ``geoip.webservice.Client`` now provides a ``close()`` method and associated
context managers to be used in ``with`` statements.
* Type hints have been added.
* The attributes ``postal_code`` and ``postal_confidence`` have been removed
from ``geoip2.record.Location``. These would previously always be ``None``.
* ``user_id`` is no longer supported as a named argument for the constructor
on ``geoip2.webservice.Client``. Use ``account_id`` or a positional
parameter instead.
* For both ``Client`` and ``AsyncClient`` requests, the default timeout is
now 60 seconds.

3.0.0 (2019-12-20)
++++++++++++++++++
Expand Down
197 changes: 117 additions & 80 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ each of which represents part of the data returned by the web service.

If the request fails, the client class throws an exception.

Web Service Example
-------------------
Sync Web Service Example
------------------------

.. code-block:: pycon

Expand All @@ -67,37 +67,82 @@ Web Service Example
>>> # This creates a Client object that can be reused across requests.
>>> # Replace "42" with your account ID and "license_key" with your license
>>> # key.
>>> client = geoip2.webservice.Client(42, 'license_key')
>>> with geoip2.webservice.Client(42, 'license_key') as client:
>>>
>>> # Replace "insights" with the method corresponding to the web service
>>> # that you are using, e.g., "country", "city".
>>> response = client.insights('203.0.113.0')
>>>
>>> response.country.iso_code
'US'
>>> response.country.name
'United States'
>>> response.country.names['zh-CN']
u'美国'
>>>
>>> response.subdivisions.most_specific.name
'Minnesota'
>>> response.subdivisions.most_specific.iso_code
'MN'
>>>
>>> response.city.name
'Minneapolis'
>>>
>>> response.postal.code
'55455'
>>>
>>> response.location.latitude
44.9733
>>> response.location.longitude
-93.2323
>>>
>>> response.traits.network
IPv4Network('203.0.113.0/32')

Async Web Service Example
------------------------

.. code-block:: pycon

>>> import geoip2.webservice
>>>
>>> # This creates an AsyncClient object that can be reused across
>>> # requests on the running event loop. If you are using multiple event
>>> # loops, you must ensure the object is not used on another loop.
>>> #
>>> # Replace "42" with your account ID and "license_key" with your license
>>> # key.
>>> async with geoip2.webservice.AsyncClient(42, 'license_key') as client:
>>>
>>> # Replace "insights" with the method corresponding to the web service
>>> # that you are using, e.g., "country", "city".
>>> response = client.insights('128.101.101.101')
>>> # Replace "insights" with the method corresponding to the web service
>>> # that you are using, e.g., "country", "city".
>>> response = await client.insights('203.0.113.0')
>>>
>>> response.country.iso_code
>>> response.country.iso_code
'US'
>>> response.country.name
>>> response.country.name
'United States'
>>> response.country.names['zh-CN']
>>> response.country.names['zh-CN']
u'美国'
>>>
>>> response.subdivisions.most_specific.name
>>> response.subdivisions.most_specific.name
'Minnesota'
>>> response.subdivisions.most_specific.iso_code
>>> response.subdivisions.most_specific.iso_code
'MN'
>>>
>>> response.city.name
>>> response.city.name
'Minneapolis'
>>>
>>> response.postal.code
>>> response.postal.code
'55455'
>>>
>>> response.location.latitude
>>> response.location.latitude
44.9733
>>> response.location.longitude
>>> response.location.longitude
-93.2323
>>>
>>> response.traits.network
IPv4Network('128.101.101.101/32')
>>> response.traits.network
IPv4Network('203.0.113.0/32')

Web Service Client Exceptions
-----------------------------
Expand Down Expand Up @@ -131,39 +176,37 @@ City Database
>>>
>>> # This creates a Reader object. You should use the same object
>>> # across multiple requests as creation of it is expensive.
>>> reader = geoip2.database.Reader('/path/to/GeoLite2-City.mmdb')
>>> with geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') as reader:
>>>
>>> # Replace "city" with the method corresponding to the database
>>> # that you are using, e.g., "country".
>>> response = reader.city('128.101.101.101')
>>> # Replace "city" with the method corresponding to the database
>>> # that you are using, e.g., "country".
>>> response = reader.city('203.0.113.0')
>>>
>>> response.country.iso_code
>>> response.country.iso_code
'US'
>>> response.country.name
>>> response.country.name
'United States'
>>> response.country.names['zh-CN']
>>> response.country.names['zh-CN']
u'美国'
>>>
>>> response.subdivisions.most_specific.name
>>> response.subdivisions.most_specific.name
'Minnesota'
>>> response.subdivisions.most_specific.iso_code
>>> response.subdivisions.most_specific.iso_code
'MN'
>>>
>>> response.city.name
>>> response.city.name
'Minneapolis'
>>>
>>> response.postal.code
>>> response.postal.code
'55455'
>>>
>>> response.location.latitude
>>> response.location.latitude
44.9733
>>> response.location.longitude
>>> response.location.longitude
-93.2323
>>>
>>> response.traits.network
IPv4Network('128.101.101.0/24')
>>>
>>> reader.close()
>>> response.traits.network
IPv4Network('203.0.113.0/24')

Anonymous IP Database
^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -174,25 +217,24 @@ Anonymous IP Database
>>>
>>> # This creates a Reader object. You should use the same object
>>> # across multiple requests as creation of it is expensive.
>>> reader = geoip2.database.Reader('/path/to/GeoIP2-Anonymous-IP.mmdb')
>>> with geoip2.database.Reader('/path/to/GeoIP2-Anonymous-IP.mmdb') as reader:
>>>
>>> response = reader.anonymous_ip('85.25.43.84')
>>> response = reader.anonymous_ip('203.0.113.0')
>>>
>>> response.is_anonymous
>>> response.is_anonymous
True
>>> response.is_anonymous_vpn
>>> response.is_anonymous_vpn
False
>>> response.is_hosting_provider
>>> response.is_hosting_provider
False
>>> response.is_public_proxy
>>> response.is_public_proxy
False
>>> response.is_tor_exit_node
>>> response.is_tor_exit_node
True
>>> response.ip_address
'85.25.43.84'
>>> response.network
IPv4Network('85.25.43.0/24')
>>> reader.close()
>>> response.ip_address
'203.0.113.0'
>>> response.network
IPv4Network('203.0.113.0/24')

ASN Database
^^^^^^^^^^^^
Expand All @@ -204,11 +246,15 @@ ASN Database
>>> # This creates a Reader object. You should use the same object
>>> # across multiple requests as creation of it is expensive.
>>> with geoip2.database.Reader('/path/to/GeoLite2-ASN.mmdb') as reader:
>>> response = reader.asn('1.128.0.0')
>>> response = reader.asn('203.0.113.0')
>>> response.autonomous_system_number
1221
>>> response.autonomous_system_organization
'Telstra Pty Ltd'
>>> response.ip_address
'203.0.113.0'
>>> response.network
IPv4Network('203.0.113.0/24')

Connection-Type Database
^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -219,17 +265,14 @@ Connection-Type Database
>>>
>>> # This creates a Reader object. You should use the same object
>>> # across multiple requests as creation of it is expensive.
>>> reader = geoip2.database.Reader('/path/to/GeoIP2-Connection-Type.mmdb')
>>>
>>> response = reader.connection_type('128.101.101.101')
>>>
>>> response.connection_type
>>> with geoip2.database.Reader('/path/to/GeoIP2-Connection-Type.mmdb') as reader:
>>> response = reader.connection_type('203.0.113.0')
>>> response.connection_type
'Corporate'
>>> response.ip_address
'128.101.101.101'
>>> response.network
IPv4Network('128.101.101.101/24')
>>> reader.close()
>>> response.ip_address
'203.0.113.0'
>>> response.network
IPv4Network('203.0.113.0/24')


Domain Database
Expand All @@ -241,15 +284,12 @@ Domain Database
>>>
>>> # This creates a Reader object. You should use the same object
>>> # across multiple requests as creation of it is expensive.
>>> reader = geoip2.database.Reader('/path/to/GeoIP2-Domain.mmdb')
>>>
>>> response = reader.domain('128.101.101.101')
>>>
>>> response.domain
>>> with geoip2.database.Reader('/path/to/GeoIP2-Domain.mmdb') as reader:
>>> response = reader.domain('203.0.113.0')
>>> response.domain
'umn.edu'
>>> response.ip_address
'128.101.101.101'
>>> reader.close()
>>> response.ip_address
'203.0.113.0'

Enterprise Database
^^^^^^^^^^^^^^^^^^^
Expand All @@ -263,7 +303,7 @@ Enterprise Database
>>> with geoip2.database.Reader('/path/to/GeoIP2-Enterprise.mmdb') as reader:
>>>
>>> # Use the .enterprise method to do a lookup in the Enterprise database
>>> response = reader.enterprise('128.101.101.101')
>>> response = reader.enterprise('203.0.113.0')
>>>
>>> response.country.confidence
99
Expand Down Expand Up @@ -297,7 +337,7 @@ Enterprise Database
-93.2323
>>>
>>> response.traits.network
IPv4Network('128.101.101.0/24')
IPv4Network('203.0.113.0/24')


ISP Database
Expand All @@ -309,23 +349,20 @@ ISP Database
>>>
>>> # This creates a Reader object. You should use the same object
>>> # across multiple requests as creation of it is expensive.
>>> reader = geoip2.database.Reader('/path/to/GeoIP2-ISP.mmdb')
>>>
>>> response = reader.isp('1.128.0.0')
>>>
>>> response.autonomous_system_number
>>> with geoip2.database.Reader('/path/to/GeoIP2-ISP.mmdb') as reader:
>>> response = reader.isp('203.0.113.0')
>>> response.autonomous_system_number
1221
>>> response.autonomous_system_organization
>>> response.autonomous_system_organization
'Telstra Pty Ltd'
>>> response.isp
>>> response.isp
'Telstra Internet'
>>> response.organization
>>> response.organization
'Telstra Internet'
>>> response.ip_address
'1.128.0.0'
>>> response.network
IPv4Network('1.128.0.0/16')
>>> reader.close()
>>> response.ip_address
'203.0.113.0'
>>> response.network
IPv4Network('203.0.113.0/24')

Database Reader Exceptions
--------------------------
Expand Down
Loading