4747from geoip2 .types import IPAddress
4848
4949
50- class Client :
51- """Creates a new client object.
52-
53- It accepts the following required arguments:
54-
55- :param account_id: Your MaxMind account ID.
56- :param license_key: Your MaxMind license key.
57-
58- Go to https://www.maxmind.com/en/my_license_key to see your MaxMind
59- account ID and license key.
60-
61- The following keyword arguments are also accepted:
62-
63- :param host: The hostname to make a request against. This defaults to
64- "geoip.maxmind.com". In most cases, you should not need to set this
65- explicitly.
66- :param locales: This is list of locale codes. This argument will be
67- passed on to record classes to use when their name properties are
68- called. The default value is ['en'].
69-
70- The order of the locales is significant. When a record class has
71- multiple names (country, city, etc.), its name property will return
72- the name in the first locale that has one.
73-
74- Note that the only locale which is always present in the GeoIP2
75- data is "en". If you do not include this locale, the name property
76- may end up returning None even when the record has an English name.
77-
78- Currently, the valid locale codes are:
79-
80- * de -- German
81- * en -- English names may still include accented characters if that is
82- the accepted spelling in English. In other words, English does not
83- mean ASCII.
84- * es -- Spanish
85- * fr -- French
86- * ja -- Japanese
87- * pt-BR -- Brazilian Portuguese
88- * ru -- Russian
89- * zh-CN -- Simplified Chinese.
90- :param timeout: The timeout to use when waiting on the request. This sets
91- both the connect timeout and the read timeout.
92-
93- """
50+ class BaseClient : # pylint: disable=missing-class-docstring
51+ _account_id : str
52+ _host : str
53+ _license_key : str
54+ _locales : List [str ]
55+ _timeout : Optional [float ]
56+ _user_agent : str
9457
9558 def __init__ (
9659 self ,
9760 account_id : int ,
9861 license_key : str ,
99- host : str = "geoip.maxmind.com" ,
100- locales : Optional [List [str ]] = None ,
101- timeout : Optional [float ] = None ,
62+ host : str ,
63+ locales : Optional [List [str ]],
64+ timeout : Optional [float ],
65+ http_user_agent : str ,
10266 ) -> None :
10367 """Construct a Client."""
10468 # pylint: disable=too-many-arguments
@@ -114,6 +78,10 @@ def __init__(
11478 self ._license_key = license_key
11579 self ._base_uri = "https://%s/geoip/v2.1" % host
11680 self ._timeout = timeout
81+ self ._user_agent = "GeoIP2-Python-Client/%s %s" % (
82+ geoip2 .__version__ ,
83+ http_user_agent ,
84+ )
11785
11886 def city (self , ip_address : IPAddress = "me" ) -> City :
11987 """Call GeoIP2 Precision City endpoint with the specified IP.
@@ -167,21 +135,14 @@ def _response_for(
167135 response = requests .get (
168136 uri ,
169137 auth = (self ._account_id , self ._license_key ),
170- headers = {"Accept" : "application/json" , "User-Agent" : self ._user_agent () },
138+ headers = {"Accept" : "application/json" , "User-Agent" : self ._user_agent },
171139 timeout = self ._timeout ,
172140 )
173141 if response .status_code != 200 :
174142 raise self ._exception_for_error (response , uri )
175143 body = self ._handle_success (response , uri )
176144 return model_class (body , locales = self ._locales )
177145
178- @staticmethod
179- def _user_agent () -> str :
180- return "GeoIP2 Python Client v%s (%s)" % (
181- geoip2 .__version__ ,
182- default_user_agent (),
183- )
184-
185146 @staticmethod
186147 def _handle_success (response : Response , uri : str ) -> Any :
187148 try :
@@ -284,3 +245,81 @@ def _exception_for_non_200_status(status: int, uri: str) -> HTTPError:
284245 status ,
285246 uri ,
286247 )
248+
249+
250+ class Client (BaseClient ):
251+ """A synchronous GeoIP2 client.
252+
253+ It accepts the following required arguments:
254+
255+ :param account_id: Your MaxMind account ID.
256+ :param license_key: Your MaxMind license key.
257+
258+ Go to https://www.maxmind.com/en/my_license_key to see your MaxMind
259+ account ID and license key.
260+
261+ The following keyword arguments are also accepted:
262+
263+ :param host: The hostname to make a request against. This defaults to
264+ "geoip.maxmind.com". In most cases, you should not need to set this
265+ explicitly.
266+ :param locales: This is list of locale codes. This argument will be
267+ passed on to record classes to use when their name properties are
268+ called. The default value is ['en'].
269+
270+ The order of the locales is significant. When a record class has
271+ multiple names (country, city, etc.), its name property will return
272+ the name in the first locale that has one.
273+
274+ Note that the only locale which is always present in the GeoIP2
275+ data is "en". If you do not include this locale, the name property
276+ may end up returning None even when the record has an English name.
277+
278+ Currently, the valid locale codes are:
279+
280+ * de -- German
281+ * en -- English names may still include accented characters if that is
282+ the accepted spelling in English. In other words, English does not
283+ mean ASCII.
284+ * es -- Spanish
285+ * fr -- French
286+ * ja -- Japanese
287+ * pt-BR -- Brazilian Portuguese
288+ * ru -- Russian
289+ * zh-CN -- Simplified Chinese.
290+ :param timeout: The timeout to use when waiting on the request. This sets
291+ both the connect timeout and the read timeout.
292+
293+ """
294+
295+ def __init__ ( # pylint: disable=too-many-arguments
296+ self ,
297+ account_id : int ,
298+ license_key : str ,
299+ host : str = "geoip.maxmind.com" ,
300+ locales : Optional [List [str ]] = None ,
301+ timeout : Optional [float ] = None ,
302+ ) -> None :
303+ super ().__init__ (
304+ account_id , license_key , host , locales , timeout , default_user_agent ()
305+ )
306+
307+ def _response_for (
308+ self ,
309+ path : str ,
310+ model_class : Union [Type [Insights ], Type [City ], Type [Country ]],
311+ ip_address : IPAddress ,
312+ ) -> Union [Country , City , Insights ]:
313+ if ip_address != "me" :
314+ ip_address = ipaddress .ip_address (ip_address )
315+ uri = "/" .join ([self ._base_uri , path , str (ip_address )])
316+ response = requests .get (
317+ uri ,
318+ auth = (self ._account_id , self ._license_key ),
319+ headers = {"Accept" : "application/json" , "User-Agent" : self ._user_agent },
320+ timeout = self ._timeout ,
321+ )
322+ if response .status_code != 200 :
323+ raise self ._exception_for_error (response , uri )
324+ body = self ._handle_success (response , uri )
325+ return model_class (body , locales = self ._locales )
0 commit comments