-
Notifications
You must be signed in to change notification settings - Fork 57
/
4a-timeout-with-wait-kwarg.py
69 lines (50 loc) · 1.71 KB
/
4a-timeout-with-wait-kwarg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import time
import random
import asyncio
import aiohttp
import argparse
from collections import namedtuple
from concurrent.futures import FIRST_COMPLETED
Service = namedtuple('Service', ('name', 'url', 'ip_attr'))
SERVICES = (
Service('ipify', 'https://api.ipify.org?format=json', 'ip'),
Service('ip-api', 'http://ip-api.com/json', 'query'),
)
DEFAULT_TIMEOUT = 0.01
async def aiohttp_get_json(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
async def fetch_ip(service):
start = time.time()
print('Fetching IP from {}'.format(service.name))
await asyncio.sleep(random.randint(1, 3) * 0.1)
try:
json_response = await aiohttp_get_json(service.url)
except:
return '{} is unresponsive'.format(service.name)
ip = json_response[service.ip_attr]
print('{} finished with result: {}, took: {:.2f} seconds'.format(
service.name, ip, time.time() - start))
return ip
async def main(timeout):
response = {
"message": "Result from asynchronous.",
"ip": "not available"
}
futures = [fetch_ip(service) for service in SERVICES]
done, pending = await asyncio.wait(
futures, timeout=timeout, return_when=FIRST_COMPLETED)
for future in pending:
future.cancel()
for future in done:
response["ip"] = future.result()
print(response)
parser = argparse.ArgumentParser()
parser.add_argument(
'-t', '--timeout',
help='Timeout to use, defaults to {}'.format(DEFAULT_TIMEOUT),
default=DEFAULT_TIMEOUT, type=float)
args = parser.parse_args()
print("Using a {} timeout".format(args.timeout))
asyncio.run(main(args.timeout))