Skip to content

Commit 37d6b52

Browse files
committed
Merge pull request maxmind#17 from maxmind/greg/anonymous-ip
Add support for Anonymous IP databases
2 parents 4846564 + 1ec5a90 commit 37d6b52

File tree

5 files changed

+108
-1
lines changed

5 files changed

+108
-1
lines changed

README.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,33 @@ City Database
151151
-93.2323
152152
>>> reader.close()
153153
154+
Anonymous IP Database
155+
^^^^^^^^^^^^^^^^^^^^^
156+
157+
.. code-block:: pycon
158+
159+
>>> import geoip2.database
160+
>>>
161+
>>> # This creates a Reader object. You should use the same object
162+
>>> # across multiple requests as creation of it is expensive.
163+
>>> reader = geoip2.database.Reader('/path/to/GeoIP2-Anonymous-IP.mmdb')
164+
>>>
165+
>>> response = reader.anonymous_ip('85.25.43.84')
166+
>>>
167+
>>> response.is_anonymous
168+
True
169+
>>> response.is_anonymous_vpn
170+
False
171+
>>> response.is_hosting_provider
172+
False
173+
>>> response.is_public_proxy
174+
False
175+
>>> response.is_tor_exit_node
176+
True
177+
>>> response.ip_address
178+
'128.101.101.101'
179+
>>> reader.close()
180+
154181
Connection-Type Database
155182
^^^^^^^^^^^^^^^^^^^^^^^^
156183

geoip2/database.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ def city(self, ip_address):
6767
"""
6868
return self._model_for(geoip2.models.City, 'City', ip_address)
6969

70+
def anonymous_ip(self, ip_address):
71+
"""Get the AnonymousIP object for the IP address
72+
73+
:param ip_address: IPv4 or IPv6 address as a string.
74+
75+
:returns: :py:class:`geoip2.models.AnonymousIP` object
76+
77+
"""
78+
return self._flat_model_for(geoip2.models.AnonymousIP,
79+
'GeoIP2-Anonymous-IP',
80+
ip_address)
81+
7082
def connection_type(self, ip_address):
7183
"""Get the ConnectionType object for the IP address
7284

geoip2/models.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,60 @@ def __repr__(self):
254254
data=str(self.raw))
255255

256256

257+
class AnonymousIP(SimpleModel):
258+
259+
"""Model class for the GeoIP2 Anonymous IP
260+
261+
This class provides the following attribute:
262+
263+
.. attribute:: is_anonymous
264+
265+
This is true if the IP address belongs to any sort of anonymous network.
266+
267+
:type: bool
268+
269+
.. attribute:: is_anonymous_vpn
270+
271+
This is true if the IP address belongs to an anonymous VPN system.
272+
273+
:type: bool
274+
275+
.. attribute:: is_hosting_provider
276+
277+
This is true if the IP address belongs to a hosting provider.
278+
279+
:type: bool
280+
281+
.. attribute:: is_public_proxy
282+
283+
This is true if the IP address belongs to a public proxy.
284+
285+
:type: bool
286+
287+
.. attribute:: is_tor_exit_node
288+
289+
This is true if the IP address is a Tor exit node.
290+
291+
:type: bool
292+
293+
.. attribute:: ip_address
294+
295+
The IP address used in the lookup.
296+
297+
:type: unicode
298+
"""
299+
300+
def __init__(self, raw):
301+
self.is_anonymous = raw.get('is_anonymous', False)
302+
self.is_anonymous_vpn = raw.get('is_anonymous_vpn', False)
303+
self.is_hosting_provider = raw.get('is_hosting_provider', False)
304+
self.is_public_proxy = raw.get('is_public_proxy', False)
305+
self.is_tor_exit_node = raw.get('is_tor_exit_node', False)
306+
307+
self.ip_address = raw.get('ip_address')
308+
self.raw = raw
309+
310+
257311
class ConnectionType(SimpleModel):
258312

259313
"""Model class for the GeoIP2 Connection-Type

tests/database_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,20 @@ def test_invalid_address(self):
7171
reader.city('invalid')
7272
reader.close()
7373

74+
def test_anonymous_ip(self):
75+
reader = geoip2.database.Reader(
76+
'tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb')
77+
ip_address = '1.2.0.1'
78+
79+
record = reader.anonymous_ip(ip_address)
80+
self.assertEqual(record.is_anonymous, True)
81+
self.assertEqual(record.is_anonymous_vpn, True)
82+
self.assertEqual(record.is_hosting_provider, False)
83+
self.assertEqual(record.is_public_proxy, False)
84+
self.assertEqual(record.is_tor_exit_node, False)
85+
self.assertEqual(record.ip_address, ip_address)
86+
reader.close()
87+
7488
def test_connection_type(self):
7589
reader = geoip2.database.Reader(
7690
'tests/data/test-data/GeoIP2-Connection-Type-Test.mmdb')

0 commit comments

Comments
 (0)