Skip to content
This repository was archived by the owner on Aug 11, 2020. It is now read-only.

Commit e4cefdd

Browse files
committed
improve error handling
1 parent c009659 commit e4cefdd

File tree

3 files changed

+135
-71
lines changed

3 files changed

+135
-71
lines changed

paperspace/jobs.py

Lines changed: 64 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from . import config
1414
from .login import apikey
15+
from .method import *
1516

1617
def zip_to_tmp(obj_name):
1718
zipname = os.path.join(tempfile.gettempdir(),
@@ -86,20 +87,9 @@ def method(category, method, params):
8687
return requests_exception_to_error_obj(e)
8788

8889
try:
89-
return r.json()
90+
return response_error_check(r.json())
9091
except ValueError:
91-
return status_code_to_error_obj(status_code)
92-
93-
94-
def requests_exception_to_error_obj(e):
95-
return { 'error': { 'message': str(e) } }
96-
97-
98-
def status_code_to_error_obj(status_code):
99-
message = 'unknown'
100-
if status_code in requests.status_codes._codes:
101-
message = requests.status_codes._codes[status_code][0]
102-
return { 'error': { 'message': message, 'status': status_code } }
92+
return status_code_to_error_obj(r.status_code)
10393

10494

10595
def getJobs(params):
@@ -147,41 +137,60 @@ def logs(params, tail=False, no_logging=False):
147137
params['line'] = 0
148138

149139
while True:
150-
r = requests.request('GET', config.CONFIG_LOG_HOST + '/jobs/logs',
151-
headers={'x-api-key': config.PAPERSPACE_API_KEY},
152-
params=params)
153140
try:
154-
res = r.json()
155-
except ValueError:
156-
res = []
157-
if no_logging:
158-
result += res
141+
r = requests.request('GET', config.CONFIG_LOG_HOST + '/jobs/logs',
142+
headers={'x-api-key': config.PAPERSPACE_API_KEY},
143+
params=params)
144+
except requests.exceptions.RequestException as e:
145+
res = requests_exception_to_error_obj(e)
146+
if no_logging:
147+
return res
148+
print_json_pretty(res)
149+
return False
159150
else:
160-
for l in res:
161-
m = l['message']
162-
if m != 'PSEOF':
163-
print(m)
164-
165-
if res:
166-
last_line = res[-1]['line']
167-
PSEOF = res[-1]['message'] == 'PSEOF'
168-
169-
if PSEOF:
170-
break
171-
172-
if last_line > params['line']:
173-
params['line'] = last_line
174-
backoff = 0
175-
continue
176-
177-
if tail:
178-
if backoff:
179-
time.sleep(backoff)
180-
backoff = min(backoff * 2, MAX_BACKOFF)
151+
try:
152+
res = r.json()
153+
if 'error' in res:
154+
if no_logging:
155+
return res
156+
print_json_pretty(res)
157+
if tail:
158+
print('Error: logs tail exited before job completed')
159+
else:
160+
print('Error: logs exited on error')
161+
return False
162+
163+
except ValueError:
164+
res = []
165+
166+
if no_logging:
167+
result += res
181168
else:
182-
backoff = 1
183-
else:
184-
break
169+
for l in res:
170+
m = l['message']
171+
if m != 'PSEOF':
172+
print(m)
173+
174+
if res:
175+
last_line = res[-1]['line']
176+
PSEOF = res[-1]['message'] == 'PSEOF'
177+
178+
if PSEOF:
179+
break
180+
181+
if last_line > params['line']:
182+
params['line'] = last_line
183+
backoff = 0
184+
continue
185+
186+
if tail:
187+
if backoff:
188+
time.sleep(backoff)
189+
backoff = min(backoff * 2, MAX_BACKOFF)
190+
else:
191+
backoff = 1
192+
else:
193+
break
185194

186195
if no_logging:
187196
return result
@@ -224,8 +233,10 @@ def create(params, no_logging=False):
224233

225234
if job['state'] != 'Error':
226235
print('Awaiting logs...')
227-
logs({'jobId': jobId}, tail=True)
228-
job = method('jobs', 'getJob', {'jobId': jobId})
236+
if logs({'jobId': jobId}, tail=True):
237+
job = method('jobs', 'getJob', {'jobId': jobId})
238+
else:
239+
job = waitfor({'jobId': jobId, 'state': 'Stopped'})
229240
if 'state' not in job:
230241
print_json_pretty(job)
231242
return job
@@ -257,7 +268,7 @@ def artifactsGet(params, no_logging=False):
257268
if artifacts_list:
258269

259270
creds = method('jobs', 'artifactsGet', params)
260-
if creds:
271+
if 'bucket' in creds:
261272
bucket = creds['bucket']
262273
folder = creds['folder']
263274
credentials = creds['Credentials']
@@ -295,6 +306,11 @@ def artifactsGet(params, no_logging=False):
295306
return result
296307
print('Download complete')
297308
return True
309+
else:
310+
if no_logging:
311+
return creds
312+
print_json_pretty(creds)
313+
return False
298314

299315
if no_logging:
300316
return result

paperspace/login.py

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,26 @@
66
import requests
77

88
from . import config
9+
from .method import *
910

1011

11-
def errorcheck(res, *args):
12+
def is_error_or_missing_keys_print(res, *required_keys):
1213
if 'error' in res:
14+
if 'message' in res:
15+
print(res['message'])
16+
return True
1317
if 'message' in res['error']:
1418
print(res['error']['message'])
15-
return False
19+
return True
1620
print(json.dumps(res, indent=2, sort_keys=True))
17-
return False
18-
elif not all(key in res for key in args):
21+
return True
22+
elif not all(key in res for key in required_keys):
1923
if 'message' in res:
2024
print(res['message'])
21-
return False
25+
return True
2226
print(json.dumps(res, indent=2, sort_keys=True))
23-
return False
24-
return True
27+
return True
28+
return False
2529

2630

2731
def login(email=None, password=None, apiToken=None):
@@ -34,29 +38,45 @@ def login(email=None, password=None, apiToken=None):
3438
config_data = json.load(open(config_path))
3539

3640
if not email:
37-
email = input('Email: ')
41+
email = raw_input('Email: ')
3842
if not password:
3943
password = getpass.getpass('Password: ')
4044

4145
# get access_token
4246
params = { "email": email, "password": password }
43-
r = requests.request('post', config.CONFIG_HOST + '/users/login',
44-
json=params)
45-
res = r.json()
46-
47-
if not errorcheck(res, 'id'):
48-
return False
47+
try:
48+
r = requests.request('post', config.CONFIG_HOST + '/users/login',
49+
json=params)
50+
except requests.exceptions.RequestException as e:
51+
res = requests_exception_to_error_obj(e)
52+
else:
53+
try:
54+
res = response_error_check(r.json())
55+
except ValueError:
56+
res = status_code_to_error_obj(r.status_code)
57+
58+
if is_error_or_missing_keys_print(res, 'id'):
59+
return False
4960

5061
# get api key using access_token
5162
params = { 'access_token': res['id'] }
5263
if apiToken:
5364
params['apiToken'] = apiToken
54-
r = requests.request('post', config.CONFIG_HOST + '/apiTokens/createPublic',
55-
params=params)
56-
api_token = r.json()
57-
58-
if not errorcheck(api_token, 'key', 'name'):
59-
return False
65+
try:
66+
r = requests.request('post', config.CONFIG_HOST + '/apiTokens/createPublic',
67+
params=params)
68+
except requests.exceptions.RequestException as e:
69+
res = requests_exception_to_error_obj(e)
70+
else:
71+
try:
72+
res = response_error_check(r.json())
73+
except ValueError:
74+
res = status_code_to_error_obj(r.status_code)
75+
76+
if is_error_or_missing_keys_print(res, 'key', 'name'):
77+
return False
78+
79+
api_token = res
6080

6181
# update config.PAPERSPACE_API_KEY
6282
config.PAPERSPACE_API_KEY = api_token['key']
@@ -91,6 +111,14 @@ def logout():
91111
outfile.write('\n')
92112

93113
if __name__ == '__main__':
94-
email, password, apiToken, *rest = sys.argv[1:] + [None] * 3
95-
if not login(email, password, apiToken):
96-
sys.exit(1)
114+
email = None
115+
password = None
116+
apiToken = None
117+
if len(sys.argv) > 1:
118+
email = sys.argv[1]
119+
if len(sys.argv) > 2:
120+
password = sys.argv[2]
121+
if len(sys.argv) > 3:
122+
apiToken = sys.argv[3]
123+
if not login(email, password, apiToken):
124+
sys.exit(1)

paperspace/method.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import requests
2+
3+
4+
def response_error_check(res):
5+
if ('error' not in res
6+
and 'status' in res
7+
and (res['status'] < 200 or res['status'] > 299)):
8+
res['error'] = True
9+
return res
10+
11+
12+
def requests_exception_to_error_obj(e):
13+
return { 'error': True, 'message': str(e) }
14+
15+
16+
def status_code_to_error_obj(status_code):
17+
message = 'unknown'
18+
if status_code in requests.status_codes._codes:
19+
message = requests.status_codes._codes[status_code][0]
20+
return { 'error': True, 'message': message, 'status': status_code }

0 commit comments

Comments
 (0)