Skip to content

Commit 64ab2a9

Browse files
Merge pull request #25 from Paperspace/PS-10385-Refactor-logger-module
Refactor logger module
2 parents e60c7d6 + e7b4a10 commit 64ab2a9

File tree

13 files changed

+310
-105
lines changed

13 files changed

+310
-105
lines changed

gradient/client.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99

1010
class API(object):
11-
def __init__(self, api_url, headers=None, api_key=None):
11+
def __init__(self, api_url, headers=None, api_key=None, logger_=logger.Logger()):
1212
self.api_url = api_url
1313
headers = headers or default_headers
1414
self.headers = headers.copy()
1515
if api_key:
1616
self.api_key = api_key
17+
self.logger = logger_
1718

1819
@property
1920
def api_key(self):
@@ -30,36 +31,36 @@ def get_path(self, url):
3031

3132
def post(self, url, json=None, params=None, files=None, data=None):
3233
path = self.get_path(url)
33-
logger.debug("POST request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}\n\tfiles: {}\n\tdata: {}"
34+
self.logger.debug("POST request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}\n\tfiles: {}\n\tdata: {}"
3435
.format(path, self.headers, json, params, files, data))
3536
response = requests.post(path, json=json, params=params, headers=self.headers, files=files, data=data)
36-
logger.debug("Response status code: {}".format(response.status_code))
37-
logger.debug("Response content: {}".format(response.content))
37+
self.logger.debug("Response status code: {}".format(response.status_code))
38+
self.logger.debug("Response content: {}".format(response.content))
3839
return response
3940

4041
def put(self, url, json=None, params=None):
4142
path = self.get_path(url)
42-
logger.debug("PUT request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}"
43+
self.logger.debug("PUT request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}"
4344
.format(path, self.headers, json, params))
4445
response = requests.put(path, json=json, params=params, headers=self.headers)
45-
logger.debug("Response status code: {}".format(response.status_code))
46-
logger.debug("Response content: {}".format(response.content))
46+
self.logger.debug("Response status code: {}".format(response.status_code))
47+
self.logger.debug("Response content: {}".format(response.content))
4748
return response
4849

4950
def get(self, url, json=None, params=None):
5051
path = self.get_path(url)
51-
logger.debug("GET request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}"
52+
self.logger.debug("GET request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}"
5253
.format(path, self.headers, json, params))
5354
response = requests.get(path, params=params, headers=self.headers, json=json)
54-
logger.debug("Response status code: {}".format(response.status_code))
55-
logger.debug("Response content: {}".format(response.content))
55+
self.logger.debug("Response status code: {}".format(response.status_code))
56+
self.logger.debug("Response content: {}".format(response.content))
5657
return response
5758

5859
def delete(self, url, json=None, params=None):
5960
path = self.get_path(url)
6061
response = requests.delete(path, params=params, headers=self.headers, json=json)
61-
logger.debug("DELETE request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}"
62+
self.logger.debug("DELETE request sent to: {} \n\theaders: {}\n\tjson: {}\n\tparams: {}"
6263
.format(response.url, self.headers, json, params))
63-
logger.debug("Response status code: {}".format(response.status_code))
64-
logger.debug("Response content: {}".format(response.content))
64+
self.logger.debug("Response status code: {}".format(response.status_code))
65+
self.logger.debug("Response content: {}".format(response.content))
6566
return response

gradient/commands/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
class CommandBase(object):
12-
def __init__(self, api=None, logger_=logger):
12+
def __init__(self, api=None, logger_=logger.Logger()):
1313
self.api = api
1414
self.logger = logger_
1515

gradient/commands/experiments.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
from gradient import logger, constants, client, config
88
from gradient.commands import common
9-
from gradient.logger import log_response
109
from gradient.utils import get_terminal_lines
1110
from gradient.workspace import S3WorkspaceHandler
1211

@@ -16,7 +15,7 @@
1615
class ExperimentCommand(common.CommandBase):
1716
def __init__(self, workspace_handler=None, **kwargs):
1817
super(ExperimentCommand, self).__init__(**kwargs)
19-
self._workspace_handler = workspace_handler or S3WorkspaceHandler(experiments_api=self.api, logger=self.logger)
18+
self._workspace_handler = workspace_handler or S3WorkspaceHandler(experiments_api=self.api, logger_=self.logger)
2019

2120
def _log_create_experiment(self, response, success_msg_template, error_msg):
2221
if response.ok:
@@ -62,16 +61,16 @@ def execute(self, json_):
6261
return None
6362

6463

65-
def start_experiment(experiment_id, api=experiments_api):
64+
def start_experiment(experiment_id, api=experiments_api, logger_=logger.Logger()):
6665
url = "/experiments/{}/start/".format(experiment_id)
6766
response = api.put(url)
68-
log_response(response, "Experiment started", "Unknown error while starting the experiment")
67+
logger_.log_response(response, "Experiment started", "Unknown error while starting the experiment")
6968

7069

71-
def stop_experiment(experiment_id, api=experiments_api):
70+
def stop_experiment(experiment_id, api=experiments_api, logger_=logger.Logger()):
7271
url = "/experiments/{}/stop/".format(experiment_id)
7372
response = api.put(url)
74-
log_response(response, "Experiment stopped", "Unknown error while stopping the experiment")
73+
logger_.log_response(response, "Experiment stopped", "Unknown error while stopping the experiment")
7574

7675

7776
class ListExperimentsCommand(common.ListCommand):
@@ -165,7 +164,7 @@ def _make_details_table(experiment):
165164
return table_string
166165

167166

168-
def get_experiment_details(experiment_id, api=experiments_api):
167+
def get_experiment_details(experiment_id, api=experiments_api, logger_=logger.Logger()):
169168
url = "/experiments/{}/".format(experiment_id)
170169
response = api.get(url)
171170
details = response.content
@@ -174,9 +173,9 @@ def get_experiment_details(experiment_id, api=experiments_api):
174173
experiment = response.json()["data"]
175174
details = _make_details_table(experiment)
176175
except (ValueError, KeyError) as e:
177-
logger.error("Error parsing response data")
176+
logger_.error("Error parsing response data")
178177

179-
log_response(response, details, "Unknown error while retrieving details of the experiment")
178+
logger_.log_response(response, details, "Unknown error while retrieving details of the experiment")
180179

181180

182181
class ExperimentLogsCommand(common.CommandBase):

gradient/commands/jobs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def _make_table(self, logs, table, table_data):
146146
class CreateJobCommand(JobsCommandBase):
147147
def __init__(self, workspace_handler=None, **kwargs):
148148
super(CreateJobCommand, self).__init__(**kwargs)
149-
self._workspace_handler = workspace_handler or WorkspaceHandler(logger=self.logger)
149+
self._workspace_handler = workspace_handler or WorkspaceHandler(logger_=self.logger)
150150

151151
def execute(self, json_):
152152
url = "/jobs/createJob/"

gradient/commands/run.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class RunCommand(object):
1111

12-
def __init__(self, api=None, logger_=logger):
12+
def __init__(self, api=None, logger_=logger.Logger()):
1313
self.api = api
1414
self.logger = logger_
1515

gradient/logger.py

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,70 @@
11
import click
2-
from six import string_types
2+
import six
33

44
from .config import config
55

66

7-
def _log(message, color=None, err=False):
8-
message = str(message)
9-
color = color if config.USE_CONSOLE_COLORS else None
10-
click.secho(message, fg=color, err=err)
11-
12-
13-
def log(message, color=None, err=False):
14-
_log(message, color=color, err=err)
15-
16-
17-
def error(message):
18-
color = "red" if config.USE_CONSOLE_COLORS else None
19-
_log(message, color=color, err=True)
20-
21-
22-
def warning(message):
23-
color = "yellow" if config.USE_CONSOLE_COLORS else None
24-
_log(message, color=color)
25-
26-
27-
def log_error_response(data):
28-
error_str = data.get("error")
29-
details = data.get("details")
30-
message = data.get("message")
31-
32-
if not any((error_str, details, message)):
33-
raise ValueError("No error messages found")
34-
35-
if error_str:
36-
try:
37-
error(error_str["message"])
38-
except (KeyError, TypeError):
39-
error(str(error_str))
40-
41-
if details:
42-
if isinstance(details, dict):
43-
for key, val in details.items():
44-
if isinstance(val, string_types):
45-
val = [val]
46-
47-
for v in val:
48-
msg = "{}: {}".format(key, str(v))
49-
error(msg)
7+
class Logger(object):
8+
def _log(self, message, color=None, err=False):
9+
message = str(message)
10+
color = color if config.USE_CONSOLE_COLORS else None
11+
click.secho(message, fg=color, err=err)
12+
13+
def log(self, message, color=None, err=False):
14+
self._log(message, color=color, err=err)
15+
16+
def error(self, message):
17+
color = "red" if config.USE_CONSOLE_COLORS else None
18+
self._log(message, color=color, err=True)
19+
20+
def warning(self, message):
21+
color = "yellow" if config.USE_CONSOLE_COLORS else None
22+
self._log(message, color=color)
23+
24+
def log_error_response(self, data):
25+
messages = list(self._get_error_messages(data))
26+
msg = "\n".join(messages)
27+
28+
if not msg:
29+
raise ValueError("No error messages found")
30+
31+
self.error(msg)
32+
33+
def _get_error_messages(self, data, add_prefix=False):
34+
if isinstance(data, dict):
35+
for key, value in sorted(data.items()):
36+
if key in ("error", "errors", "message", "messages"):
37+
for message in self._get_error_messages(value):
38+
yield message
39+
40+
# when key == "details" and value is a dict then values should be prefixed with key
41+
if add_prefix:
42+
for message in self._get_error_messages(value):
43+
# there is some useless message in data["context"]
44+
if key != "context":
45+
yield key + ": " + message
46+
if key == "details":
47+
for message in self._get_error_messages(value, add_prefix=True):
48+
yield message
49+
50+
if isinstance(data, list):
51+
for element in data:
52+
for message in self._get_error_messages(element):
53+
yield message
54+
55+
if isinstance(data, six.string_types):
56+
yield data
57+
58+
def debug(self, message):
59+
if config.DEBUG:
60+
self._log("DEBUG: {}".format(message))
61+
62+
def log_response(self, response, success_msg, error_msg):
63+
if response.ok:
64+
self._log(success_msg)
5065
else:
51-
error(details)
52-
53-
if message:
54-
error(str(message))
55-
56-
57-
def debug(message):
58-
if config.DEBUG:
59-
log("DEBUG: {}".format(message))
60-
61-
62-
def log_response(response, success_msg, error_msg):
63-
if response.ok:
64-
log(success_msg)
65-
else:
66-
try:
67-
data = response.json()
68-
log_error_response(data)
69-
except ValueError:
70-
error(error_msg)
66+
try:
67+
data = response.json()
68+
self.log_error_response(data)
69+
except ValueError:
70+
self.error(error_msg)

gradient/version_checker.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
import xmlrpc.client as xmlrpclib
1414

1515

16+
logger = logger.Logger()
17+
18+
1619
class PackageNotFoundError(Exception):
1720
pass
1821

gradient/wizards/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)