55import ipaddress
66import json
77import os
8- import requests
98import sys
9+
10+ import requests
11+
1012from .cache .default import DefaultCache
1113from .details import Details
1214from .exceptions import RequestQuotaExceededError
@@ -18,45 +20,49 @@ class Handler:
1820 and maintains access to cache.
1921 """
2022
21- API_URL = ' https://ipinfo.io'
23+ API_URL = " https://ipinfo.io"
2224CACHE_MAXSIZE = 4096
2325CACHE_TTL = 60 * 60 * 24
24- COUNTRY_FILE_DEFAULT = ' countries.json'
26+ COUNTRY_FILE_DEFAULT = " countries.json"
2527REQUEST_TIMEOUT_DEFAULT = 2
2628
2729def __init__ (self ,access_token = None ,** kwargs ):
2830"""Initialize the Handler object with country name list and the cache initialized."""
2931self .access_token = access_token
30- self .countries = self ._read_country_names (kwargs .get (' countries_file' ))
32+ self .countries = self ._read_country_names (kwargs .get (" countries_file" ))
3133
32- self .request_options = kwargs .get (' request_options' , {})
33- if ' timeout' not in self .request_options :
34- self .request_options [' timeout' ]= self .REQUEST_TIMEOUT_DEFAULT
34+ self .request_options = kwargs .get (" request_options" , {})
35+ if " timeout" not in self .request_options :
36+ self .request_options [" timeout" ]= self .REQUEST_TIMEOUT_DEFAULT
3537
36- if ' cache' in kwargs :
37- self .cache = kwargs [' cache' ]
38+ if " cache" in kwargs :
39+ self .cache = kwargs [" cache" ]
3840else :
39- cache_options = kwargs .get (' cache_options' , {})
40- maxsize = cache_options .get (' maxsize' ,self .CACHE_MAXSIZE )
41- ttl = cache_options .get (' ttl' ,self .CACHE_TTL )
41+ cache_options = kwargs .get (" cache_options" , {})
42+ maxsize = cache_options .get (" maxsize" ,self .CACHE_MAXSIZE )
43+ ttl = cache_options .get (" ttl" ,self .CACHE_TTL )
4244self .cache = DefaultCache (maxsize ,ttl ,** cache_options )
4345
4446def getDetails (self ,ip_address = None ):
4547"""Get details for specified IP address as a Details object."""
4648raw_details = self ._requestDetails (ip_address )
47- raw_details ['country_name' ]= self .countries .get (raw_details .get ('country' ))
48- raw_details ['ip_address' ]= ipaddress .ip_address (raw_details .get ('ip' ))
49- raw_details ['latitude' ],raw_details ['longitude' ]= self ._read_coords (raw_details .get ('loc' ))
49+ raw_details ["country_name" ]= self .countries .get (raw_details .get ("country" ))
50+ raw_details ["ip_address" ]= ipaddress .ip_address (raw_details .get ("ip" ))
51+ raw_details ["latitude" ],raw_details ["longitude" ]= self ._read_coords (
52+ raw_details .get ("loc" )
53+ )
5054return Details (raw_details )
5155
5256def _requestDetails (self ,ip_address = None ):
5357"""Get IP address data by sending request to IPinfo API."""
5458if ip_address not in self .cache :
5559url = self .API_URL
5660if ip_address :
57- url += '/' + ip_address
61+ url += "/" + ip_address
5862
59- response = requests .get (url ,headers = self ._get_headers (),** self .request_options )
63+ response = requests .get (
64+ url ,headers = self ._get_headers (),** self .request_options
65+ )
6066if response .status_code == 429 :
6167raise RequestQuotaExceededError ()
6268response .raise_for_status ()
@@ -67,26 +73,30 @@ def _requestDetails(self, ip_address=None):
6773def _get_headers (self ):
6874"""Built headers for request to IPinfo API."""
6975headers = {
70- 'user-agent' :'IPinfoClient/Python{version}/1.0' .format (version = sys .version_info [0 ]),
71- 'accept' :'application/json'
76+ "user-agent" :"IPinfoClient/Python{version}/1.0" .format (
77+ version = sys .version_info [0 ]
78+ ),
79+ "accept" :"application/json" ,
7280 }
7381
7482if self .access_token :
75- headers [' authorization' ]= ' Bearer {}' .format (self .access_token )
83+ headers [" authorization" ]= " Bearer {}" .format (self .access_token )
7684
7785return headers
7886
7987def _read_coords (self ,location ):
8088lat ,lon = None ,None
81- coords = tuple (location .split (',' ))if location else ''
89+ coords = tuple (location .split ("," ))if location else ""
8290if len (coords )== 2 and coords [0 ]and coords [1 ]:
8391lat ,lon = coords [0 ],coords [1 ]
8492return lat ,lon
8593
8694def _read_country_names (self ,countries_file = None ):
8795"""Read list of countries from specified country file or default file."""
8896if not countries_file :
89- countries_file = os .path .join (os .path .dirname (__file__ ),self .COUNTRY_FILE_DEFAULT )
97+ countries_file = os .path .join (
98+ os .path .dirname (__file__ ),self .COUNTRY_FILE_DEFAULT
99+ )
90100with open (countries_file )as f :
91101countries_json = f .read ()
92102