Skip to content

Commit 5a6794e

Browse files
authored
Merge pull request #162 from maxmind/greg/eng-1114
Upgrade to geoip2 5.0.1 and minor cleanup
2 parents 0468503 + ce35572 commit 5a6794e

File tree

12 files changed

+467
-361
lines changed

12 files changed

+467
-361
lines changed

docs/conf.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env python3
2-
# -*- coding: utf-8 -*-
32
#
43
# This file is execfile()d with the current directory set to its containing dir.
54
#
@@ -9,8 +8,8 @@
98
# All configuration values have a default; values that are commented out
109
# serve to show the default.
1110

12-
import sys
1311
import os
12+
import sys
1413

1514
# If extensions (or modules to document with autodoc) are in another directory,
1615
# add these directories to sys.path here. If the directory is relative to the

minfraud/__init__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77

88
# flake8: noqa: F401
99
from .errors import (
10-
MinFraudError,
1110
AuthenticationError,
1211
HTTPError,
13-
InvalidRequestError,
1412
InsufficientFundsError,
13+
InvalidRequestError,
14+
MinFraudError,
1515
)
16-
17-
from .webservice import AsyncClient, Client
1816
from .version import __version__
17+
from .webservice import AsyncClient, Client
1918

2019
__author__ = "Gregory Oschwald"

minfraud/models.py

Lines changed: 75 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,27 @@
77
"""
88

99
# pylint:disable=too-many-lines,too-many-instance-attributes,too-many-locals
10-
from typing import Dict, List, Optional, Sequence
10+
from collections.abc import Sequence
11+
from typing import Optional
1112

12-
from geoip2.mixins import SimpleEquality
1313
import geoip2.models
1414
import geoip2.records
1515

1616

17-
class _Serializable(SimpleEquality):
18-
def to_dict(self):
19-
"""Returns a dict of the object suitable for serialization"""
17+
class _Serializable:
18+
def __eq__(self, other: object) -> bool:
19+
return isinstance(other, self.__class__) and self.to_dict() == other.to_dict()
20+
21+
def __ne__(self, other: object) -> bool:
22+
return not self.__eq__(other)
23+
24+
def to_dict(self) -> dict:
25+
"""Returns a dict of the object suitable for serialization."""
2026
result = {}
2127
for key, value in self.__dict__.items():
2228
if hasattr(value, "to_dict") and callable(value.to_dict):
2329
if d := value.to_dict():
2430
result[key] = d
25-
elif hasattr(value, "raw"):
26-
# geoip2 uses "raw" for historical reasons
27-
if d := value.raw:
28-
result[key] = d
2931
elif isinstance(value, list):
3032
ls = []
3133
for e in value:
@@ -82,7 +84,9 @@ class IPRiskReason(_Serializable):
8284
code: Optional[str]
8385
reason: Optional[str]
8486

85-
def __init__(self, code: Optional[str] = None, reason: Optional[str] = None):
87+
def __init__(
88+
self, code: Optional[str] = None, reason: Optional[str] = None
89+
) -> None:
8690
self.code = code
8791
self.reason = reason
8892

@@ -112,7 +116,7 @@ class GeoIP2Location(geoip2.records.Location):
112116
local_time: Optional[str]
113117

114118
def __init__(self, *args, **kwargs) -> None:
115-
self.local_time = kwargs.get("local_time", None)
119+
self.local_time = kwargs.get("local_time")
116120
super().__init__(*args, **kwargs)
117121

118122

@@ -196,16 +200,16 @@ class IPAddress(geoip2.models.Insights):
196200

197201
location: GeoIP2Location
198202
risk: Optional[float]
199-
risk_reasons: List[IPRiskReason]
203+
risk_reasons: list[IPRiskReason]
200204

201205
def __init__(
202206
self,
203207
locales: Optional[Sequence[str]],
204208
*,
205-
country: Optional[Dict] = None,
206-
location: Optional[Dict] = None,
209+
country: Optional[dict] = None,
210+
location: Optional[dict] = None,
207211
risk: Optional[float] = None,
208-
risk_reasons: Optional[List[Dict]] = None,
212+
risk_reasons: Optional[list[dict]] = None,
209213
**kwargs,
210214
) -> None:
211215
# For raw attribute
@@ -218,7 +222,7 @@ def __init__(
218222
if risk_reasons is not None:
219223
kwargs["risk_reasons"] = risk_reasons
220224

221-
super().__init__(kwargs, locales=list(locales or []))
225+
super().__init__(locales, **kwargs)
222226
self.location = GeoIP2Location(**(location or {}))
223227
self.risk = risk
224228
self.risk_reasons = [IPRiskReason(**x) for x in risk_reasons or []]
@@ -237,7 +241,7 @@ class ScoreIPAddress(_Serializable):
237241

238242
risk: Optional[float]
239243

240-
def __init__(self, *, risk: Optional[float] = None, **_):
244+
def __init__(self, *, risk: Optional[float] = None, **_) -> None:
241245
self.risk = risk
242246

243247

@@ -292,7 +296,7 @@ def __init__(
292296
phone_number: Optional[str] = None,
293297
matches_provided_phone_number: Optional[bool] = None,
294298
**_,
295-
):
299+
) -> None:
296300
self.name = name
297301
self.matches_provided_name = matches_provided_name
298302
self.phone_number = phone_number
@@ -352,7 +356,7 @@ def __init__(
352356
last_seen: Optional[str] = None,
353357
local_time: Optional[str] = None,
354358
**_,
355-
):
359+
) -> None:
356360
self.confidence = confidence
357361
self.id = id
358362
self.last_seen = last_seen
@@ -402,7 +406,7 @@ def __init__(
402406
reason: Optional[str] = None,
403407
rule_label: Optional[str] = None,
404408
**_,
405-
):
409+
) -> None:
406410
self.action = action
407411
self.reason = reason
408412
self.rule_label = rule_label
@@ -423,7 +427,7 @@ class EmailDomain(_Serializable):
423427

424428
first_seen: Optional[str]
425429

426-
def __init__(self, *, first_seen: Optional[str] = None, **_):
430+
def __init__(self, *, first_seen: Optional[str] = None, **_) -> None:
427431
self.first_seen = first_seen
428432

429433

@@ -477,12 +481,12 @@ class Email(_Serializable):
477481

478482
def __init__(
479483
self,
480-
domain: Optional[Dict] = None,
484+
domain: Optional[dict] = None,
481485
first_seen: Optional[str] = None,
482486
is_disposable: Optional[bool] = None,
483487
is_free: Optional[bool] = None,
484488
is_high_risk: Optional[bool] = None,
485-
):
489+
) -> None:
486490
self.domain = EmailDomain(**(domain or {}))
487491
self.first_seen = first_seen
488492
self.is_disposable = is_disposable
@@ -564,7 +568,7 @@ class CreditCard(_Serializable):
564568

565569
def __init__(
566570
self,
567-
issuer: Optional[Dict] = None,
571+
issuer: Optional[dict] = None,
568572
country: Optional[str] = None,
569573
brand: Optional[str] = None,
570574
is_business: Optional[bool] = None,
@@ -573,7 +577,7 @@ def __init__(
573577
is_virtual: Optional[bool] = None,
574578
# pylint:disable=redefined-builtin
575579
type: Optional[str] = None,
576-
):
580+
) -> None:
577581
self.issuer = Issuer(**(issuer or {}))
578582
self.country = country
579583
self.brand = brand
@@ -642,7 +646,7 @@ def __init__(
642646
distance_to_ip_location: Optional[int] = None,
643647
is_in_ip_country: Optional[bool] = None,
644648
**_,
645-
):
649+
) -> None:
646650
self.is_postal_in_city = is_postal_in_city
647651
self.latitude = latitude
648652
self.longitude = longitude
@@ -729,7 +733,7 @@ def __init__(
729733
is_high_risk: Optional[bool] = None,
730734
distance_to_billing_address: Optional[int] = None,
731735
**_,
732-
):
736+
) -> None:
733737
self.is_postal_in_city = is_postal_in_city
734738
self.latitude = latitude
735739
self.longitude = longitude
@@ -789,7 +793,7 @@ def __init__(
789793
network_operator: Optional[str] = None,
790794
number_type: Optional[str] = None,
791795
**_,
792-
):
796+
) -> None:
793797
self.country = country
794798
self.is_voip = is_voip
795799
self.network_operator = network_operator
@@ -837,7 +841,7 @@ def __init__(
837841
warning: Optional[str] = None,
838842
input_pointer: Optional[str] = None,
839843
**_,
840-
):
844+
) -> None:
841845
self.code = code
842846
self.warning = warning
843847
self.input_pointer = input_pointer
@@ -1060,7 +1064,7 @@ def __init__(
10601064
shipping_address_distance_to_ip_location: Optional[float] = None,
10611065
time_of_day: Optional[float] = None,
10621066
**_,
1063-
):
1067+
) -> None:
10641068
self.avs_result = avs_result
10651069
self.billing_address = billing_address
10661070
self.billing_address_distance_to_ip_location = (
@@ -1174,8 +1178,12 @@ class Reason(_Serializable):
11741178
reason: Optional[str]
11751179

11761180
def __init__(
1177-
self, *, code: Optional[str] = None, reason: Optional[str] = None, **_
1178-
):
1181+
self,
1182+
*,
1183+
code: Optional[str] = None,
1184+
reason: Optional[str] = None,
1185+
**_,
1186+
) -> None:
11791187
self.code = code
11801188
self.reason = reason
11811189

@@ -1202,15 +1210,15 @@ class RiskScoreReason(_Serializable):
12021210
"""
12031211

12041212
multiplier: float
1205-
reasons: List[Reason]
1213+
reasons: list[Reason]
12061214

12071215
def __init__(
12081216
self,
12091217
*,
12101218
multiplier: float,
1211-
reasons: Optional[List] = None,
1219+
reasons: Optional[list] = None,
12121220
**_,
1213-
):
1221+
) -> None:
12141222
self.multiplier = multiplier
12151223
self.reasons = [Reason(**x) for x in reasons or []]
12161224

@@ -1357,32 +1365,32 @@ class Factors(_Serializable):
13571365
shipping_address: ShippingAddress
13581366
shipping_phone: Phone
13591367
subscores: Subscores
1360-
warnings: List[ServiceWarning]
1361-
risk_score_reasons: List[RiskScoreReason]
1368+
warnings: list[ServiceWarning]
1369+
risk_score_reasons: list[RiskScoreReason]
13621370

13631371
def __init__(
13641372
self,
13651373
locales: Sequence[str],
13661374
*,
1367-
billing_address: Optional[Dict] = None,
1368-
billing_phone: Optional[Dict] = None,
1369-
credit_card: Optional[Dict] = None,
1370-
disposition: Optional[Dict] = None,
1375+
billing_address: Optional[dict] = None,
1376+
billing_phone: Optional[dict] = None,
1377+
credit_card: Optional[dict] = None,
1378+
disposition: Optional[dict] = None,
13711379
funds_remaining: float,
1372-
device: Optional[Dict] = None,
1373-
email: Optional[Dict] = None,
1380+
device: Optional[dict] = None,
1381+
email: Optional[dict] = None,
13741382
# pylint:disable=redefined-builtin
13751383
id: str,
1376-
ip_address: Optional[Dict] = None,
1384+
ip_address: Optional[dict] = None,
13771385
queries_remaining: int,
13781386
risk_score: float,
1379-
shipping_address: Optional[Dict] = None,
1380-
shipping_phone: Optional[Dict] = None,
1381-
subscores: Optional[Dict] = None,
1382-
warnings: Optional[List[Dict]] = None,
1383-
risk_score_reasons: Optional[List[Dict]] = None,
1387+
shipping_address: Optional[dict] = None,
1388+
shipping_phone: Optional[dict] = None,
1389+
subscores: Optional[dict] = None,
1390+
warnings: Optional[list[dict]] = None,
1391+
risk_score_reasons: Optional[list[dict]] = None,
13841392
**_,
1385-
):
1393+
) -> None:
13861394
self.billing_address = BillingAddress(**(billing_address or {}))
13871395
self.billing_phone = Phone(**(billing_phone or {}))
13881396
self.credit_card = CreditCard(**(credit_card or {}))
@@ -1524,29 +1532,29 @@ class Insights(_Serializable):
15241532
risk_score: float
15251533
shipping_address: ShippingAddress
15261534
shipping_phone: Phone
1527-
warnings: List[ServiceWarning]
1535+
warnings: list[ServiceWarning]
15281536

15291537
def __init__(
15301538
self,
15311539
locales: Sequence[str],
15321540
*,
1533-
billing_address: Optional[Dict] = None,
1534-
billing_phone: Optional[Dict] = None,
1535-
credit_card: Optional[Dict] = None,
1536-
device: Optional[Dict] = None,
1537-
disposition: Optional[Dict] = None,
1538-
email: Optional[Dict] = None,
1541+
billing_address: Optional[dict] = None,
1542+
billing_phone: Optional[dict] = None,
1543+
credit_card: Optional[dict] = None,
1544+
device: Optional[dict] = None,
1545+
disposition: Optional[dict] = None,
1546+
email: Optional[dict] = None,
15391547
funds_remaining: float,
15401548
# pylint:disable=redefined-builtin
15411549
id: str,
1542-
ip_address: Optional[Dict] = None,
1550+
ip_address: Optional[dict] = None,
15431551
queries_remaining: int,
15441552
risk_score: float,
1545-
shipping_address: Optional[Dict] = None,
1546-
shipping_phone: Optional[Dict] = None,
1547-
warnings: Optional[List[Dict]] = None,
1553+
shipping_address: Optional[dict] = None,
1554+
shipping_phone: Optional[dict] = None,
1555+
warnings: Optional[list[dict]] = None,
15481556
**_,
1549-
):
1557+
) -> None:
15501558
self.billing_address = BillingAddress(**(billing_address or {}))
15511559
self.billing_phone = Phone(**(billing_phone or {}))
15521560
self.credit_card = CreditCard(**(credit_card or {}))
@@ -1627,21 +1635,21 @@ class Score(_Serializable):
16271635
ip_address: ScoreIPAddress
16281636
queries_remaining: int
16291637
risk_score: float
1630-
warnings: List[ServiceWarning]
1638+
warnings: list[ServiceWarning]
16311639

16321640
def __init__(
16331641
self,
16341642
*,
1635-
disposition: Optional[Dict] = None,
1643+
disposition: Optional[dict] = None,
16361644
funds_remaining: float,
16371645
# pylint:disable=redefined-builtin
16381646
id: str,
1639-
ip_address: Optional[Dict] = None,
1647+
ip_address: Optional[dict] = None,
16401648
queries_remaining: int,
16411649
risk_score: float,
1642-
warnings: Optional[List[Dict]] = None,
1650+
warnings: Optional[list[dict]] = None,
16431651
**_,
1644-
):
1652+
) -> None:
16451653
self.disposition = Disposition(**(disposition or {}))
16461654
self.funds_remaining = funds_remaining
16471655
self.id = id

0 commit comments

Comments
 (0)