Skip to content

Commit 4d113d8

Browse files
authored
Update ipapi.py
1 parent d21f3a9 commit 4d113d8

File tree

1 file changed

+72
-46
lines changed

1 file changed

+72
-46
lines changed

ipapi/ipapi.py

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,90 @@
11

2-
# ipapi Python bindings (https://ipapi.co)
3-
# API docs at https://ipapi.co/api
4-
5-
import sys
6-
import argparse
7-
from requests import get
2+
'''
83
4+
IP Address Location & Geolocation API
95
10-
API_KEY = ''
6+
(c) ipapi by Kloudend, Inc. | https://ipapi.co/
117
12-
headers = {'user-agent': 'ipapi/ipapi-python/0.5.1'}
8+
API Docs : https://ipapi.co/api/
139
14-
field_list = ['ip', 'city', 'region', 'country', 'postal',
15-
'latitude', 'longitude', 'timezone', 'latlong']
10+
'''
1611

12+
from requests import get
1713

14+
try:
15+
from .exceptions import RateLimited, PageNotFound, AuthorizationFailed
16+
except (SystemError, ImportError):
17+
from exceptions import RateLimited, PageNotFound, AuthorizationFailed
1818

19-
def location(ip=None, key=None, field=None):
20-
''' Get geolocation data for a given IP address
21-
If field is specified, get specific field as text
22-
Else get complete location data as JSON
23-
'''
2419

25-
if field and (field not in field_list):
26-
return 'Invalid field'
20+
field_list = ['ip', 'city', 'region', 'region_code', 'country', 'country_code', 'country_code_iso3',
21+
'country_capital', 'country_tld', 'country_name', 'continent_code', 'in_eu', 'postal',
22+
'latitude', 'longitude', 'timezone', 'utc_offset', 'country_calling_code', 'currency',
23+
'currency_name', 'languages', 'country_area', 'country_population', 'latlong',
24+
'asn', 'org']
2725

28-
if field:
29-
if ip:
30-
url = 'https://ipapi.co/{}/{}/'.format(ip, field)
31-
else:
32-
url = 'https://ipapi.co/{}/'.format(field)
33-
else:
34-
if ip:
35-
url = 'https://ipapi.co/{}/json/'.format(ip)
36-
else:
37-
url = 'https://ipapi.co/json/'
3826

39-
if key or API_KEY:
40-
url = '{}?key={}'.format(url, (key or API_KEY))
27+
def build_url(ip, key, output):
28+
url = 'https://ipapi.co/'
4129

42-
response = get(url, headers=headers)
30+
if ip:
31+
url = '{}{}/'.format(url, ip)
4332

44-
if field:
45-
return response.text
46-
else:
47-
return response.json()
33+
url = '{}{}/'.format(url, output)
4834

35+
if key:
36+
url = '{}?key={}'.format(url, key)
4937

38+
return url
5039

51-
def main(argv=None):
52-
argv = argv or sys.argv[1:]
53-
parser = argparse.ArgumentParser(description='IP address location API : https://ipapi.co')
54-
parser.add_argument('-i', '--ip', dest='ip', help='IP address', default=None)
55-
parser.add_argument('-f', '--field', dest='field', help='specific field e.g. {}'.format(', '.join(field_list)))
56-
parser.add_argument('-k', '--key', dest='key', help='API key', default=None)
57-
args = parser.parse_args(argv)
5840

59-
print (location(args.ip, args.key, args.field))
60-
61-
62-
if __name__ == "__main__":
63-
sys.exit(main())
41+
def parse_response(resp):
42+
if resp.headers['Content-Type'] == 'application/json':
43+
return resp.json()
44+
else:
45+
return resp.text
46+
47+
48+
def location(ip=None, key=None, output=None, options=None):
49+
'''
50+
Get Geolocation data and related information for an IP address
51+
52+
- ip : IP Address (IPv4 or IPv6) that you wish to locate.
53+
If omitted, it defaults to the your machine's IP
54+
- key : API key (for paid plans).
55+
Omit it or set key=None for usage under free IP Location tier.
56+
- output : The desired output from the API.
57+
For complete IP location object, valid values are json, csv, xml, yaml.
58+
To retrieve a specific field (e.g. city, country etc. as text), valid values are [1].
59+
If omitted or None, gets the entire location data as json
60+
- options : request options supported by python requests library
61+
62+
'''
63+
64+
if output is None:
65+
output = 'json'
66+
67+
if options is None:
68+
options = {}
69+
70+
url = build_url(ip, key, output)
71+
72+
headers = {
73+
'user-agent': 'ipapi.co/#ipapi-python-v1.0.4'
74+
}
75+
76+
resp = get(url, headers=headers, **options)
77+
78+
data = parse_response(resp)
79+
80+
if resp.status_code == 200:
81+
return data
82+
elif resp.status_code == 403:
83+
raise AuthorizationFailed(data)
84+
elif resp.status_code == 404:
85+
raise PageNotFound(data)
86+
elif resp.status_code == 429:
87+
raise RateLimited(data)
88+
else:
89+
raise Exception(data)
6490

0 commit comments

Comments
 (0)