Skip to content

Commit ca14f05

Browse files
committed
Add is_residential_proxy
1 parent fe8e488 commit ca14f05

File tree

7 files changed

+49
-1
lines changed

7 files changed

+49
-1
lines changed

HISTORY.rst

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

6+
4.1.0
7+
++++++++++++++++++
8+
9+
* Added the ``is_residential_proxy`` attribute to ``geoip2.model.AnonymousIP``
10+
and ``geoip2.record.Traits``.
11+
612
4.0.2 (2020-07-28)
713
++++++++++++++++++
814

README.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ Anonymous IP Database
229229
False
230230
>>> response.is_public_proxy
231231
False
232+
>>> response.is_residential_proxy
233+
False
232234
>>> response.is_tor_exit_node
233235
True
234236
>>> response.ip_address

geoip2/models.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,13 @@ class AnonymousIP(SimpleModel):
396396
397397
:type: bool
398398
399+
.. attribute:: is_residential_proxy
400+
401+
This is true if the IP address is on a suspected anonymizing network
402+
and belongs to a residential ISP.
403+
404+
:type: bool
405+
399406
.. attribute:: is_tor_exit_node
400407
401408
This is true if the IP address is a Tor exit node.
@@ -421,6 +428,7 @@ class AnonymousIP(SimpleModel):
421428
is_anonymous_vpn: bool
422429
is_hosting_provider: bool
423430
is_public_proxy: bool
431+
is_residential_proxy: bool
424432
is_tor_exit_node: bool
425433

426434
def __init__(self, raw: Dict[str, bool]) -> None:
@@ -429,6 +437,7 @@ def __init__(self, raw: Dict[str, bool]) -> None:
429437
self.is_anonymous_vpn = raw.get("is_anonymous_vpn", False)
430438
self.is_hosting_provider = raw.get("is_hosting_provider", False)
431439
self.is_public_proxy = raw.get("is_public_proxy", False)
440+
self.is_residential_proxy = raw.get("is_residential_proxy", False)
432441
self.is_tor_exit_node = raw.get("is_tor_exit_node", False)
433442

434443

geoip2/records.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,14 @@ class Traits(Record):
693693
694694
:type: bool
695695
696+
.. attribute:: is_residential_proxy
697+
698+
This is true if the IP address is on a suspected anonymizing network
699+
and belongs to a residential ISP.
700+
701+
:type: bool
702+
703+
696704
.. attribute:: is_satellite_provider
697705
698706
This is true if the IP address is from a satellite provider that
@@ -798,6 +806,7 @@ class Traits(Record):
798806
is_hosting_provider: bool
799807
is_legitimate_proxy: bool
800808
is_public_proxy: bool
809+
is_residential_proxy: bool
801810
is_satellite_provider: bool
802811
is_tor_exit_node: bool
803812
isp: Optional[str]
@@ -821,6 +830,7 @@ def __init__(
821830
is_hosting_provider: bool = False,
822831
is_legitimate_proxy: bool = False,
823832
is_public_proxy: bool = False,
833+
is_residential_proxy: bool = False,
824834
is_satellite_provider: bool = False,
825835
is_tor_exit_node: bool = False,
826836
isp: Optional[str] = None,
@@ -843,6 +853,7 @@ def __init__(
843853
self.is_hosting_provider = is_hosting_provider
844854
self.is_legitimate_proxy = is_legitimate_proxy
845855
self.is_public_proxy = is_public_proxy
856+
self.is_residential_proxy = is_residential_proxy
846857
self.is_satellite_provider = is_satellite_provider
847858
self.is_tor_exit_node = is_tor_exit_node
848859
self.isp = isp

tests/data

Submodule data updated 44 files

tests/database_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,29 @@ def test_anonymous_ip(self) -> None:
6666
self.assertEqual(record.is_anonymous_vpn, True)
6767
self.assertEqual(record.is_hosting_provider, False)
6868
self.assertEqual(record.is_public_proxy, False)
69+
self.assertEqual(record.is_residential_proxy, False)
6970
self.assertEqual(record.is_tor_exit_node, False)
7071
self.assertEqual(record.ip_address, ip_address)
7172
self.assertEqual(record.network, ipaddress.ip_network("1.2.0.0/16"))
7273
reader.close()
7374

75+
def test_anonymous_ip_all_set(self) -> None:
76+
reader = geoip2.database.Reader(
77+
"tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb"
78+
)
79+
ip_address = "81.2.69.1"
80+
81+
record = reader.anonymous_ip(ip_address)
82+
self.assertEqual(record.is_anonymous, True)
83+
self.assertEqual(record.is_anonymous_vpn, True)
84+
self.assertEqual(record.is_hosting_provider, True)
85+
self.assertEqual(record.is_public_proxy, True)
86+
self.assertEqual(record.is_residential_proxy, True)
87+
self.assertEqual(record.is_tor_exit_node, True)
88+
self.assertEqual(record.ip_address, ip_address)
89+
self.assertEqual(record.network, ipaddress.ip_network("81.2.69.0/24"))
90+
reader.close()
91+
7492
def test_asn(self) -> None:
7593
reader = geoip2.database.Reader("tests/data/test-data/GeoLite2-ASN-Test.mmdb")
7694

tests/models_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def test_insights_full(self) -> None:
7979
"is_anonymous_vpn": True,
8080
"is_hosting_provider": True,
8181
"is_public_proxy": True,
82+
"is_residential_proxy": True,
8283
"is_satellite_provider": True,
8384
"is_tor_exit_node": True,
8485
"isp": "Comcast",
@@ -194,6 +195,7 @@ def test_insights_full(self) -> None:
194195
self.assertIs(model.traits.is_anonymous_vpn, True)
195196
self.assertIs(model.traits.is_hosting_provider, True)
196197
self.assertIs(model.traits.is_public_proxy, True)
198+
self.assertIs(model.traits.is_residential_proxy, True)
197199
self.assertIs(model.traits.is_satellite_provider, True)
198200
self.assertIs(model.traits.is_tor_exit_node, True)
199201
self.assertEqual(model.traits.user_count, 2)

0 commit comments

Comments
 (0)