import argparse
import logging
import textwrap
import itertools
from benchmarkstt.modules import Modules
from benchmarkstt import __meta__
from benchmarkstt.normalization.core import Config
from argparse import ArgumentError
from contextlib import contextmanager
import sys
from functools import partial
import re
# allow loading of modules based on current working directory
sys.path.insert(0, '')
[docs]def args_help(parser):
parser.add_argument('--help', action='help', default=argparse.SUPPRESS,
help=argparse._('Show this help message and exit'))
[docs]def args_common(parser):
parser.add_argument('--log-level', type=str.lower, default='warning', dest='log_level',
choices=list(map(str.lower, logging._nameToLevel.keys())),
help=argparse._('Set the logging output level'))
[docs]def args_from_factory(action, factory, parser):
for conf in factory:
name = conf.name
docs = conf.docs
arguments = dict()
arguments['help'] = docs
arguments['nargs'] = 0
if len(conf.required_args) or len(conf.optional_args):
arguments['nargs'] = '+' if len(conf.required_args) else '*'
optionals = list(map(lambda x: '[%s]' % x, conf.optional_args))
arguments['metavar'] = tuple(conf.required_args + optionals)
arguments['action'] = action_with_arguments(action,
conf.required_args,
conf.optional_args)
parser.add_argument('--%s' % (name,), **arguments)
class _ActionWithArguments:
"""
Placeholder class to recognize an argument is a NormalizerAction in argparse
"""
[docs]def action_with_arguments(action, required_args, optional_args):
"""
Custom argparse action to support a variable amount of arguments
:param action: name of the action
:param list required_args: required arguments
:param list optional_args: optional arguments
:rtype: ActionWithArguments
"""
minlen = len(required_args)
maxlen = minlen + len(optional_args)
class ActionWithArguments(argparse.Action, _ActionWithArguments):
def __call__(self, parser, args, values, option_string=None):
if len(values) < minlen or len(values) > maxlen:
if minlen == maxlen:
lentxt = str(minlen)
else:
lentxt = 'between %d and % d' % (minlen, maxlen)
raise ArgumentError(self, 'requires %s arguments (got %d)' % (lentxt, len(values)))
if not hasattr(args, action):
setattr(args, action, [])
getattr(args, action).append([self.dest] + values)
return ActionWithArguments
# TODO: further augment formatter to give cleaner output
[docs]def args_complete(parser): # pragma: no cover
try:
# support argument completion if package is installed
import argcomplete
argcomplete.autocomplete(parser)
except ImportError:
pass
[docs]def create_parser(*args, **kwargs):
defaults = {
'add_help': False,
'formatter_class': HelpFormatter,
'allow_abbrev': False,
}
kwargs = {k: kwargs.get(k, v) for k, v in defaults.items()}
parser = argparse.ArgumentParser(*args, **kwargs)
parser._optionals.title = 'named arguments'
return parser
[docs]@contextmanager
def main_parser_context():
try:
# import done here to avoid circular references
import benchmarkstt.benchmark.cli as benchmark_cli
name = 'benchmarkstt'
desc = 'BenchmarkSTT\'s main command line tool that is used for benchmarking speech-to-text, ' \
'for additional tools, see ``benchmarkstt-tools --help``.'
parser = create_parser(prog=name, description=desc)
benchmark_cli.argparser(parser)
parser.add_argument('--version', action='store_true',
help='Output %s version number' % (name,))
args_common(parser)
args_help(parser)
yield parser
finally:
pass
[docs]def determine_log_level():
# Set log-level manually before parse_args(), so that also factory logs, etc. get output
log_level = 'WARNING'
if '--log-level' in sys.argv:
idx = sys.argv.index('--log-level') + 1
if idx < len(sys.argv):
if sys.argv[idx].upper() in logging._nameToLevel:
log_level = sys.argv[idx].upper()
logging.basicConfig(level=log_level)
logging.getLogger().setLevel(log_level)
[docs]def main():
determine_log_level()
# import done here to avoid circular dependencies
import benchmarkstt.benchmark.cli as benchmark_cli
with main_parser_context() as parser:
args_complete(parser)
if '--version' in sys.argv:
print("benchmarkstt: %s" % (__meta__.__version__,))
logging.getLogger().info('python version: %s', sys.version)
parser.exit(0)
args = parser.parse_args()
benchmark_cli.main(parser, args)
exit(0)
[docs]def main_parser():
with main_parser_context() as parser:
return parser
if __name__ == '__main__': # pragma: nocover
main()