Skip to content

Commit 90b8aae

Browse files
committed
Check that the database is of the right type before doing a lookup
1 parent 63e4500 commit 90b8aae

File tree

4 files changed

+55
-41
lines changed

4 files changed

+55
-41
lines changed

HISTORY.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
History
44
-------
55

6+
0.7.0 (2014-09-XX)
7+
++++++++++++++++++
8+
9+
- The ``geoip2.database.Reader`` lookup methods (e.g., ``city()``, ``isp()``)
10+
now raise a ``TypeError`` if they are used with a database that does not
11+
match the method. In particular, doing a ``city()`` lookup on a GeoIP2
12+
Country database will result in an error and vice versa.
13+
- A ``metadata()`` method has been added to the ``geoip2.database.Reader``
14+
class. This returns a ``maxminddb.reader.Metadata`` object with information
15+
about the database.
16+
617
0.6.0 (2014-07-22)
718
++++++++++++++++++
819

geoip2/database.py

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
======================
55
66
"""
7+
import inspect
8+
79
import geoip2
810
import geoip2.models
911
import geoip2.errors
@@ -53,7 +55,9 @@ def country(self, ip_address):
5355
5456
"""
5557

56-
return self._model_for(geoip2.models.Country, ip_address)
58+
return self._model_for(geoip2.models.Country,
59+
['GeoIP2-Country', 'GeoLite2-Country'],
60+
ip_address)
5761

5862
def city(self, ip_address):
5963
"""Get the City object for the IP address
@@ -63,33 +67,9 @@ def city(self, ip_address):
6367
:returns: :py:class:`geoip2.models.City` object
6468
6569
"""
66-
return self._model_for(geoip2.models.City, ip_address)
67-
68-
def city_isp_org(self, ip_address):
69-
"""Get the City object for the IP address
70-
71-
:param ip_address: IPv4 or IPv6 address as a string. If no address
72-
is provided.
73-
74-
:returns: :py:class:`geoip2.models.City` object
75-
76-
.. deprecated:: 0.6.0
77-
Use :py:method:`city` instead.
78-
"""
79-
80-
return self.city(ip_address)
81-
82-
def omni(self, ip_address):
83-
"""Get the Insights object for the IP address
84-
85-
:param ip_address: IPv4 or IPv6 address as a string.
86-
87-
:returns: :py:class:`geoip2.models.Insights` object
88-
89-
.. deprecated:: 0.6.0
90-
Use :py:method:`city` instead.
91-
"""
92-
return self._model_for(geoip2.models.Insights, ip_address)
70+
return self._model_for(geoip2.models.City,
71+
['GeoIP2-City', 'GeoLite2-City'],
72+
ip_address)
9373

9474
def connection_type(self, ip_address):
9575
"""Get the ConnectionType object for the IP address
@@ -99,7 +79,9 @@ def connection_type(self, ip_address):
9979
:returns: :py:class:`geoip2.models.ConnectionType` object
10080
10181
"""
102-
return self._flat_model_for(geoip2.models.ConnectionType, ip_address)
82+
return self._flat_model_for(geoip2.models.ConnectionType,
83+
['GeoIP2-Connection-Type'],
84+
ip_address)
10385

10486
def domain(self, ip_address):
10587
"""Get the Domain object for the IP address
@@ -109,7 +91,9 @@ def domain(self, ip_address):
10991
:returns: :py:class:`geoip2.models.Domain` object
11092
11193
"""
112-
return self._flat_model_for(geoip2.models.Domain, ip_address)
94+
return self._flat_model_for(geoip2.models.Domain,
95+
['GeoIP2-Domain'],
96+
ip_address)
11397

11498
def isp(self, ip_address):
11599
"""Get the ISP object for the IP address
@@ -119,25 +103,35 @@ def isp(self, ip_address):
119103
:returns: :py:class:`geoip2.models.ISP` object
120104
121105
"""
122-
return self._flat_model_for(geoip2.models.ISP, ip_address)
123-
124-
def _get(self, ip_address):
106+
return self._flat_model_for(geoip2.models.ISP,
107+
['GeoIP2-ISP'],
108+
ip_address)
109+
110+
def _get(self, types, ip_address):
111+
if not self.metadata().database_type in types:
112+
caller = inspect.stack()[2][3]
113+
raise TypeError("The %s method cannot be used with the "
114+
"%s database" %
115+
(caller, self.metadata().database_type))
125116
record = self._db_reader.get(ip_address)
126117
if record is None:
127118
raise geoip2.errors.AddressNotFoundError(
128119
"The address %s is not in the database." % ip_address)
129120
return record
130121

131-
def _model_for(self, model_class, ip_address):
132-
record = self._get(ip_address)
122+
def _model_for(self, model_class, types, ip_address):
123+
record = self._get(types, ip_address)
133124
record.setdefault('traits', {})['ip_address'] = ip_address
134125
return model_class(record, locales=self._locales)
135126

136-
def _flat_model_for(self, model_class, ip_address):
137-
record = self._get(ip_address)
127+
def _flat_model_for(self, model_class, types, ip_address):
128+
record = self._get(types, ip_address)
138129
record['ip_address'] = ip_address
139130
return model_class(record)
140131

132+
def metadata(self):
133+
return self._db_reader.metadata()
134+
141135
def close(self):
142136
"""Closes the GeoIP2 database"""
143137

tests/database_test.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def test_default_locale(self):
2929

3030
def test_language_list(self):
3131
reader = geoip2.database.Reader(
32-
'tests/data/test-data/GeoIP2-City-Test.mmdb',
32+
'tests/data/test-data/GeoIP2-Country-Test.mmdb',
3333
['xx', 'ru', 'pt-BR', 'es', 'en'])
3434
record = reader.country('81.2.69.160')
3535

@@ -38,7 +38,7 @@ def test_language_list(self):
3838

3939
def test_has_ip_address(self):
4040
reader = geoip2.database.Reader(
41-
'tests/data/test-data/GeoIP2-City-Test.mmdb')
41+
'tests/data/test-data/GeoIP2-Country-Test.mmdb')
4242
record = reader.country('81.2.69.160')
4343
self.assertEqual(record.traits.ip_address, '81.2.69.160')
4444
reader.close()
@@ -49,7 +49,16 @@ def test_unknown_address(self):
4949
with self.assertRaisesRegex(geoip2.errors.AddressNotFoundError,
5050
'The address 10.10.10.10 is not in the '
5151
'database.'):
52-
reader.city_isp_org('10.10.10.10')
52+
reader.city('10.10.10.10')
53+
reader.close()
54+
55+
def test_wrong_database(self):
56+
reader = geoip2.database.Reader(
57+
'tests/data/test-data/GeoIP2-City-Test.mmdb')
58+
with self.assertRaisesRegex(TypeError,
59+
'The country method cannot be used with '
60+
'the GeoIP2-City database'):
61+
reader.country('1.1.1.1')
5362
reader.close()
5463

5564
def test_invalid_address(self):

0 commit comments

Comments
 (0)