|
1 | 1 |
|
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 | +''' |
8 | 3 |
|
| 4 | +IP Address Location & Geolocation API |
9 | 5 |
|
10 | | -API_KEY = '' |
| 6 | +(c) ipapi by Kloudend, Inc. | https://ipapi.co/ |
11 | 7 |
|
12 | | -headers = {'user-agent': 'ipapi/ipapi-python/0.5.1'} |
| 8 | +API Docs : https://ipapi.co/api/ |
13 | 9 |
|
14 | | -field_list = ['ip', 'city', 'region', 'country', 'postal', |
15 | | - 'latitude', 'longitude', 'timezone', 'latlong'] |
| 10 | +''' |
16 | 11 |
|
| 12 | +from requests import get |
17 | 13 |
|
| 14 | +try: |
| 15 | + from .exceptions import RateLimited, PageNotFound, AuthorizationFailed |
| 16 | +except (SystemError, ImportError): |
| 17 | + from exceptions import RateLimited, PageNotFound, AuthorizationFailed |
18 | 18 |
|
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 | | - ''' |
24 | 19 |
|
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'] |
27 | 25 |
|
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/' |
38 | 26 |
|
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/' |
41 | 29 |
|
42 | | - response = get(url, headers=headers) |
| 30 | + if ip: |
| 31 | + url = '{}{}/'.format(url, ip) |
43 | 32 |
|
44 | | - if field: |
45 | | - return response.text |
46 | | - else: |
47 | | - return response.json() |
| 33 | + url = '{}{}/'.format(url, output) |
48 | 34 |
|
| 35 | + if key: |
| 36 | + url = '{}?key={}'.format(url, key) |
49 | 37 |
|
| 38 | + return url |
50 | 39 |
|
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) |
58 | 40 |
|
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) |
64 | 90 |
|
0 commit comments