11"""Client for minFraud Score, Insights, and Factors."""
22
3+ from __future__ import annotations
4+
35import json
4- from collections .abc import Sequence
56from functools import partial
6- from typing import Any , Callable , Optional , Union , cast
7+ from typing import TYPE_CHECKING , Any , Callable , cast
78
89import aiohttp
910import aiohttp .http
1011import requests
1112import requests .utils
12- from requests . models import Response
13+ from typing_extensions import Self
1314
1415from .errors import (
1516 AuthenticationError ,
2324from .request import prepare_report , prepare_transaction
2425from .version import __version__
2526
27+ if TYPE_CHECKING :
28+ import types
29+ from collections .abc import Sequence
30+
31+ from requests .models import Response
32+
2633_AIOHTTP_UA = f"minFraud-API/{ __version__ } { aiohttp .http .SERVER_SOFTWARE } "
2734
2835_REQUEST_UA = f"minFraud-API/{ __version__ } { requests .utils .default_user_agent ()} "
@@ -68,32 +75,35 @@ def _handle_success(
6875 raw_body : str ,
6976 uri : str ,
7077 model_class : Callable ,
71- ) -> Union [ Score , Factors , Insights ] :
78+ ) -> Score | Factors | Insights :
7279 """Handle successful response."""
7380 try :
7481 decoded_body = json .loads (raw_body )
7582 except ValueError as ex :
76- raise MinFraudError (
83+ msg = (
7784 "Received a 200 response but could not decode the "
78- f"response as JSON: { raw_body } " ,
85+ f"response as JSON: { raw_body } "
86+ )
87+ raise MinFraudError (
88+ msg ,
7989 200 ,
8090 uri ,
8191 ) from ex
82- return model_class (** decoded_body ) # type: ignore
92+ return model_class (** decoded_body )
8393
8494 def _exception_for_error (
8595 self ,
8696 status : int ,
87- content_type : Optional [ str ] ,
97+ content_type : str | None ,
8898 raw_body : str ,
8999 uri : str ,
90- ) -> Union [
91- AuthenticationError ,
92- InsufficientFundsError ,
93- InvalidRequestError ,
94- HTTPError ,
95- PermissionRequiredError ,
96- ] :
100+ ) -> (
101+ AuthenticationError
102+ | InsufficientFundsError
103+ | InvalidRequestError
104+ | HTTPError
105+ | PermissionRequiredError
106+ ) :
97107 """Return the exception for the error responses."""
98108 if 400 <= status < 500 :
99109 return self ._exception_for_4xx_status (status , content_type , raw_body , uri )
@@ -104,16 +114,16 @@ def _exception_for_error(
104114 def _exception_for_4xx_status (
105115 self ,
106116 status : int ,
107- content_type : Optional [ str ] ,
117+ content_type : str | None ,
108118 raw_body : str ,
109119 uri : str ,
110- ) -> Union [
111- AuthenticationError ,
112- InsufficientFundsError ,
113- InvalidRequestError ,
114- HTTPError ,
115- PermissionRequiredError ,
116- ] :
120+ ) -> (
121+ AuthenticationError
122+ | InsufficientFundsError
123+ | InvalidRequestError
124+ | HTTPError
125+ | PermissionRequiredError
126+ ) :
117127 """Return exception for error responses with 4xx status codes."""
118128 if not raw_body :
119129 return HTTPError (
@@ -161,12 +171,12 @@ def _exception_for_web_service_error(
161171 code : str ,
162172 status : int ,
163173 uri : str ,
164- ) -> Union [
165- InvalidRequestError ,
166- AuthenticationError ,
167- PermissionRequiredError ,
168- InsufficientFundsError ,
169- ] :
174+ ) -> (
175+ InvalidRequestError
176+ | AuthenticationError
177+ | PermissionRequiredError
178+ | InsufficientFundsError
179+ ) :
170180 """Return exception for error responses with the JSON body."""
171181 if code in (
172182 "ACCOUNT_ID_REQUIRED" ,
@@ -185,7 +195,7 @@ def _exception_for_web_service_error(
185195 @staticmethod
186196 def _exception_for_5xx_status (
187197 status : int ,
188- raw_body : Optional [ str ] ,
198+ raw_body : str | None ,
189199 uri : str ,
190200 ) -> HTTPError :
191201 """Return exception for error response with 5xx status codes."""
@@ -199,7 +209,7 @@ def _exception_for_5xx_status(
199209 @staticmethod
200210 def _exception_for_unexpected_status (
201211 status : int ,
202- raw_body : Optional [ str ] ,
212+ raw_body : str | None ,
203213 uri : str ,
204214 ) -> HTTPError :
205215 """Return exception for responses with unexpected status codes."""
@@ -215,7 +225,7 @@ class AsyncClient(BaseClient):
215225 """Async client for accessing the minFraud web services."""
216226
217227 _existing_session : aiohttp .ClientSession
218- _proxy : Optional [ str ]
228+ _proxy : str | None
219229
220230 def __init__ (
221231 self ,
@@ -224,7 +234,7 @@ def __init__(
224234 host : str = "minfraud.maxmind.com" ,
225235 locales : Sequence [str ] = ("en" ,),
226236 timeout : float = 60 ,
227- proxy : Optional [ str ] = None ,
237+ proxy : str | None = None ,
228238 ) -> None :
229239 """Construct AsyncClient.
230240
@@ -368,7 +378,7 @@ async def score(
368378
369379 async def report (
370380 self ,
371- report : dict [str , Optional [ str ] ],
381+ report : dict [str , str | None ],
372382 validate : bool = True ,
373383 ) -> None :
374384 """Send a transaction report to the Report Transaction endpoint.
@@ -405,7 +415,7 @@ async def _response_for(
405415 request : dict [str , Any ],
406416 validate : bool ,
407417 hash_email : bool ,
408- ) -> Union [ Score , Factors , Insights ] :
418+ ) -> Score | Factors | Insights :
409419 """Send request and create response object."""
410420 prepared_request = prepare_transaction (request , validate , hash_email )
411421 async with await self ._do_request (uri , prepared_request ) as response :
@@ -443,17 +453,22 @@ async def close(self) -> None:
443453 if hasattr (self , "_existing_session" ):
444454 await self ._existing_session .close ()
445455
446- async def __aenter__ (self ) -> "AsyncClient" :
456+ async def __aenter__ (self ) -> Self :
447457 return self
448458
449- async def __aexit__ (self , exc_type : None , exc_value : None , traceback : None ) -> None :
459+ async def __aexit__ (
460+ self ,
461+ exc_type : type [BaseException ] | None ,
462+ exc_value : BaseException | None ,
463+ traceback : types .TracebackType | None ,
464+ ) -> None :
450465 await self .close ()
451466
452467
453468class Client (BaseClient ):
454469 """Synchronous client for accessing the minFraud web services."""
455470
456- _proxies : Optional [ dict [str , str ]]
471+ _proxies : dict [str , str ] | None
457472 _session : requests .Session
458473
459474 def __init__ (
@@ -463,7 +478,7 @@ def __init__(
463478 host : str = "minfraud.maxmind.com" ,
464479 locales : Sequence [str ] = ("en" ,),
465480 timeout : float = 60 ,
466- proxy : Optional [ str ] = None ,
481+ proxy : str | None = None ,
467482 ) -> None :
468483 """Construct Client.
469484
@@ -619,7 +634,7 @@ def score(
619634 ),
620635 )
621636
622- def report (self , report : dict [str , Optional [ str ] ], validate : bool = True ) -> None :
637+ def report (self , report : dict [str , str | None ], validate : bool = True ) -> None :
623638 """Send a transaction report to the Report Transaction endpoint.
624639
625640 :param report: A dictionary containing the transaction report to be sent
@@ -654,7 +669,7 @@ def _response_for(
654669 request : dict [str , Any ],
655670 validate : bool ,
656671 hash_email : bool ,
657- ) -> Union [ Score , Factors , Insights ] :
672+ ) -> Score | Factors | Insights :
658673 """Send request and create response object."""
659674 prepared_request = prepare_transaction (request , validate , hash_email )
660675
@@ -681,8 +696,13 @@ def close(self) -> None:
681696 """
682697 self ._session .close ()
683698
684- def __enter__ (self ) -> "Client" :
699+ def __enter__ (self ) -> Self :
685700 return self
686701
687- def __exit__ (self , exc_type : None , exc_value : None , traceback : None ) -> None :
702+ def __exit__ (
703+ self ,
704+ exc_type : type [BaseException ] | None ,
705+ exc_value : BaseException | None ,
706+ traceback : types .TracebackType | None ,
707+ ) -> None :
688708 self .close ()
0 commit comments