def geolocate(url): """ Finds data about url in geolocation database and transfers it mongodb :param url: url to lacate :return: geolocation_id """ from geoip2.database import Reader from geoip2.webservice import Client from geoip2.errors import GeoIP2Error, HTTPError geolocation_data = dict() try: ip = url_to_ip(url) response = None if config.GEOIP2_WEB_SERVICE_USER_ID and config.GEOIP2_WEB_SERVICE_LICENSE_KEY \ and config.GEOIP2_WEB_SERVICE_TYPE: client = Client(config.GEOIP2_WEB_SERVICE_USER_ID, config.GEOIP2_WEB_SERVICE_LICENSE_KEY) if config.GEOIP2_WEB_SERVICE_TYPE == 'country': response = client.country(ip).country elif config.GEOIP2_WEB_SERVICE_TYPE == 'city': response = client.city(ip).city elif config.GEOIP2_WEB_SERVICE_TYPE == 'insights': response = client.insights(ip).insights elif config.GEOIP2_DATABASE_PATH and config.GEOIP2_DATABASE_TYPE: reader = Reader(config.GEOIP2_DATABASE_PATH) if config.GEOIP2_DATABASE_TYPE == 'country': response = reader.country(ip).country if config.GEOIP2_DATABASE_TYPE == 'city': response = reader.city(ip).city else: reader = Reader( '/opt/project/worker/utils/geoloc_databases/GeoLite2-City.mmdb' ) response = reader.city(ip) for name in dir(response): value = getattr(response, name) if not name.startswith('_') and not type(value) == dict: geolocation_data[name] = value.__dict__ except (GeoIP2Error, HTTPError) as error: geolocation_data = {'_error': str(error)} finally: duplicate = db.geolocation.find_one(geolocation_data) if duplicate: return duplicate['_id'] geolocation_id = db.geolocation.insert_one(geolocation_data) return str(geolocation_id.inserted_id)
class TestClient(unittest.TestCase): def setUp(self): self.client = Client(42, 'abcdef123456') base_uri = 'https://geoip.maxmind.com/geoip/v2.1/' country = { 'continent': {'code': 'NA', 'geoname_id': 42, 'names': {'en': 'North America'}}, 'country': { 'geoname_id': 1, 'iso_code': 'US', 'names': {'en': 'United States of America'} }, 'maxmind': {'queries_remaining': 11}, 'traits': {'ip_address': '1.2.3.4'}, } def _content_type(self, endpoint): return ('application/vnd.maxmind.com-' + endpoint + '+json; charset=UTF-8; version=1.0') @requests_mock.mock() def test_country_ok(self, mock): mock.get(self.base_uri + 'country/1.2.3.4', json=self.country, status_code=200, headers={'Content-Type': self._content_type('country')}) country = self.client.country('1.2.3.4') self.assertEqual( type(country), geoip2.models.Country, 'return value of client.country') self.assertEqual(country.continent.geoname_id, 42, 'continent geoname_id is 42') self.assertEqual(country.continent.code, 'NA', 'continent code is NA') self.assertEqual(country.continent.name, 'North America', 'continent name is North America') self.assertEqual(country.country.geoname_id, 1, 'country geoname_id is 1') self.assertEqual(country.country.iso_code, 'US', 'country iso_code is US') self.assertEqual(country.country.names, {'en': 'United States of America'}, 'country names') self.assertEqual(country.country.name, 'United States of America', 'country name is United States of America') self.assertEqual(country.maxmind.queries_remaining, 11, 'queries_remaining is 11') self.assertEqual(country.raw, self.country, 'raw response is correct') @requests_mock.mock() def test_me(self, mock): mock.get(self.base_uri + 'country/me', json=self.country, status_code=200, headers={'Content-Type': self._content_type('country')}) implicit_me = self.client.country() self.assertEqual( type(implicit_me), geoip2.models.Country, 'country() returns Country object') explicit_me = self.client.country() self.assertEqual( type(explicit_me), geoip2.models.Country, 'country(\'me\') returns Country object') @requests_mock.mock() def test_200_error(self, mock): mock.get(self.base_uri + 'country/1.1.1.1', status_code=200, headers={'Content-Type': self._content_type('country')}) with self.assertRaisesRegex(GeoIP2Error, 'could not decode the response as JSON'): self.client.country('1.1.1.1') def test_bad_ip_address(self): with self.assertRaisesRegex(ValueError, "'1.2.3' does not appear to be an IPv4 " "or IPv6 address"): self.client.country('1.2.3') @requests_mock.mock() def test_no_body_error(self, mock): mock.get(self.base_uri + 'country/' + '1.2.3.7', text='', status_code=400, headers={'Content-Type': self._content_type('country')}) with self.assertRaisesRegex( HTTPError, 'Received a 400 error for .* with no body'): self.client.country('1.2.3.7') @requests_mock.mock() def test_weird_body_error(self, mock): mock.get(self.base_uri + 'country/' + '1.2.3.8', text='{"wierd": 42}', status_code=400, headers={'Content-Type': self._content_type('country')}) with self.assertRaisesRegex(HTTPError, 'Response contains JSON but it does not ' 'specify code or error keys'): self.client.country('1.2.3.8') @requests_mock.mock() def test_bad_body_error(self, mock): mock.get(self.base_uri + 'country/' + '1.2.3.9', text='bad body', status_code=400, headers={'Content-Type': self._content_type('country')}) with self.assertRaisesRegex( HTTPError, 'it did not include the expected JSON body'): self.client.country('1.2.3.9') @requests_mock.mock() def test_500_error(self, mock): mock.get(self.base_uri + 'country/' + '1.2.3.10', status_code=500) with self.assertRaisesRegex(HTTPError, 'Received a server error \(500\) for'): self.client.country('1.2.3.10') @requests_mock.mock() def test_300_error(self, mock): mock.get(self.base_uri + 'country/' + '1.2.3.11', status_code=300, headers={'Content-Type': self._content_type('country')}) with self.assertRaisesRegex(HTTPError, 'Received a very surprising HTTP status ' '\(300\) for'): self.client.country('1.2.3.11') @requests_mock.mock() def test_ip_address_required(self, mock): self._test_error(mock, 400, 'IP_ADDRESS_REQUIRED', InvalidRequestError) @requests_mock.mock() def test_ip_address_not_found(self, mock): self._test_error(mock, 404, 'IP_ADDRESS_NOT_FOUND', AddressNotFoundError) @requests_mock.mock() def test_ip_address_reserved(self, mock): self._test_error(mock, 400, 'IP_ADDRESS_RESERVED', AddressNotFoundError) @requests_mock.mock() def test_permission_required(self, mock): self._test_error(mock, 403, 'PERMISSION_REQUIRED', PermissionRequiredError) @requests_mock.mock() def test_auth_invalid(self, mock): self._test_error(mock, 400, 'AUTHORIZATION_INVALID', AuthenticationError) @requests_mock.mock() def test_license_key_required(self, mock): self._test_error(mock, 401, 'LICENSE_KEY_REQUIRED', AuthenticationError) @requests_mock.mock() def test_user_id_required(self, mock): self._test_error(mock, 401, 'USER_ID_REQUIRED', AuthenticationError) @requests_mock.mock() def test_user_id_unkown(self, mock): self._test_error(mock, 401, 'USER_ID_UNKNOWN', AuthenticationError) @requests_mock.mock() def test_out_of_queries_error(self, mock): self._test_error(mock, 402, 'OUT_OF_QUERIES', OutOfQueriesError) def _test_error(self, mock, status, error_code, error_class): msg = 'Some error message' body = {'error': msg, 'code': error_code} mock.get(self.base_uri + 'country/1.2.3.18', json=body, status_code=status, headers={'Content-Type': self._content_type('country')}) with self.assertRaisesRegex(error_class, msg): self.client.country('1.2.3.18') @requests_mock.mock() def test_unknown_error(self, mock): msg = 'Unknown error type' ip = '1.2.3.19' body = {'error': msg, 'code': 'UNKNOWN_TYPE'} mock.get(self.base_uri + 'country/' + ip, json=body, status_code=400, headers={'Content-Type': self._content_type('country')}) with self.assertRaisesRegex(InvalidRequestError, msg): self.client.country(ip) @requests_mock.mock() def test_request(self, mock): mock.get(self.base_uri + 'country/' + '1.2.3.4', json=self.country, status_code=200, headers={'Content-Type': self._content_type('country')}) self.client.country('1.2.3.4') request = mock.request_history[-1] self.assertEqual(request.path, '/geoip/v2.1/country/1.2.3.4', 'correct URI is used') self.assertEqual(request.headers['Accept'], 'application/json', 'correct Accept header') self.assertRegex(request.headers['User-Agent'], '^GeoIP2 Python Client v', 'Correct User-Agent') self.assertEqual(request.headers['Authorization'], 'Basic NDI6YWJjZGVmMTIzNDU2', 'correct auth') @requests_mock.mock() def test_city_ok(self, mock): mock.get(self.base_uri + 'city/' + '1.2.3.4', json=self.country, status_code=200, headers={'Content-Type': self._content_type('city')}) city = self.client.city('1.2.3.4') self.assertEqual( type(city), geoip2.models.City, 'return value of client.city') @requests_mock.mock() def test_insights_ok(self, mock): mock.get(self.base_uri + 'insights/1.2.3.4', json=self.country, status_code=200, headers={'Content-Type': self._content_type('country')}) insights = self.client.insights('1.2.3.4') self.assertEqual( type(insights), geoip2.models.Insights, 'return value of client.insights')
class TestClient(unittest.TestCase): def setUp(self): self.client = Client(42, "abcdef123456") base_uri = "https://geoip.maxmind.com/geoip/v2.1/" country = { "continent": { "code": "NA", "geoname_id": 42, "names": { "en": "North America" } }, "country": { "geoname_id": 1, "iso_code": "US", "names": { "en": "United States of America" }, }, "maxmind": { "queries_remaining": 11 }, "registered_country": { "geoname_id": 2, "is_in_european_union": True, "iso_code": "DE", "names": { "en": "Germany" }, }, "traits": { "ip_address": "1.2.3.4", "network": "1.2.3.0/24" }, } # this is not a comprehensive representation of the # JSON from the server insights = copy.deepcopy(country) insights["traits"]["user_count"] = 2 insights["traits"]["static_ip_score"] = 1.3 def _content_type(self, endpoint): return ("application/vnd.maxmind.com-" + endpoint + "+json; charset=UTF-8; version=1.0") @requests_mock.mock() def test_country_ok(self, mock): mock.get( self.base_uri + "country/1.2.3.4", json=self.country, status_code=200, headers={"Content-Type": self._content_type("country")}, ) country = self.client.country("1.2.3.4") self.assertEqual(type(country), geoip2.models.Country, "return value of client.country") self.assertEqual(country.continent.geoname_id, 42, "continent geoname_id is 42") self.assertEqual(country.continent.code, "NA", "continent code is NA") self.assertEqual(country.continent.name, "North America", "continent name is North America") self.assertEqual(country.country.geoname_id, 1, "country geoname_id is 1") self.assertIs( country.country.is_in_european_union, False, "country is_in_european_union is False", ) self.assertEqual(country.country.iso_code, "US", "country iso_code is US") self.assertEqual(country.country.names, {"en": "United States of America"}, "country names") self.assertEqual( country.country.name, "United States of America", "country name is United States of America", ) self.assertEqual(country.maxmind.queries_remaining, 11, "queries_remaining is 11") self.assertIs( country.registered_country.is_in_european_union, True, "registered_country is_in_european_union is True", ) self.assertEqual(country.traits.network, compat_ip_network("1.2.3.0/24"), "network") self.assertEqual(country.raw, self.country, "raw response is correct") @requests_mock.mock() def test_me(self, mock): mock.get( self.base_uri + "country/me", json=self.country, status_code=200, headers={"Content-Type": self._content_type("country")}, ) implicit_me = self.client.country() self.assertEqual(type(implicit_me), geoip2.models.Country, "country() returns Country object") explicit_me = self.client.country() self.assertEqual( type(explicit_me), geoip2.models.Country, "country('me') returns Country object", ) @requests_mock.mock() def test_200_error(self, mock): mock.get( self.base_uri + "country/1.1.1.1", status_code=200, headers={"Content-Type": self._content_type("country")}, ) with self.assertRaisesRegex(GeoIP2Error, "could not decode the response as JSON"): self.client.country("1.1.1.1") def test_bad_ip_address(self): with self.assertRaisesRegex( ValueError, "'1.2.3' does not appear to be an IPv4 " "or IPv6 address"): self.client.country("1.2.3") @requests_mock.mock() def test_no_body_error(self, mock): mock.get( self.base_uri + "country/" + "1.2.3.7", text="", status_code=400, headers={"Content-Type": self._content_type("country")}, ) with self.assertRaisesRegex( HTTPError, "Received a 400 error for .* with no body"): self.client.country("1.2.3.7") @requests_mock.mock() def test_weird_body_error(self, mock): mock.get( self.base_uri + "country/" + "1.2.3.8", text='{"wierd": 42}', status_code=400, headers={"Content-Type": self._content_type("country")}, ) with self.assertRaisesRegex( HTTPError, "Response contains JSON but it does not " "specify code or error keys", ): self.client.country("1.2.3.8") @requests_mock.mock() def test_bad_body_error(self, mock): mock.get( self.base_uri + "country/" + "1.2.3.9", text="bad body", status_code=400, headers={"Content-Type": self._content_type("country")}, ) with self.assertRaisesRegex( HTTPError, "it did not include the expected JSON body"): self.client.country("1.2.3.9") @requests_mock.mock() def test_500_error(self, mock): mock.get(self.base_uri + "country/" + "1.2.3.10", status_code=500) with self.assertRaisesRegex(HTTPError, r"Received a server error \(500\) for"): self.client.country("1.2.3.10") @requests_mock.mock() def test_300_error(self, mock): mock.get( self.base_uri + "country/" + "1.2.3.11", status_code=300, headers={"Content-Type": self._content_type("country")}, ) with self.assertRaisesRegex( HTTPError, r"Received a very surprising HTTP status \(300\) for"): self.client.country("1.2.3.11") @requests_mock.mock() def test_ip_address_required(self, mock): self._test_error(mock, 400, "IP_ADDRESS_REQUIRED", InvalidRequestError) @requests_mock.mock() def test_ip_address_not_found(self, mock): self._test_error(mock, 404, "IP_ADDRESS_NOT_FOUND", AddressNotFoundError) @requests_mock.mock() def test_ip_address_reserved(self, mock): self._test_error(mock, 400, "IP_ADDRESS_RESERVED", AddressNotFoundError) @requests_mock.mock() def test_permission_required(self, mock): self._test_error(mock, 403, "PERMISSION_REQUIRED", PermissionRequiredError) @requests_mock.mock() def test_auth_invalid(self, mock): self._test_error(mock, 400, "AUTHORIZATION_INVALID", AuthenticationError) @requests_mock.mock() def test_license_key_required(self, mock): self._test_error(mock, 401, "LICENSE_KEY_REQUIRED", AuthenticationError) @requests_mock.mock() def test_account_id_required(self, mock): self._test_error(mock, 401, "ACCOUNT_ID_REQUIRED", AuthenticationError) @requests_mock.mock() def test_user_id_required(self, mock): self._test_error(mock, 401, "USER_ID_REQUIRED", AuthenticationError) @requests_mock.mock() def test_account_id_unkown(self, mock): self._test_error(mock, 401, "ACCOUNT_ID_UNKNOWN", AuthenticationError) @requests_mock.mock() def test_user_id_unkown(self, mock): self._test_error(mock, 401, "USER_ID_UNKNOWN", AuthenticationError) @requests_mock.mock() def test_out_of_queries_error(self, mock): self._test_error(mock, 402, "OUT_OF_QUERIES", OutOfQueriesError) def _test_error(self, mock, status, error_code, error_class): msg = "Some error message" body = {"error": msg, "code": error_code} mock.get( self.base_uri + "country/1.2.3.18", json=body, status_code=status, headers={"Content-Type": self._content_type("country")}, ) with self.assertRaisesRegex(error_class, msg): self.client.country("1.2.3.18") @requests_mock.mock() def test_unknown_error(self, mock): msg = "Unknown error type" ip = "1.2.3.19" body = {"error": msg, "code": "UNKNOWN_TYPE"} mock.get( self.base_uri + "country/" + ip, json=body, status_code=400, headers={"Content-Type": self._content_type("country")}, ) with self.assertRaisesRegex(InvalidRequestError, msg): self.client.country(ip) @requests_mock.mock() def test_request(self, mock): mock.get( self.base_uri + "country/" + "1.2.3.4", json=self.country, status_code=200, headers={"Content-Type": self._content_type("country")}, ) self.client.country("1.2.3.4") request = mock.request_history[-1] self.assertEqual(request.path, "/geoip/v2.1/country/1.2.3.4", "correct URI is used") self.assertEqual(request.headers["Accept"], "application/json", "correct Accept header") self.assertRegex( request.headers["User-Agent"], "^GeoIP2 Python Client v", "Correct User-Agent", ) self.assertEqual( request.headers["Authorization"], "Basic NDI6YWJjZGVmMTIzNDU2", "correct auth", ) @requests_mock.mock() def test_city_ok(self, mock): mock.get( self.base_uri + "city/" + "1.2.3.4", json=self.country, status_code=200, headers={"Content-Type": self._content_type("city")}, ) city = self.client.city("1.2.3.4") self.assertEqual(type(city), geoip2.models.City, "return value of client.city") self.assertEqual(city.traits.network, compat_ip_network("1.2.3.0/24"), "network") @requests_mock.mock() def test_insights_ok(self, mock): mock.get( self.base_uri + "insights/1.2.3.4", json=self.insights, status_code=200, headers={"Content-Type": self._content_type("country")}, ) insights = self.client.insights("1.2.3.4") self.assertEqual(type(insights), geoip2.models.Insights, "return value of client.insights") self.assertEqual(insights.traits.network, compat_ip_network("1.2.3.0/24"), "network") self.assertEqual(insights.traits.static_ip_score, 1.3, "static_ip_score is 1.3") self.assertEqual(insights.traits.user_count, 2, "user_count is 2") def test_named_constructor_args(self): id = "47" key = "1234567890ab" for client in ( Client(account_id=id, license_key=key), Client(user_id=id, license_key=key), ): self.assertEqual(client._account_id, id) self.assertEqual(client._license_key, key) def test_missing_constructor_args(self): with self.assertRaises(TypeError): Client(license_key="1234567890ab") with self.assertRaises(TypeError): Client("47")
class TestClient(unittest.TestCase): def setUp(self): self.client = Client( 42, 'abcdef123456', ) base_uri = 'https://geoip.maxmind.com/geoip/v2.1/' country = { 'continent': { 'code': 'NA', 'geoname_id': 42, 'names': { 'en': 'North America' } }, 'country': { 'geoname_id': 1, 'iso_code': 'US', 'names': { 'en': 'United States of America' } }, 'maxmind': { 'queries_remaining': 11 }, 'traits': { 'ip_address': '1.2.3.4' }, } def _content_type(self, endpoint): return ('application/vnd.maxmind.com-' + endpoint + '+json; charset=UTF-8; version=1.0') def test_country_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) country = self.client.country('1.2.3.4') self.assertEqual(type(country), geoip2.models.Country, 'return value of client.country') self.assertEqual(country.continent.geoname_id, 42, 'continent geoname_id is 42') self.assertEqual(country.continent.code, 'NA', 'continent code is NA') self.assertEqual(country.continent.name, 'North America', 'continent name is North America') self.assertEqual(country.country.geoname_id, 1, 'country geoname_id is 1') self.assertEqual(country.country.iso_code, 'US', 'country iso_code is US') self.assertEqual(country.country.names, {'en': 'United States of America'}, 'country names') self.assertEqual(country.country.name, 'United States of America', 'country name is United States of America') self.assertEqual(country.maxmind.queries_remaining, 11, 'queries_remaining is 11') self.assertEqual(country.raw, self.country, 'raw response is correct') def test_me(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/me', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) implicit_me = self.client.country() self.assertEqual(type(implicit_me), geoip2.models.Country, 'country() returns Country object') explicit_me = self.client.country() self.assertEqual(type(explicit_me), geoip2.models.Country, 'country(\'me\') returns Country object') def test_200_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/1.1.1.1', status=200, content_type=self._content_type('country')) with self.assertRaisesRegex(GeoIP2Error, 'could not decode the response as JSON'): self.client.country('1.1.1.1') def test_bad_ip_address(self): with self.assertRaisesRegex( ValueError, "'1.2.3' does not appear to be an IPv4 " "or IPv6 address"): self.client.country('1.2.3') def test_no_body_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.7', body='', status=400, content_type=self._content_type('country')) with self.assertRaisesRegex( HTTPError, 'Received a 400 error for .* with no body'): self.client.country('1.2.3.7') def test_weird_body_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.8', body='{"wierd": 42}', status=400, content_type=self._content_type('country')) with self.assertRaisesRegex( HTTPError, 'Response contains JSON but it does not ' 'specify code or error keys'): self.client.country('1.2.3.8') def test_bad_body_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.9', body='bad body', status=400, content_type=self._content_type('country')) with self.assertRaisesRegex( HTTPError, 'it did not include the expected JSON body'): self.client.country('1.2.3.9') def test_500_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.10', status=500) with self.assertRaisesRegex(HTTPError, 'Received a server error \(500\) for'): self.client.country('1.2.3.10') def test_300_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.11', status=300, content_type=self._content_type('country')) with self.assertRaisesRegex( HTTPError, 'Received a very surprising HTTP status ' '\(300\) for'): self.client.country('1.2.3.11') def test_address_not_found_error(self): body = {'error': 'Not in DB', 'code': 'IP_ADDRESS_NOT_FOUND'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.13', body=json.dumps(body), status=404, content_type=self._content_type('country')) with self.assertRaisesRegex(AddressNotFoundError, 'Not in DB'): self.client.country('1.2.3.13') def test_private_address_error(self): body = {'error': 'Private', 'code': 'IP_ADDRESS_RESERVED'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.14', body=json.dumps(body), status=401, content_type=self._content_type('country')) with self.assertRaisesRegex(AddressNotFoundError, 'Private'): self.client.country('1.2.3.14') def test_auth_invalid(self): body = {'error': 'Invalid auth', 'code': 'AUTHORIZATION_INVALID'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.15', body=json.dumps(body), status=400, content_type=self._content_type('country')) with self.assertRaisesRegex(AuthenticationError, 'Invalid auth'): self.client.country('1.2.3.15') def test_license_required(self): body = {'error': 'License required', 'code': 'LICENSE_KEY_REQUIRED'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.16', body=json.dumps(body), status=401, content_type=self._content_type('country')) with self.assertRaisesRegex(AuthenticationError, 'License required'): self.client.country('1.2.3.16') def test_user_id_required(self): body = {'error': 'User ID required', 'code': 'USER_ID_REQUIRED'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.17', body=json.dumps(body), status=401, content_type=self._content_type('country')) with self.assertRaisesRegex(AuthenticationError, 'User ID required'): self.client.country('1.2.3.17') def test_out_of_queries_error(self): body = {'error': 'Out of Queries', 'code': 'OUT_OF_QUERIES'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.18', body=json.dumps(body), status=402, content_type=self._content_type('country')) with self.assertRaisesRegex( OutOfQueriesError, 'Out of Queries', ): self.client.country('1.2.3.18') def test_request(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) country = self.client.country('1.2.3.4') request = httpretty.core.httpretty.latest_requests[-1] self.assertEqual(request.path, '/geoip/v2.1/country/1.2.3.4', 'correct URI is used') self.assertEqual(request.headers['Accept'], 'application/json', 'correct Accept header') self.assertRegex(request.headers['User-Agent'], '^GeoIP2 Python Client v', 'Correct User-Agent') self.assertEqual(request.headers['Authorization'], 'Basic NDI6YWJjZGVmMTIzNDU2', 'correct auth') def test_city_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'city/' + '1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('city')) city = self.client.city('1.2.3.4') self.assertEqual(type(city), geoip2.models.City, 'return value of client.city') def test_insights_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'insights/1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) insights = self.client.insights('1.2.3.4') self.assertEqual(type(insights), geoip2.models.Insights, 'return value of client.insights') def test_insights_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'insights/1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) insights = self.client.insights('1.2.3.4') self.assertEqual(type(insights), geoip2.models.Insights, 'return value of client.insights')
class TestClient(unittest.TestCase): def setUp(self): self.client = Client(42, 'abcdef123456',) base_uri = 'https://geoip.maxmind.com/geoip/v2.1/' country = { 'continent': { 'code': 'NA', 'geoname_id': 42, 'names': {'en': 'North America'} }, 'country': { 'geoname_id': 1, 'iso_code': 'US', 'names': {'en': 'United States of America'} }, 'maxmind': {'queries_remaining': 11}, 'traits': {'ip_address': '1.2.3.4'}, } def _content_type(self, endpoint): return ('application/vnd.maxmind.com-' + endpoint + '+json; charset=UTF-8; version=1.0') def test_country_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) country = self.client.country('1.2.3.4') self.assertEqual(type(country), geoip2.models.Country, 'return value of client.country') self.assertEqual(country.continent.geoname_id, 42, 'continent geoname_id is 42') self.assertEqual(country.continent.code, 'NA', 'continent code is NA') self.assertEqual(country.continent.name, 'North America', 'continent name is North America') self.assertEqual(country.country.geoname_id, 1, 'country geoname_id is 1') self.assertEqual(country.country.iso_code, 'US', 'country iso_code is US') self.assertEqual(country.country.names, {'en': 'United States of America'}, 'country names') self.assertEqual(country.country.name, 'United States of America', 'country name is United States of America') self.assertEqual(country.maxmind.queries_remaining, 11, 'queries_remaining is 11') self.assertEqual(country.raw, self.country, 'raw response is correct') def test_me(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/me', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) implicit_me = self.client.country() self.assertEqual(type(implicit_me), geoip2.models.Country, 'country() returns Country object') explicit_me = self.client.country() self.assertEqual(type(explicit_me), geoip2.models.Country, 'country(\'me\') returns Country object') def test_200_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/1.1.1.1', status=200, content_type=self._content_type('country')) with self.assertRaisesRegex(GeoIP2Error, 'could not decode the response as JSON'): self.client.country('1.1.1.1') def test_bad_ip_address(self): with self.assertRaisesRegex(ValueError, "'1.2.3' does not appear to be an IPv4 " "or IPv6 address"): self.client.country('1.2.3') def test_no_body_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.7', body='', status=400, content_type=self._content_type('country')) with self.assertRaisesRegex(HTTPError, 'Received a 400 error for .* with no body'): self.client.country('1.2.3.7') def test_weird_body_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.8', body='{"wierd": 42}', status=400, content_type=self._content_type('country')) with self.assertRaisesRegex(HTTPError, 'Response contains JSON but it does not ' 'specify code or error keys'): self.client.country('1.2.3.8') def test_bad_body_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.9', body='bad body', status=400, content_type=self._content_type('country')) with self.assertRaisesRegex(HTTPError, 'it did not include the expected JSON body' ): self.client.country('1.2.3.9') def test_500_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.10', status=500) with self.assertRaisesRegex(HTTPError, 'Received a server error \(500\) for'): self.client.country('1.2.3.10') def test_300_error(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.11', status=300, content_type=self._content_type('country')) with self.assertRaisesRegex(HTTPError, 'Received a very surprising HTTP status ' '\(300\) for'): self.client.country('1.2.3.11') def test_address_not_found_error(self): body = {'error': 'Not in DB', 'code': 'IP_ADDRESS_NOT_FOUND'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.13', body=json.dumps(body), status=404, content_type=self._content_type('country')) with self.assertRaisesRegex(AddressNotFoundError, 'Not in DB'): self.client.country('1.2.3.13') def test_private_address_error(self): body = {'error': 'Private', 'code': 'IP_ADDRESS_RESERVED'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.14', body=json.dumps(body), status=401, content_type=self._content_type('country')) with self.assertRaisesRegex(AddressNotFoundError, 'Private'): self.client.country('1.2.3.14') def test_auth_invalid(self): body = {'error': 'Invalid auth', 'code': 'AUTHORIZATION_INVALID'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.15', body=json.dumps(body), status=400, content_type=self._content_type('country')) with self.assertRaisesRegex(AuthenticationError, 'Invalid auth'): self.client.country('1.2.3.15') def test_license_required(self): body = {'error': 'License required', 'code': 'LICENSE_KEY_REQUIRED'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.16', body=json.dumps(body), status=401, content_type=self._content_type('country')) with self.assertRaisesRegex(AuthenticationError, 'License required'): self.client.country('1.2.3.16') def test_user_id_required(self): body = {'error': 'User ID required', 'code': 'USER_ID_REQUIRED'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.17', body=json.dumps(body), status=401, content_type=self._content_type('country')) with self.assertRaisesRegex(AuthenticationError, 'User ID required'): self.client.country('1.2.3.17') def test_out_of_queries_error(self): body = {'error': 'Out of Queries', 'code': 'OUT_OF_QUERIES'} httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.18', body=json.dumps(body), status=402, content_type=self._content_type('country')) with self.assertRaisesRegex(OutOfQueriesError, 'Out of Queries',): self.client.country('1.2.3.18') def test_request(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'country/' + '1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) country = self.client.country('1.2.3.4') request = httpretty.core.httpretty.latest_requests[-1] self.assertEqual(request.path, '/geoip/v2.1/country/1.2.3.4', 'correct URI is used') self.assertEqual(request.headers['Accept'], 'application/json', 'correct Accept header') self.assertRegex(request.headers['User-Agent'], '^GeoIP2 Python Client v', 'Correct User-Agent') self.assertEqual(request.headers['Authorization'], 'Basic NDI6YWJjZGVmMTIzNDU2', 'correct auth') def test_city_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'city/' + '1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('city')) city = self.client.city('1.2.3.4') self.assertEqual(type(city), geoip2.models.City, 'return value of client.city') def test_city_isp_org_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'city/1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) city_isp_org = self.client.city_isp_org('1.2.3.4') self.assertEqual(type(city_isp_org), geoip2.models.City, 'return value of client.city_isp_org') def test_insights_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'insights/1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) omni = self.client.insights('1.2.3.4') self.assertEqual(type(omni), geoip2.models.Insights, 'return value of client.omni') def test_insights_ok(self): httpretty.register_uri(httpretty.GET, self.base_uri + 'insights/1.2.3.4', body=json.dumps(self.country), status=200, content_type=self._content_type('country')) insights = self.client.insights('1.2.3.4') self.assertEqual(type(insights), geoip2.models.Insights, 'return value of client.insights')