Skip to content

Commit

Permalink
Merge pull request #162 from maxmind/greg/eng-1114
Browse files Browse the repository at this point in the history
Upgrade to geoip2 5.0.1 and minor cleanup
  • Loading branch information
horgh authored Jan 29, 2025
2 parents 0468503 + ce35572 commit 5a6794e
Show file tree
Hide file tree
Showing 12 changed files with 467 additions and 361 deletions.
3 changes: 1 addition & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# This file is execfile()d with the current directory set to its containing dir.
#
Expand All @@ -9,8 +8,8 @@
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys
import os
import sys

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
Expand Down
7 changes: 3 additions & 4 deletions minfraud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@

# flake8: noqa: F401
from .errors import (
MinFraudError,
AuthenticationError,
HTTPError,
InvalidRequestError,
InsufficientFundsError,
InvalidRequestError,
MinFraudError,
)

from .webservice import AsyncClient, Client
from .version import __version__
from .webservice import AsyncClient, Client

__author__ = "Gregory Oschwald"
142 changes: 75 additions & 67 deletions minfraud/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,27 @@
"""

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

from geoip2.mixins import SimpleEquality
import geoip2.models
import geoip2.records


class _Serializable(SimpleEquality):
def to_dict(self):
"""Returns a dict of the object suitable for serialization"""
class _Serializable:
def __eq__(self, other: object) -> bool:
return isinstance(other, self.__class__) and self.to_dict() == other.to_dict()

def __ne__(self, other: object) -> bool:
return not self.__eq__(other)

def to_dict(self) -> dict:
"""Returns a dict of the object suitable for serialization."""
result = {}
for key, value in self.__dict__.items():
if hasattr(value, "to_dict") and callable(value.to_dict):
if d := value.to_dict():
result[key] = d
elif hasattr(value, "raw"):
# geoip2 uses "raw" for historical reasons
if d := value.raw:
result[key] = d
elif isinstance(value, list):
ls = []
for e in value:
Expand Down Expand Up @@ -82,7 +84,9 @@ class IPRiskReason(_Serializable):
code: Optional[str]
reason: Optional[str]

def __init__(self, code: Optional[str] = None, reason: Optional[str] = None):
def __init__(
self, code: Optional[str] = None, reason: Optional[str] = None
) -> None:
self.code = code
self.reason = reason

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

def __init__(self, *args, **kwargs) -> None:
self.local_time = kwargs.get("local_time", None)
self.local_time = kwargs.get("local_time")
super().__init__(*args, **kwargs)


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

location: GeoIP2Location
risk: Optional[float]
risk_reasons: List[IPRiskReason]
risk_reasons: list[IPRiskReason]

def __init__(
self,
locales: Optional[Sequence[str]],
*,
country: Optional[Dict] = None,
location: Optional[Dict] = None,
country: Optional[dict] = None,
location: Optional[dict] = None,
risk: Optional[float] = None,
risk_reasons: Optional[List[Dict]] = None,
risk_reasons: Optional[list[dict]] = None,
**kwargs,
) -> None:
# For raw attribute
Expand All @@ -218,7 +222,7 @@ def __init__(
if risk_reasons is not None:
kwargs["risk_reasons"] = risk_reasons

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

risk: Optional[float]

def __init__(self, *, risk: Optional[float] = None, **_):
def __init__(self, *, risk: Optional[float] = None, **_) -> None:
self.risk = risk


Expand Down Expand Up @@ -292,7 +296,7 @@ def __init__(
phone_number: Optional[str] = None,
matches_provided_phone_number: Optional[bool] = None,
**_,
):
) -> None:
self.name = name
self.matches_provided_name = matches_provided_name
self.phone_number = phone_number
Expand Down Expand Up @@ -352,7 +356,7 @@ def __init__(
last_seen: Optional[str] = None,
local_time: Optional[str] = None,
**_,
):
) -> None:
self.confidence = confidence
self.id = id
self.last_seen = last_seen
Expand Down Expand Up @@ -402,7 +406,7 @@ def __init__(
reason: Optional[str] = None,
rule_label: Optional[str] = None,
**_,
):
) -> None:
self.action = action
self.reason = reason
self.rule_label = rule_label
Expand All @@ -423,7 +427,7 @@ class EmailDomain(_Serializable):

first_seen: Optional[str]

def __init__(self, *, first_seen: Optional[str] = None, **_):
def __init__(self, *, first_seen: Optional[str] = None, **_) -> None:
self.first_seen = first_seen


Expand Down Expand Up @@ -477,12 +481,12 @@ class Email(_Serializable):

def __init__(
self,
domain: Optional[Dict] = None,
domain: Optional[dict] = None,
first_seen: Optional[str] = None,
is_disposable: Optional[bool] = None,
is_free: Optional[bool] = None,
is_high_risk: Optional[bool] = None,
):
) -> None:
self.domain = EmailDomain(**(domain or {}))
self.first_seen = first_seen
self.is_disposable = is_disposable
Expand Down Expand Up @@ -564,7 +568,7 @@ class CreditCard(_Serializable):

def __init__(
self,
issuer: Optional[Dict] = None,
issuer: Optional[dict] = None,
country: Optional[str] = None,
brand: Optional[str] = None,
is_business: Optional[bool] = None,
Expand All @@ -573,7 +577,7 @@ def __init__(
is_virtual: Optional[bool] = None,
# pylint:disable=redefined-builtin
type: Optional[str] = None,
):
) -> None:
self.issuer = Issuer(**(issuer or {}))
self.country = country
self.brand = brand
Expand Down Expand Up @@ -642,7 +646,7 @@ def __init__(
distance_to_ip_location: Optional[int] = None,
is_in_ip_country: Optional[bool] = None,
**_,
):
) -> None:
self.is_postal_in_city = is_postal_in_city
self.latitude = latitude
self.longitude = longitude
Expand Down Expand Up @@ -729,7 +733,7 @@ def __init__(
is_high_risk: Optional[bool] = None,
distance_to_billing_address: Optional[int] = None,
**_,
):
) -> None:
self.is_postal_in_city = is_postal_in_city
self.latitude = latitude
self.longitude = longitude
Expand Down Expand Up @@ -789,7 +793,7 @@ def __init__(
network_operator: Optional[str] = None,
number_type: Optional[str] = None,
**_,
):
) -> None:
self.country = country
self.is_voip = is_voip
self.network_operator = network_operator
Expand Down Expand Up @@ -837,7 +841,7 @@ def __init__(
warning: Optional[str] = None,
input_pointer: Optional[str] = None,
**_,
):
) -> None:
self.code = code
self.warning = warning
self.input_pointer = input_pointer
Expand Down Expand Up @@ -1060,7 +1064,7 @@ def __init__(
shipping_address_distance_to_ip_location: Optional[float] = None,
time_of_day: Optional[float] = None,
**_,
):
) -> None:
self.avs_result = avs_result
self.billing_address = billing_address
self.billing_address_distance_to_ip_location = (
Expand Down Expand Up @@ -1174,8 +1178,12 @@ class Reason(_Serializable):
reason: Optional[str]

def __init__(
self, *, code: Optional[str] = None, reason: Optional[str] = None, **_
):
self,
*,
code: Optional[str] = None,
reason: Optional[str] = None,
**_,
) -> None:
self.code = code
self.reason = reason

Expand All @@ -1202,15 +1210,15 @@ class RiskScoreReason(_Serializable):
"""

multiplier: float
reasons: List[Reason]
reasons: list[Reason]

def __init__(
self,
*,
multiplier: float,
reasons: Optional[List] = None,
reasons: Optional[list] = None,
**_,
):
) -> None:
self.multiplier = multiplier
self.reasons = [Reason(**x) for x in reasons or []]

Expand Down Expand Up @@ -1357,32 +1365,32 @@ class Factors(_Serializable):
shipping_address: ShippingAddress
shipping_phone: Phone
subscores: Subscores
warnings: List[ServiceWarning]
risk_score_reasons: List[RiskScoreReason]
warnings: list[ServiceWarning]
risk_score_reasons: list[RiskScoreReason]

def __init__(
self,
locales: Sequence[str],
*,
billing_address: Optional[Dict] = None,
billing_phone: Optional[Dict] = None,
credit_card: Optional[Dict] = None,
disposition: Optional[Dict] = None,
billing_address: Optional[dict] = None,
billing_phone: Optional[dict] = None,
credit_card: Optional[dict] = None,
disposition: Optional[dict] = None,
funds_remaining: float,
device: Optional[Dict] = None,
email: Optional[Dict] = None,
device: Optional[dict] = None,
email: Optional[dict] = None,
# pylint:disable=redefined-builtin
id: str,
ip_address: Optional[Dict] = None,
ip_address: Optional[dict] = None,
queries_remaining: int,
risk_score: float,
shipping_address: Optional[Dict] = None,
shipping_phone: Optional[Dict] = None,
subscores: Optional[Dict] = None,
warnings: Optional[List[Dict]] = None,
risk_score_reasons: Optional[List[Dict]] = None,
shipping_address: Optional[dict] = None,
shipping_phone: Optional[dict] = None,
subscores: Optional[dict] = None,
warnings: Optional[list[dict]] = None,
risk_score_reasons: Optional[list[dict]] = None,
**_,
):
) -> None:
self.billing_address = BillingAddress(**(billing_address or {}))
self.billing_phone = Phone(**(billing_phone or {}))
self.credit_card = CreditCard(**(credit_card or {}))
Expand Down Expand Up @@ -1524,29 +1532,29 @@ class Insights(_Serializable):
risk_score: float
shipping_address: ShippingAddress
shipping_phone: Phone
warnings: List[ServiceWarning]
warnings: list[ServiceWarning]

def __init__(
self,
locales: Sequence[str],
*,
billing_address: Optional[Dict] = None,
billing_phone: Optional[Dict] = None,
credit_card: Optional[Dict] = None,
device: Optional[Dict] = None,
disposition: Optional[Dict] = None,
email: Optional[Dict] = None,
billing_address: Optional[dict] = None,
billing_phone: Optional[dict] = None,
credit_card: Optional[dict] = None,
device: Optional[dict] = None,
disposition: Optional[dict] = None,
email: Optional[dict] = None,
funds_remaining: float,
# pylint:disable=redefined-builtin
id: str,
ip_address: Optional[Dict] = None,
ip_address: Optional[dict] = None,
queries_remaining: int,
risk_score: float,
shipping_address: Optional[Dict] = None,
shipping_phone: Optional[Dict] = None,
warnings: Optional[List[Dict]] = None,
shipping_address: Optional[dict] = None,
shipping_phone: Optional[dict] = None,
warnings: Optional[list[dict]] = None,
**_,
):
) -> None:
self.billing_address = BillingAddress(**(billing_address or {}))
self.billing_phone = Phone(**(billing_phone or {}))
self.credit_card = CreditCard(**(credit_card or {}))
Expand Down Expand Up @@ -1627,21 +1635,21 @@ class Score(_Serializable):
ip_address: ScoreIPAddress
queries_remaining: int
risk_score: float
warnings: List[ServiceWarning]
warnings: list[ServiceWarning]

def __init__(
self,
*,
disposition: Optional[Dict] = None,
disposition: Optional[dict] = None,
funds_remaining: float,
# pylint:disable=redefined-builtin
id: str,
ip_address: Optional[Dict] = None,
ip_address: Optional[dict] = None,
queries_remaining: int,
risk_score: float,
warnings: Optional[List[Dict]] = None,
warnings: Optional[list[dict]] = None,
**_,
):
) -> None:
self.disposition = Disposition(**(disposition or {}))
self.funds_remaining = funds_remaining
self.id = id
Expand Down
Loading

0 comments on commit 5a6794e

Please sign in to comment.