diff --git a/.travis.yml b/.travis.yml index 841e454..702cf4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,3 @@ -language: python -python: -- '2.7' -install: -- pip install . -- pip install unittest2 -script: -- echo "No tests" before_deploy: - wget https://github.com/jgm/pandoc/releases/download/1.19.1/pandoc-1.19.1-1-amd64.deb -O $TRAVIS_BUILD_DIR/pandoc.deb @@ -18,37 +10,44 @@ deploy: api_key: secure: siQVd277FRApq4RSiq3149zA+2OcPVu7wmh0Qv/U5AUBTJRv4sKP9VV8lKLjgKmmFUsq2lxxe+ENPk66jD0OSp4ZBHTdVAI2k3W9xeuUO/b8ol+peXt78uOnuNIdNyrJPuQYcPVhzKaeUh5lBmLGQrOCJi10foPJK6r2zkvMAB6jvvYhczE/KWCpBKLmC1YI2fwlqUWPeO6agLDnZ3XhHxJaKkTwcBAmQ50qWaUaMf/E8TMfz7L+cGedVBaR1ml6+Te1NN5uw09y/RaEb9UVYREz4zgYz5dhevmXiX8OG9pSxwJApIsejF47LYI2xoIjhaeysf1RpsYurbz3BFUHT9cVaP3BkBNiDRenPrhhyAPe+U/Xv5N9CWn9t7rKB/0gncBx+GyVgAKu5EkyHuGWhOA5knMWaUAB057w5hKBBKReYclrtNlPUWYjAE/s3vTaUSuUej1bCRr9y1noIiMxwGeYTwGfc3TFoMJVFVM6SBN7E22l5PHISqcjBch2/dtCsaHHdxi5PIxb61UPSREQ6c6hzIfu2gWrKpLuDFs8z78xxGUrG4peIRr3jZ6MUhi0Fw1LFFkKSvtXe3HQ2sdzMy7G91gj5hajtPXJ+ZWV6xvS5FU/Vh2bZroJvhnOJM9OV+qjI596OZ19E6XfA3BwHwS+cFG7jLD2+e8fFSe/Hz0= file: - - LICENSE - - README.md - - setup.py - - basescript/basescript.py - - basescript/__init__.py - - basescript/log.py - - basescript/utils.py - - examples/adder.py - - examples/helloworld.py + - LICENSE + - README.md + - setup.py + - basescript/basescript.py + - basescript/__init__.py + - basescript/log.py + - basescript/utils.py + - examples/adder.py + - examples/helloworld.py name: basescript-0.3.1 tag_name: 0.3.1 - on: + true: repo: deep-compute/basescript - provider: pypi - distributions: "sdist bdist_wheel" + distributions: sdist bdist_wheel server: https://test.pypi.org/legacy/ skip_cleanup: true - user: "deepcompute" + user: deepcompute password: - secure: "fkHbFReSrTMDhMP1T26rlk0jVwmWyz8AkJqjThLWd0JBzxpAzLpeDCweCFuJk9hk1bnVnbJN/SgRBcRyYDkGCrarEtu3WkesGnIaqFKbMnu5Zwytex3ghPDK4ZK6+GVYSyljbYJUYXDZLMRoumiMOm7IHGVZ8soA02XNy7lBe36o5Dj3QfpRGUZLb2/nbMWIBvltecuhMk66yWKkSlwy0RjsOTn9XwjtTr5hGC6XD9kdC6NUeK6eSmdU/pa6DyOVSoKXEBims100g4gfOck5P8gXq8ssGVnWDkU9pvTKz085ayeepVDMygI5xug1U2zM3dTvTsRnsjr3B4FsAewfc9uh/sfFpr3v2oOIdUARf2sphJEja+0Z606s9DfxFMWHopouG9JDmzPwZBJNhJRIVW93VfODsUPejKtWJd259SfNRioj+ORP4b7wVQVfjvZM5CifDKrlMTBp1adt4bE8C/DepcezwgKLjRiGU0N0ndg7oJ9XcxUppzOwtEAPx0rLymWCz03O2gCXbr5NrtFZ/kbzPpMhDW1cnSW8zTzSQpzpXrqj5la+KIBynIp+EQZdxvM3NOyHFkpswOr1bsaFSmJ96ejrohIUq95FamQI6l8yo8iJiqROTLw6YUbcLa+F8qEP8ZdthPv98uV0ZAddduO9nysWzu2Hit3bXT4dQ3U=" - on: + secure: fkHbFReSrTMDhMP1T26rlk0jVwmWyz8AkJqjThLWd0JBzxpAzLpeDCweCFuJk9hk1bnVnbJN/SgRBcRyYDkGCrarEtu3WkesGnIaqFKbMnu5Zwytex3ghPDK4ZK6+GVYSyljbYJUYXDZLMRoumiMOm7IHGVZ8soA02XNy7lBe36o5Dj3QfpRGUZLb2/nbMWIBvltecuhMk66yWKkSlwy0RjsOTn9XwjtTr5hGC6XD9kdC6NUeK6eSmdU/pa6DyOVSoKXEBims100g4gfOck5P8gXq8ssGVnWDkU9pvTKz085ayeepVDMygI5xug1U2zM3dTvTsRnsjr3B4FsAewfc9uh/sfFpr3v2oOIdUARf2sphJEja+0Z606s9DfxFMWHopouG9JDmzPwZBJNhJRIVW93VfODsUPejKtWJd259SfNRioj+ORP4b7wVQVfjvZM5CifDKrlMTBp1adt4bE8C/DepcezwgKLjRiGU0N0ndg7oJ9XcxUppzOwtEAPx0rLymWCz03O2gCXbr5NrtFZ/kbzPpMhDW1cnSW8zTzSQpzpXrqj5la+KIBynIp+EQZdxvM3NOyHFkpswOr1bsaFSmJ96ejrohIUq95FamQI6l8yo8iJiqROTLw6YUbcLa+F8qEP8ZdthPv98uV0ZAddduO9nysWzu2Hit3bXT4dQ3U= + true: branch: master tags: false - # pypi - provider: pypi - distributions: "sdist bdist_wheel" + distributions: sdist bdist_wheel skip_cleanup: true - user: "deepcompute" - password: - secure: "fkHbFReSrTMDhMP1T26rlk0jVwmWyz8AkJqjThLWd0JBzxpAzLpeDCweCFuJk9hk1bnVnbJN/SgRBcRyYDkGCrarEtu3WkesGnIaqFKbMnu5Zwytex3ghPDK4ZK6+GVYSyljbYJUYXDZLMRoumiMOm7IHGVZ8soA02XNy7lBe36o5Dj3QfpRGUZLb2/nbMWIBvltecuhMk66yWKkSlwy0RjsOTn9XwjtTr5hGC6XD9kdC6NUeK6eSmdU/pa6DyOVSoKXEBims100g4gfOck5P8gXq8ssGVnWDkU9pvTKz085ayeepVDMygI5xug1U2zM3dTvTsRnsjr3B4FsAewfc9uh/sfFpr3v2oOIdUARf2sphJEja+0Z606s9DfxFMWHopouG9JDmzPwZBJNhJRIVW93VfODsUPejKtWJd259SfNRioj+ORP4b7wVQVfjvZM5CifDKrlMTBp1adt4bE8C/DepcezwgKLjRiGU0N0ndg7oJ9XcxUppzOwtEAPx0rLymWCz03O2gCXbr5NrtFZ/kbzPpMhDW1cnSW8zTzSQpzpXrqj5la+KIBynIp+EQZdxvM3NOyHFkpswOr1bsaFSmJ96ejrohIUq95FamQI6l8yo8iJiqROTLw6YUbcLa+F8qEP8ZdthPv98uV0ZAddduO9nysWzu2Hit3bXT4dQ3U=" - on: + user: deepcompute + password: + secure: fkHbFReSrTMDhMP1T26rlk0jVwmWyz8AkJqjThLWd0JBzxpAzLpeDCweCFuJk9hk1bnVnbJN/SgRBcRyYDkGCrarEtu3WkesGnIaqFKbMnu5Zwytex3ghPDK4ZK6+GVYSyljbYJUYXDZLMRoumiMOm7IHGVZ8soA02XNy7lBe36o5Dj3QfpRGUZLb2/nbMWIBvltecuhMk66yWKkSlwy0RjsOTn9XwjtTr5hGC6XD9kdC6NUeK6eSmdU/pa6DyOVSoKXEBims100g4gfOck5P8gXq8ssGVnWDkU9pvTKz085ayeepVDMygI5xug1U2zM3dTvTsRnsjr3B4FsAewfc9uh/sfFpr3v2oOIdUARf2sphJEja+0Z606s9DfxFMWHopouG9JDmzPwZBJNhJRIVW93VfODsUPejKtWJd259SfNRioj+ORP4b7wVQVfjvZM5CifDKrlMTBp1adt4bE8C/DepcezwgKLjRiGU0N0ndg7oJ9XcxUppzOwtEAPx0rLymWCz03O2gCXbr5NrtFZ/kbzPpMhDW1cnSW8zTzSQpzpXrqj5la+KIBynIp+EQZdxvM3NOyHFkpswOr1bsaFSmJ96ejrohIUq95FamQI6l8yo8iJiqROTLw6YUbcLa+F8qEP8ZdthPv98uV0ZAddduO9nysWzu2Hit3bXT4dQ3U= + true: branch: master - # only when there is a release it will update pypi tags: true +install: +- pip install . +- pip install unittest2 +language: python +python: +- '2.7' +script: +- docker run -v $(pwd):/app deepcompute/black:python-black-latest --check . +- echo "No tests" diff --git a/basescript/basescript.py b/basescript/basescript.py index cc01e1f..ad63f2e 100644 --- a/basescript/basescript.py +++ b/basescript/basescript.py @@ -7,8 +7,9 @@ from .log import init_logger from deeputil import Dummy + class BaseScript(object): - DESC = 'Base script abstraction' + DESC = "Base script abstraction" METRIC_GROUPING_INTERVAL = 1 def __init__(self, args=None): @@ -16,11 +17,11 @@ def __init__(self, args=None): self.parser = argparse.ArgumentParser(description=self.DESC) self.define_baseargs(self.parser) - self.subcommands = self.parser.add_subparsers(title='commands') - self.subcommands.dest = 'commands' + self.subcommands = self.parser.add_subparsers(title="commands") + self.subcommands.dest = "commands" self.subcommands.required = True self.define_subcommands(self.subcommands) - self.subcommand_run = self.subcommands.add_parser('run') + self.subcommand_run = self.subcommands.add_parser("run") self.subcommand_run.set_defaults(func=self.run) self.define_args(self.subcommand_run) @@ -34,12 +35,12 @@ def __init__(self, args=None): if self.args.debug: if self.args.log_level is None: - self.args.log_level = 'debug' + self.args.log_level = "debug" if self.args.metric_grouping_interval is None: self.args.metric_grouping_interval = 0 if not self.args.log_level: - self.args.log_level = 'info' + self.args.log_level = "info" self.args.metric_grouping_interval = self.METRIC_GROUPING_INTERVAL if self.args.metric_grouping_interval is None: @@ -52,7 +53,7 @@ def __init__(self, args=None): fpath=self.args.log_file, pre_hooks=self.define_log_pre_format_hooks(), post_hooks=self.define_log_post_format_hooks(), - metric_grouping_interval=self.args.metric_grouping_interval + metric_grouping_interval=self.args.metric_grouping_interval, ) self._flush_metrics_q = log._force_flush_q @@ -60,14 +61,14 @@ def __init__(self, args=None): self.stats = Dummy() - args = { n: getattr(self.args, n) for n in vars(self.args) } - args['func'] = self.args.func.__name__ + args = {n: getattr(self.args, n) for n in vars(self.args)} + args["func"] = self.args.func.__name__ self.log.debug("basescript init", **args) def start(self): - ''' + """ Starts execution of the script - ''' + """ # invoke the appropriate sub-command as requested from command-line try: self.args.func() @@ -88,7 +89,7 @@ def start(self): @property def name(self): - return '.'.join([x for x in (sys.argv[0].split('.')[0], self.args.name) if x]) + return ".".join([x for x in (sys.argv[0].split(".")[0], self.args.name) if x]) def define_log_pre_format_hooks(self): """ @@ -110,48 +111,67 @@ def define_log_post_format_hooks(self): return [] def define_subcommands(self, subcommands): - ''' + """ Define subcommands (as defined at https://docs.python.org/2/library/argparse.html#sub-commands) eg: adding a sub-command called "blah" that invokes a function fn_blah blah_command = subcommands.add_parser('blah') blah_command.set_defaults(func=fn_blah) - ''' + """ pass def define_baseargs(self, parser): - ''' + """ Define basic command-line arguments required by the script. @parser is a parser object created using the `argparse` module. returns: None - ''' - parser.add_argument('--name', default=sys.argv[0], - help='Name to identify this instance') - parser.add_argument('--log-level', default=None, - help='Logging level as picked from the logging module') - parser.add_argument('--log-format', default=None, + """ + parser.add_argument( + "--name", default=sys.argv[0], help="Name to identify this instance" + ) + parser.add_argument( + "--log-level", + default=None, + help="Logging level as picked from the logging module", + ) + parser.add_argument( + "--log-format", + default=None, # TODO add more formats - choices=("json", "pretty",), - help=("Force the format of the logs. By default, if the " - "command is from a terminal, print colorful logs. " - "Otherwise print json."), + choices=("json", "pretty"), + help=( + "Force the format of the logs. By default, if the " + "command is from a terminal, print colorful logs. " + "Otherwise print json." + ), ) - parser.add_argument('--log-file', default=None, - help='Writes logs to log file if specified, default: %(default)s', + parser.add_argument( + "--log-file", + default=None, + help="Writes logs to log file if specified, default: %(default)s", ) - parser.add_argument('--quiet', default=False, action="store_true", - help='if true, does not print logs to stderr, default: %(default)s', + parser.add_argument( + "--quiet", + default=False, + action="store_true", + help="if true, does not print logs to stderr, default: %(default)s", ) - parser.add_argument('--metric-grouping-interval', default=None, type=int, - help='To group metrics based on time interval ex:10 i.e;(10 sec)', + parser.add_argument( + "--metric-grouping-interval", + default=None, + type=int, + help="To group metrics based on time interval ex:10 i.e;(10 sec)", ) - parser.add_argument('--debug', default=False, action="store_true", - help='To run the code in debug mode', + parser.add_argument( + "--debug", + default=False, + action="store_true", + help="To run the code in debug mode", ) def define_args(self, parser): - ''' + """ Define script specific command-line arguments. @parser is a parser object created using the `argparse` module. @@ -160,12 +180,11 @@ def define_args(self, parser): module. returns: None - ''' + """ pass def run(self): - ''' + """ Override this method to define logic for `run` sub-command - ''' + """ pass - diff --git a/basescript/log.py b/basescript/log.py index 5e77fca..1dc4880 100644 --- a/basescript/log.py +++ b/basescript/log.py @@ -23,12 +23,13 @@ LOG = None + class Stream(object): def __init__(self, *streams): self.streams = streams def write(self, data): - print (data) + print(data) for s in self.streams: s.write(data) @@ -40,6 +41,7 @@ def close(self): for s in self.streams: s.close() + class StderrConsoleRenderer(object): BACKUP_KEYS = ("timestamp", "level", "event", "logger", "stack", "exception") @@ -58,13 +60,13 @@ def __call__(self, logger, method_name, event_dict): continue backup[k] = v - msg = self.cr(logger, method_name, event_dict) self.pl.msg(msg) event_dict.update(backup) return event_dict + class StdlibStructlogHandler(logging.Handler): def __init__(self): super(StdlibStructlogHandler, self).__init__() @@ -75,8 +77,8 @@ def emit(self, record): levelname = record.levelname.lower() if record.exc_info is not None: - kw['exc_info'] = record.exc_info - levelname = 'exception' + kw["exc_info"] = record.exc_info + levelname = "exception" fn = getattr(self._log, levelname) event = record.msg @@ -89,6 +91,7 @@ def emit(self, record): fn(event, *args, **kw) + # Logger with an interface similar to python's standard library logger # to be used with structlog.PrintLoggerFactory class LevelLogger(structlog.PrintLogger): @@ -109,6 +112,7 @@ def setLevel(self, level): def isEnabledFor(self, level): return level >= self.level + class LevelLoggerFactory(object): def __init__(self, fp, level=None): self.fp = fp @@ -117,6 +121,7 @@ def __init__(self, fp, level=None): def __call__(self, *args): return LevelLogger(self.fp, level=self.level) + class BoundLevelLogger(structlog.BoundLoggerBase): """ Python Standard Library "like" version. @@ -141,8 +146,8 @@ def debug(self, event=None, *args, **kw): return kw = self._add_base_info(kw) - kw['level'] = "debug" - return self._proxy_to_logger('debug', event, *args, **kw) + kw["level"] = "debug" + return self._proxy_to_logger("debug", event, *args, **kw) def info(self, event=None, *args, **kw): """ @@ -152,8 +157,8 @@ def info(self, event=None, *args, **kw): return kw = self._add_base_info(kw) - kw['level'] = "info" - return self._proxy_to_logger('info', event, *args, **kw) + kw["level"] = "info" + return self._proxy_to_logger("info", event, *args, **kw) def warning(self, event=None, *args, **kw): """ @@ -163,8 +168,8 @@ def warning(self, event=None, *args, **kw): return kw = self._add_base_info(kw) - kw['level'] = "warning" - return self._proxy_to_logger('warning', event, *args, **kw) + kw["level"] = "warning" + return self._proxy_to_logger("warning", event, *args, **kw) warn = warning @@ -176,8 +181,8 @@ def error(self, event=None, *args, **kw): return kw = self._add_base_info(kw) - kw['level'] = "error" - return self._proxy_to_logger('error', event, *args, **kw) + kw["level"] = "error" + return self._proxy_to_logger("error", event, *args, **kw) def critical(self, event=None, *args, **kw): """ @@ -187,8 +192,8 @@ def critical(self, event=None, *args, **kw): return kw = self._add_base_info(kw) - kw['level'] = "critical" - return self._proxy_to_logger('critical', event, *args, **kw) + kw["level"] = "critical" + return self._proxy_to_logger("critical", event, *args, **kw) def exception(self, event=None, *args, **kw): """ @@ -199,8 +204,8 @@ def exception(self, event=None, *args, **kw): return kw = self._add_base_info(kw) - kw['level'] = "exception" - kw.setdefault('exc_info', True) + kw["level"] = "exception" + kw.setdefault("exc_info", True) return self.error(event, *args, **kw) def _dump_stats(self, metric): @@ -209,12 +214,11 @@ def _dump_stats(self, metric): """ # TODO have a feature to silence metrics as well # TODO if dumping to console, we shouldn't club metrics. It should be sent one by one on each line. - return self._proxy_to_logger('msg', metric, type='metric', level='info') + return self._proxy_to_logger("msg", metric, type="metric", level="info") fatal = critical - def _proxy_to_logger(self, method_name, event, *event_args, - **event_kw): + def _proxy_to_logger(self, method_name, event, *event_args, **event_kw): """ Propagate a method call to the wrapped logger. @@ -224,14 +228,14 @@ def _proxy_to_logger(self, method_name, event, *event_args, """ if isinstance(event, bytes): - event = event.decode('utf-8') + event = event.decode("utf-8") if event_args: - event_kw['positional_args'] = event_args + event_kw["positional_args"] = event_args - return super(BoundLevelLogger, self)._proxy_to_logger(method_name, - event=event, - **event_kw) + return super(BoundLevelLogger, self)._proxy_to_logger( + method_name, event=event, **event_kw + ) # Pass-through methods to mimick the stdlib's logger interface. @@ -241,6 +245,7 @@ def setLevel(self, level): """ self._logger.setLevel(level) + def define_log_renderer(fmt, fpath, quiet): """ the final log processor that structlog requires to render. @@ -260,23 +265,25 @@ def define_log_renderer(fmt, fpath, quiet): return structlog.processors.JSONRenderer() + def _structlog_default_keys_processor(logger_class, log_method, event): - ''' Add unique id, type and hostname ''' + """ Add unique id, type and hostname """ global HOSTNAME - if 'id' not in event: - event['id'] = '%s_%s' % ( - datetime.utcnow().strftime('%Y%m%dT%H%M%S'), - uuid.uuid1().hex + if "id" not in event: + event["id"] = "%s_%s" % ( + datetime.utcnow().strftime("%Y%m%dT%H%M%S"), + uuid.uuid1().hex, ) - if 'type' not in event: - event['type'] = 'log' + if "type" not in event: + event["type"] = "log" - event['host'] = HOSTNAME + event["host"] = HOSTNAME return event + @keeprunning() def dump_metrics(log, interval): global METRICS_STATE @@ -296,37 +303,39 @@ def dump_metrics(log, interval): METRICS_STATE_LOCK.release() for (k, _), v in m.items(): - n = v['num'] + n = v["num"] d = dict(k) - d.update(v['fields']) + d.update(v["fields"]) - level = d.pop('level') - event = d.pop('event') + level = d.pop("level") + event = d.pop("event") fn = getattr(log, level) - fn(event, type='metric', __grouped__=True, num=n, **d) + fn(event, type="metric", __grouped__=True, num=n, **d) if terminate: break + def metrics_grouping_processor(logger_class, log_method, event): - if event.get('type') == 'logged_metric': - event['type'] = 'metric' + if event.get("type") == "logged_metric": + event["type"] = "metric" return event - if event.get('type') != 'metric': + if event.get("type") != "metric": return event - if event.get('__grouped__'): - event.pop('__grouped__') + if event.get("__grouped__"): + event.pop("__grouped__") return event - for k in ('timestamp', 'type', 'id'): - if k not in event: continue + for k in ("timestamp", "type", "id"): + if k not in event: + continue event.pop(k) # Delete a key startswith `_` for grouping. - event = {k:v for k, v in event.items() if not k.startswith('_')} + event = {k: v for k, v in event.items() if not k.startswith("_")} key = [] fields = [] @@ -337,16 +346,16 @@ def metrics_grouping_processor(logger_class, log_method, event): key = (tuple(key), tuple(sorted(k for k, _ in fields))) METRICS_STATE_LOCK.acquire() try: - state = METRICS_STATE.get(key, {'num': 0, 'fields': {}}) - sfields = state['fields'] - num = state['num'] + state = METRICS_STATE.get(key, {"num": 0, "fields": {}}) + sfields = state["fields"] + num = state["num"] for fk, fv in fields: favg = sfields.get(fk, 0.0) - favg = (favg * num + fv) / (num + 1) #moving average + favg = (favg * num + fv) / (num + 1) # moving average sfields[fk] = favg - state['num'] += 1 + state["num"] += 1 METRICS_STATE[key] = state finally: @@ -354,6 +363,7 @@ def metrics_grouping_processor(logger_class, log_method, event): raise structlog.DropEvent + def define_log_processors(): """ log processors that structlog executes before final rendering @@ -368,8 +378,10 @@ def define_log_processors(): structlog.processors.format_exc_info, ] -def _configure_logger(fmt, quiet, level, fpath, - pre_hooks, post_hooks, metric_grouping_interval): + +def _configure_logger( + fmt, quiet, level, fpath, pre_hooks, post_hooks, metric_grouping_interval +): """ configures a logger when required write to stderr or a file """ @@ -391,34 +403,25 @@ def processor(logger, method_name, event_dict): return processor processors = define_log_processors() - processors.extend( - [ wrap_hook(h) for h in pre_hooks ] - ) + processors.extend([wrap_hook(h) for h in pre_hooks]) if metric_grouping_interval: processors.append(metrics_grouping_processor) log_renderer = define_log_renderer(fmt, fpath, quiet) - stderr_required = (not quiet) - pretty_to_stderr = ( - stderr_required - and ( - fmt == "pretty" - or (fmt is None and sys.stderr.isatty()) - ) + stderr_required = not quiet + pretty_to_stderr = stderr_required and ( + fmt == "pretty" or (fmt is None and sys.stderr.isatty()) ) - should_inject_pretty_renderer = ( - pretty_to_stderr - and not isinstance(log_renderer, structlog.dev.ConsoleRenderer) + should_inject_pretty_renderer = pretty_to_stderr and not isinstance( + log_renderer, structlog.dev.ConsoleRenderer ) if should_inject_pretty_renderer: stderr_required = False processors.append(StderrConsoleRenderer()) processors.append(log_renderer) - processors.extend( - [ wrap_hook(h) for h in post_hooks ] - ) + processors.extend([wrap_hook(h) for h in post_hooks]) streams = [] # we need to use a stream if we are writing to both file and stderr, and both are json @@ -428,7 +431,7 @@ def processor(logger, method_name, event_dict): if fpath is not None: # TODO handle creating a directory for this log file ? # TODO set mode and encoding appropriately - streams.append(open(fpath, 'a')) + streams.append(open(fpath, "a")) assert len(streams) != 0, "cannot configure logger for 0 streams" @@ -451,15 +454,16 @@ def processor(logger, method_name, event_dict): _GLOBAL_LOG_CONFIGURED = True + def init_logger( fmt=None, quiet=False, - level='INFO', + level="INFO", fpath=None, pre_hooks=[], post_hooks=[], - metric_grouping_interval=None - ): + metric_grouping_interval=None, +): global LOG if LOG is not None: @@ -469,8 +473,9 @@ def init_logger( # no need for a log - return a dummy return Dummy() - _configure_logger(fmt, quiet, level, fpath, - pre_hooks, post_hooks, metric_grouping_interval) + _configure_logger( + fmt, quiet, level, fpath, pre_hooks, post_hooks, metric_grouping_interval + ) log = structlog.get_logger() level = getattr(logging, level.upper()) @@ -488,5 +493,6 @@ def init_logger( LOG = log return log + def get_logger(): return LOG diff --git a/examples/adder.py b/examples/adder.py index 68d2e13..0eb57cc 100644 --- a/examples/adder.py +++ b/examples/adder.py @@ -1,9 +1,10 @@ from basescript import BaseScript + class Adder(BaseScript): # The following specifies the script description so that it be used # as a part of the usage doc when --help option is used during running. - DESC = 'Adds numbers' + DESC = "Adds numbers" def __init__(self): super(Adder, self).__init__() @@ -11,14 +12,15 @@ def __init__(self): self.b = 20 def define_args(self, parser): - parser.add_argument('c', type=int, help='Number to add') + parser.add_argument("c", type=int, help="Number to add") def run(self): self.log.info("Starting run of script ...") - print (self.a + self.b + self.args.c) + print(self.a + self.b + self.args.c) self.log.info("Script is done") -if __name__ == '__main__': + +if __name__ == "__main__": Adder().start() diff --git a/examples/helloworld.py b/examples/helloworld.py index 8d898e9..5061213 100644 --- a/examples/helloworld.py +++ b/examples/helloworld.py @@ -1,8 +1,10 @@ from basescript import BaseScript + class HelloWorld(BaseScript): def run(self): - print ("Hello world") + print("Hello world") + -if __name__ == '__main__': +if __name__ == "__main__": HelloWorld().start() diff --git a/setup.py b/setup.py index 3ad9ef4..f90b994 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,10 @@ import os HERE = os.path.abspath(os.path.dirname(__file__)) + + def get_long_description(): - dirs = [ HERE ] + dirs = [HERE] if os.getenv("TRAVIS"): dirs.append(os.getenv("TRAVIS_BUILD_DIR")) @@ -20,20 +22,21 @@ def get_long_description(): return long_description + long_description = get_long_description() -version = '0.3.1' +version = "0.3.1" setup( name="basescript", version=version, description="Basic infrastructure for writing scripts", long_description=long_description, - keywords='basescript', - author='Deep Compute, LLC', + keywords="basescript", + author="Deep Compute, LLC", author_email="contact@deepcompute.com", url="https://github.com/deep-compute/basescript", download_url="https://github.com/deep-compute/basescript/tarball/%s" % version, - license='MIT License', + license="MIT License", install_requires=[ "pytz==2018.3", "six>=1.11.0", @@ -41,8 +44,8 @@ def get_long_description(): "colorama==0.3.9", "deeputil>=0.2.7", ], - package_dir={'basescript': 'basescript'}, - packages=find_packages('.', exclude=['tests*']), + package_dir={"basescript": "basescript"}, + packages=find_packages(".", exclude=["tests*"]), include_package_data=True, classifiers=[ "Programming Language :: Python :: 2.7", @@ -50,5 +53,5 @@ def get_long_description(): "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", - ] + ], )