Skip to content

Commit f496397

Browse files
committed
Added new database models and methods
1 parent e133e5d commit f496397

File tree

4 files changed

+196
-18
lines changed

4 files changed

+196
-18
lines changed

geoip2/database.py

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ def __init__(self, filename, locales=None):
5151
def country(self, ip_address):
5252
"""Get the Country record object for the IP address
5353
54-
:param ip_address: IPv4 or IPv6 address as a string. If no address
55-
is provided, the address that the web service is called from will
56-
be used.
54+
:param ip_address: IPv4 or IPv6 address as a string.
5755
5856
:returns: :py:class:`geoip2.models.Country` object
5957
@@ -64,9 +62,7 @@ def country(self, ip_address):
6462
def city(self, ip_address):
6563
"""Get the City record object for the IP address
6664
67-
:param ip_address: IPv4 or IPv6 address as a string. If no address
68-
is provided, the address that the web service is called from will
69-
be used.
65+
:param ip_address: IPv4 or IPv6 address as a string.
7066
7167
:returns: :py:class:`geoip2.models.City` object
7268
@@ -77,8 +73,7 @@ def city_isp_org(self, ip_address):
7773
"""Get the CityISPOrg record object for the IP address
7874
7975
:param ip_address: IPv4 or IPv6 address as a string. If no address
80-
is provided, the address that the web service is called from will
81-
be used.
76+
is provided.
8277
8378
:returns: :py:class:`geoip2.models.CityISPOrg` object
8479
@@ -89,20 +84,64 @@ def city_isp_org(self, ip_address):
8984
def omni(self, ip_address):
9085
"""Get the Omni record object for the IP address
9186
92-
:param ip_address: IPv4 or IPv6 address as a string. If no address
93-
is provided, the address that the web service is called from will
94-
be used.
87+
:param ip_address: IPv4 or IPv6 address as a string.
9588
9689
:returns: :py:class:`geoip2.models.Omni` object
9790
9891
"""
9992
return self._model_for(geoip2.models.Omni, ip_address)
10093

101-
def _model_for(self, model_class, ip_address):
94+
def connection_type(self, ip_address):
95+
"""Get the ConnectionType object for the IP address
96+
97+
:param ip_address: IPv4 or IPv6 address as a string.
98+
99+
:returns: :py:class:`geoip2.models.ConnectionType` object
100+
101+
"""
102+
record = self._get(ip_address)
103+
return geoip2.models.ConnectionType(ip_address=ip_address,
104+
connection_type=record.get(
105+
'connection_type'))
106+
107+
def domain(self, ip_address):
108+
"""Get the Domain object for the IP address
109+
110+
:param ip_address: IPv4 or IPv6 address as a string.
111+
112+
:returns: :py:class:`geoip2.models.Domain` object
113+
114+
"""
115+
record = self._get(ip_address)
116+
return geoip2.models.Domain(ip_address=ip_address,
117+
domain=record.get('domain'))
118+
119+
def isp_org(self, ip_address):
120+
"""Get the ISPOrg object for the IP address
121+
122+
:param ip_address: IPv4 or IPv6 address as a string.
123+
124+
:returns: :py:class:`geoip2.models.ISPOrg` object
125+
126+
"""
127+
record = self._get(ip_address)
128+
return geoip2.models.ISPOrg(ip_address=ip_address,
129+
autonomous_system_number=record.get(
130+
'autonomous_system_number'),
131+
autonomous_system_organization=record.get(
132+
'autonomous_system_organization'),
133+
isp=record.get('isp'),
134+
organization=record.get('organization'))
135+
136+
def _get(self, ip_address):
102137
record = self._db_reader.get(ip_address)
103138
if record is None:
104139
raise geoip2.errors.AddressNotFoundError(
105140
"The address %s is not in the database." % ip_address)
141+
return record
142+
143+
def _model_for(self, model_class, ip_address):
144+
record = self._get(ip_address)
106145
record.setdefault('traits', {})['ip_address'] = ip_address
107146
return model_class(record, locales=self._locales)
108147

geoip2/models.py

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
class Country(object):
1818

19-
"""Model class for the GeoIP2 Country end point
19+
"""Model class for the GeoIP2 Country Web Service or Database
2020
21-
This class provides the following methods, each of which returns a record
22-
object.
21+
This class provides the following attributes:
2322
2423
.. attribute:: continent
2524
@@ -93,7 +92,7 @@ def __init__(self, raw_response, locales=None):
9392

9493
class City(Country):
9594

96-
"""Model class for the GeoIP2 Precision City end point
95+
"""Model class for the GeoIP2 Precision City Web Service or City Database
9796
9897
.. attribute:: city
9998
@@ -299,3 +298,109 @@ class Omni(CityISPOrg):
299298
:type: :py:class:`geoip2.records.Traits`
300299
301300
"""
301+
302+
303+
class ConnectionType(object):
304+
305+
"""Model class for the GeoIP2 Connection-Type Database
306+
307+
This class provides the following attribute:
308+
309+
.. attribute:: connection_type
310+
311+
The connection type may take the following values:
312+
313+
- Dialup
314+
- Cable/DSL
315+
- Corporate
316+
- Cellular
317+
318+
Additional values may be added in the future.
319+
320+
:type: unicode
321+
322+
.. attribute:: ip_address
323+
324+
The IP address used in the lookup.
325+
326+
:type: unicode
327+
"""
328+
329+
def __init__(self, ip_address=None, connection_type=None):
330+
self.connection_type = connection_type
331+
self.ip_address = ip_address
332+
333+
334+
class Domain(object):
335+
336+
"""Model class for the GeoIP2 Domain Database
337+
338+
This class provides the following attribute:
339+
340+
.. attribute:: domain
341+
342+
The domain associated with the IP address.
343+
344+
:type: unicode
345+
346+
.. attribute:: ip_address
347+
348+
The IP address used in the lookup.
349+
350+
:type: unicode
351+
352+
"""
353+
354+
def __init__(self, ip_address=None, domain=None):
355+
self.domain = domain
356+
self.ip_address = ip_address
357+
358+
359+
class ISPOrg(object):
360+
361+
"""Model class for the GeoIP2 ISP-Org Database
362+
363+
This class provides the following attribute:
364+
365+
.. attribute:: autonomous_system_number
366+
367+
The autonomous system number associated with the IP address.
368+
369+
:type: int
370+
371+
.. attribute:: autonomous_system_organization
372+
373+
The organization associated with the registered autonomous system number
374+
for the IP address.
375+
376+
:type: unicode
377+
378+
.. attribute:: isp
379+
380+
The name of the ISP associated with the IP address.
381+
382+
:type: unicode
383+
384+
.. attribute:: organization
385+
386+
The name of the organization associated with the IP address.
387+
388+
:type: unicode
389+
390+
.. attribute:: ip_address
391+
392+
The IP address used in the lookup.
393+
394+
:type: unicode
395+
"""
396+
397+
def __init__(self, ip_address=None,
398+
autonomous_system_number=None,
399+
autonomous_system_organization=None,
400+
isp=None,
401+
organization=None):
402+
self.autonomous_system_number = autonomous_system_number
403+
self.autonomous_system_organization = autonomous_system_organization
404+
self.isp = isp
405+
self.organization = organization
406+
self.ip_address = ip_address

tests/database_test.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def test_has_ip_address(self):
4040
reader = geoip2.database.Reader(
4141
'tests/data/test-data/GeoIP2-City-Test.mmdb')
4242
record = reader.country('81.2.69.160')
43-
record = reader.omni('81.2.69.160')
4443
self.assertEqual(record.traits.ip_address, '81.2.69.160')
4544
reader.close()
4645

@@ -61,3 +60,38 @@ def test_invalid_address(self):
6160
"IPv4 or IPv6 address"):
6261
reader.city('invalid')
6362
reader.close()
63+
64+
def test_connection_type(self):
65+
reader = geoip2.database.Reader(
66+
'tests/data/test-data/GeoIP2-Connection-Type-Test.mmdb')
67+
ip_address = '1.0.1.0'
68+
69+
record = reader.connection_type(ip_address)
70+
self.assertEqual(record.connection_type, 'Cable/DSL')
71+
self.assertEqual(record.ip_address, ip_address)
72+
reader.close()
73+
74+
def test_domain(self):
75+
reader = geoip2.database.Reader(
76+
'tests/data/test-data/GeoIP2-Domain-Test.mmdb')
77+
78+
ip_address = '1.2.0.0'
79+
record = reader.domain(ip_address)
80+
self.assertEqual(record.domain, 'maxmind.com')
81+
self.assertEqual(record.ip_address, ip_address)
82+
83+
reader.close()
84+
85+
def test_isp_org(self):
86+
reader = geoip2.database.Reader(
87+
'tests/data/test-data/GeoIP2-ISP-Org-Test.mmdb')
88+
89+
ip_address = '2001:1700::'
90+
record = reader.isp_org(ip_address)
91+
self.assertEqual(record.autonomous_system_number, 6730)
92+
self.assertEqual(record.autonomous_system_organization,
93+
'Sunrise Communications AG')
94+
# XXX - Add org/isp when available
95+
self.assertEqual(record.ip_address, ip_address)
96+
97+
reader.close()

0 commit comments

Comments
 (0)