Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
History
-------

4.1.0
++++++++++++++++++

* Added the ``is_residential_proxy`` attribute to ``geoip2.model.AnonymousIP``
and ``geoip2.record.Traits``.

4.0.2 (2020-07-28)
++++++++++++++++++

Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ Anonymous IP Database
False
>>> response.is_public_proxy
False
>>> response.is_residential_proxy
False
>>> response.is_tor_exit_node
True
>>> response.ip_address
Expand Down
9 changes: 9 additions & 0 deletions geoip2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,13 @@ class AnonymousIP(SimpleModel):

:type: bool

.. attribute:: is_residential_proxy

This is true if the IP address is on a suspected anonymizing network
and belongs to a residential ISP.

:type: bool

.. attribute:: is_tor_exit_node

This is true if the IP address is a Tor exit node.
Expand All @@ -421,6 +428,7 @@ class AnonymousIP(SimpleModel):
is_anonymous_vpn: bool
is_hosting_provider: bool
is_public_proxy: bool
is_residential_proxy: bool
is_tor_exit_node: bool

def __init__(self, raw: Dict[str, bool]) -> None:
Expand All @@ -429,6 +437,7 @@ def __init__(self, raw: Dict[str, bool]) -> None:
self.is_anonymous_vpn = raw.get("is_anonymous_vpn", False)
self.is_hosting_provider = raw.get("is_hosting_provider", False)
self.is_public_proxy = raw.get("is_public_proxy", False)
self.is_residential_proxy = raw.get("is_residential_proxy", False)
self.is_tor_exit_node = raw.get("is_tor_exit_node", False)


Expand Down
12 changes: 12 additions & 0 deletions geoip2/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,15 @@ class Traits(Record):

:type: bool

.. attribute:: is_residential_proxy

This is true if the IP address is on a suspected anonymizing network
and belongs to a residential ISP. This attribute is only available from
GeoIP2 Precision Insights.

:type: bool


.. attribute:: is_satellite_provider

This is true if the IP address is from a satellite provider that
Expand Down Expand Up @@ -798,6 +807,7 @@ class Traits(Record):
is_hosting_provider: bool
is_legitimate_proxy: bool
is_public_proxy: bool
is_residential_proxy: bool
is_satellite_provider: bool
is_tor_exit_node: bool
isp: Optional[str]
Expand All @@ -821,6 +831,7 @@ def __init__(
is_hosting_provider: bool = False,
is_legitimate_proxy: bool = False,
is_public_proxy: bool = False,
is_residential_proxy: bool = False,
is_satellite_provider: bool = False,
is_tor_exit_node: bool = False,
isp: Optional[str] = None,
Expand All @@ -843,6 +854,7 @@ def __init__(
self.is_hosting_provider = is_hosting_provider
self.is_legitimate_proxy = is_legitimate_proxy
self.is_public_proxy = is_public_proxy
self.is_residential_proxy = is_residential_proxy
self.is_satellite_provider = is_satellite_provider
self.is_tor_exit_node = is_tor_exit_node
self.isp = isp
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
include_package_data=True,
python_requires=">=3.6",
install_requires=requirements,
tests_require=["mocket>=3.8.6"],
tests_require=["mocket>=3.8.9"],
test_suite="tests",
license=geoip2.__license__,
classifiers=[
Expand Down
2 changes: 1 addition & 1 deletion tests/data
Submodule data updated 44 files
+1 −0 .gitignore
+19 −7 MaxMind-DB-spec.md
+ MaxMind-DB-test-metadata-pointers.mmdb
+ bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb
+9 −1 source-data/GeoIP2-Anonymous-IP-Test.json
+488 −488 source-data/GeoIP2-City-Test.json
+4,584 −15 source-data/GeoIP2-Country-Test.json
+48 −34 source-data/GeoIP2-Enterprise-Test.json
+11 −1 source-data/GeoIP2-ISP-Test.json
+703 −49 source-data/GeoIP2-Precision-Enterprise-Test.json
+2,132 −0 source-data/GeoIP2-Static-IP-Score-Test.json
+2,835 −2,822 source-data/GeoIP2-User-Count-Test.json
+ test-data/GeoIP2-Anonymous-IP-Test.mmdb
+ test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb
+ test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb
+ test-data/GeoIP2-City-Test.mmdb
+ test-data/GeoIP2-Connection-Type-Test.mmdb
+ test-data/GeoIP2-Country-Test.mmdb
+ test-data/GeoIP2-DensityIncome-Test.mmdb
+ test-data/GeoIP2-Domain-Test.mmdb
+ test-data/GeoIP2-Enterprise-Test.mmdb
+ test-data/GeoIP2-ISP-Test.mmdb
+ test-data/GeoIP2-Precision-Enterprise-Test.mmdb
+ test-data/GeoIP2-Static-IP-Score-Test.mmdb
+ test-data/GeoIP2-User-Count-Test.mmdb
+ test-data/GeoLite2-ASN-Test.mmdb
+ test-data/MaxMind-DB-no-ipv4-search-tree.mmdb
+ test-data/MaxMind-DB-string-value-entries.mmdb
+ test-data/MaxMind-DB-test-broken-pointers-24.mmdb
+ test-data/MaxMind-DB-test-broken-search-tree-24.mmdb
+ test-data/MaxMind-DB-test-decoder.mmdb
+ test-data/MaxMind-DB-test-ipv4-24.mmdb
+ test-data/MaxMind-DB-test-ipv4-28.mmdb
+ test-data/MaxMind-DB-test-ipv4-32.mmdb
+ test-data/MaxMind-DB-test-ipv6-24.mmdb
+ test-data/MaxMind-DB-test-ipv6-28.mmdb
+ test-data/MaxMind-DB-test-ipv6-32.mmdb
+ test-data/MaxMind-DB-test-metadata-pointers.mmdb
+ test-data/MaxMind-DB-test-mixed-24.mmdb
+ test-data/MaxMind-DB-test-mixed-28.mmdb
+ test-data/MaxMind-DB-test-mixed-32.mmdb
+ test-data/MaxMind-DB-test-nested.mmdb
+ test-data/MaxMind-DB-test-pointer-decoder.mmdb
+96 −25 test-data/write-test-data.pl
18 changes: 18 additions & 0 deletions tests/database_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,29 @@ def test_anonymous_ip(self) -> None:
self.assertEqual(record.is_anonymous_vpn, True)
self.assertEqual(record.is_hosting_provider, False)
self.assertEqual(record.is_public_proxy, False)
self.assertEqual(record.is_residential_proxy, False)
self.assertEqual(record.is_tor_exit_node, False)
self.assertEqual(record.ip_address, ip_address)
self.assertEqual(record.network, ipaddress.ip_network("1.2.0.0/16"))
reader.close()

def test_anonymous_ip_all_set(self) -> None:
reader = geoip2.database.Reader(
"tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb"
)
ip_address = "81.2.69.1"

record = reader.anonymous_ip(ip_address)
self.assertEqual(record.is_anonymous, True)
self.assertEqual(record.is_anonymous_vpn, True)
self.assertEqual(record.is_hosting_provider, True)
self.assertEqual(record.is_public_proxy, True)
self.assertEqual(record.is_residential_proxy, True)
self.assertEqual(record.is_tor_exit_node, True)
self.assertEqual(record.ip_address, ip_address)
self.assertEqual(record.network, ipaddress.ip_network("81.2.69.0/24"))
reader.close()

def test_asn(self) -> None:
reader = geoip2.database.Reader("tests/data/test-data/GeoLite2-ASN-Test.mmdb")

Expand Down
2 changes: 2 additions & 0 deletions tests/models_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def test_insights_full(self) -> None:
"is_anonymous_vpn": True,
"is_hosting_provider": True,
"is_public_proxy": True,
"is_residential_proxy": True,
"is_satellite_provider": True,
"is_tor_exit_node": True,
"isp": "Comcast",
Expand Down Expand Up @@ -194,6 +195,7 @@ def test_insights_full(self) -> None:
self.assertIs(model.traits.is_anonymous_vpn, True)
self.assertIs(model.traits.is_hosting_provider, True)
self.assertIs(model.traits.is_public_proxy, True)
self.assertIs(model.traits.is_residential_proxy, True)
self.assertIs(model.traits.is_satellite_provider, True)
self.assertIs(model.traits.is_tor_exit_node, True)
self.assertEqual(model.traits.user_count, 2)
Expand Down
2 changes: 1 addition & 1 deletion tests/webservice_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# httpretty currently doesn't work, but mocket with the compat interface
# does.
from mocket import Mocket # type: ignore
from mocket.plugins.httpretty import HTTPretty as httpretty, httprettified # type: ignore
from mocket.plugins.httpretty import httpretty, httprettified # type: ignore
import geoip2
from geoip2.errors import (
AddressNotFoundError,
Expand Down