-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmisc.py
87 lines (73 loc) · 2.41 KB
/
misc.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
Miscellaneous utility functions
"""
import time
import json
from pprint import pformat
import requests
def elapsed_time_hms(start_time):
"""
Get time elapsed since start_time in hh:mm:ss str format
"""
elapsed = time.time() - start_time
return time.strftime('%H:%M:%S', time.gmtime(elapsed))
def send_request(method, *args, ignore_status_codes=None, **kwargs):
"""Send http request. Raise exception on status_code >= 300
:param method: name of the requests method to call
:type method: str
:raises: requests.Exception.HTTPError
:returns: requests Response object
:rtype: requests.Response
"""
if isinstance(ignore_status_codes, str):
ignore_status_codes = [ignore_status_codes]
# NOTE: Set timeout so requests don't hang
# See https://requests.readthedocs.io/en/latest/user/advanced/#timeouts
if not kwargs.get("timeout"):
# connect timeout, read timeout
kwargs["timeout"] = (3, 60)
else:
print(
f"⌚️ Applying user timeout: {kwargs['timeout']} (connect, read)"
" seconds to request"
)
requests_op = getattr(requests, method.lower())
status_code = 0
try:
resp = requests_op(*args, **kwargs)
status_code = resp.status_code
resp.raise_for_status()
except requests.exceptions.HTTPError as e:
if ignore_status_codes and (status_code in ignore_status_codes):
pass
else:
body = ""
try:
body = pformat(resp.json())
except:
body = resp.text
msg = (
f"❌ Problem sending {method} request to server\n"
f"{str(e)}\n"
f"args: {args}\n"
f"kwargs: {pformat(kwargs)}\n"
f"{body}\n"
)
print(msg)
raise e
return resp
def read_json(filepath, default=None):
"""
Read JSON file into Python dict. If default is not None and the file
does not exist, then return default.
:param filepath: path to JSON file
:type filepath: str
:param default: default return value if file not found, defaults to None
:type default: any, optional
:returns: your data
:rtype: dict
"""
if (default is not None) and (not os.path.isfile(filepath)):
return default
with open(filepath, "r") as json_file:
return json.load(json_file)