autograder.cli.parser

Customize an argument parser for the autograder.

  1"""
  2Customize an argument parser for the autograder.
  3"""
  4
  5import argparse
  6import typing
  7
  8import edq.config.settings
  9import edq.config.source
 10import edq.core.argparser
 11import edq.net.settings
 12import edq.util.reflection
 13import lms.model.constants
 14
 15import autograder
 16import autograder.api.common
 17import autograder.model.config
 18import autograder.util.net
 19
 20CONFIG_FILENAME: str = 'autograder.json'
 21LOCAL_CONFIG_FILENAME: str = 'config.json'
 22ENV_CONFIG_PREFIX: str = 'AG__'
 23DEFAULT_ENCRYPTION_KEY: str = 'LynxGrader'
 24
 25DEFAULT_SKIP_ROWS: int = 0
 26
 27_set_exchanges_clean_response_func: bool = True  # pylint: disable=invalid-name
 28
 29def _post_parse(
 30        parser: argparse.ArgumentParser,
 31        args: argparse.Namespace,
 32        extra_state: typing.Dict[str, typing.Any]) -> None:
 33    """ Called after argument parsing. """
 34
 35    if (args.testing_mode):
 36        autograder.api.common.set_testing_source_info()
 37
 38def get_parser(
 39        description: str,
 40        api_params: typing.Union[typing.List[autograder.api.config.APIParam], None] = None,
 41        include_output_format: bool = False,
 42        include_net: bool = True,
 43        include_skip_rows: bool = False,
 44        ) -> argparse.ArgumentParser:
 45    """
 46    Get an argument parser specialized for autograder-py.
 47    """
 48
 49    if (api_params is None):
 50        api_params = []
 51
 52    # Set config options.
 53    edq.config.settings.set_config_filename(CONFIG_FILENAME)
 54    edq.config.settings.set_application_config_class(autograder.model.config.Config)
 55    edq.config.settings.set_env_prefix(ENV_CONFIG_PREFIX)
 56    edq.config.settings.set_default_encryption_key(DEFAULT_ENCRYPTION_KEY)
 57    edq.config.settings.set_load_order([
 58        edq.config.source.LocalSpec(filename = LOCAL_CONFIG_FILENAME),
 59        edq.config.source.GlobalSpec(),
 60        edq.config.source.ProjectSpec(),
 61        edq.config.source.ENVSpec(),
 62        edq.config.source.CLIFileSpec(),
 63        edq.config.source.CLIImplicitSpec(),
 64        edq.config.source.CLIExplicitSpec(),
 65    ])
 66
 67    parser = edq.core.argparser.get_default_parser(
 68            description,
 69            version = f"v{autograder.__version__}",
 70            include_net = include_net,
 71    )
 72
 73    parser.register_callbacks('autograder-py', None, _post_parse)
 74
 75    # Add arguments according to the given API params.
 76    group = parser.add_argument_group('command-specific options')
 77    for api_param in api_params:
 78        api_param.add_to_parser(group)
 79
 80    group = parser.add_argument_group('testing options')
 81    group.add_argument('--testing-mode', dest = 'testing_mode',
 82        action = 'store_true', default = False,
 83        help = 'Run as if a test is being run (default: %(default)s).')
 84
 85    # Ensure that responses are cleaned as API responses.
 86    if (include_net):
 87        if (_set_exchanges_clean_response_func):
 88            edq.net.settings.set_exchanges_clean_response_func(edq.util.reflection.get_qualified_name(autograder.util.net.clean_api_response))
 89
 90    if (include_output_format):
 91        group = parser.add_argument_group('output formatting options')
 92
 93        group.add_argument('--format', dest = 'output_format',
 94            action = 'store', type = str,
 95            default = lms.model.constants.OutputFormat.TEXT.value,
 96            choices = [choice.value for choice in lms.model.constants.OutputFormat],
 97            help = 'The format to display the output as (default: %(default)s).')
 98
 99        group.add_argument('--include-extra-fields', dest = 'include_extra_fields',
100            action = 'store_true', default = False,
101            help = 'Include uncommon fields in results (default: %(default)s).')
102
103        group.add_argument('--pretty-headers', dest = 'pretty_headers',
104            action = 'store_true', default = False,
105            help = 'When displaying headers, try to make them look "pretty" (default: %(default)s).')
106
107        group.add_argument('--skip-headers', dest = 'skip_headers',
108            action = 'store_true', default = False,
109            help = 'Skip headers when outputting results, will not apply to all formats (default: %(default)s).')
110
111    if (include_skip_rows):
112        parser.add_argument('--skip-rows', dest = 'skip_rows',
113            action = 'store', type = int, default = DEFAULT_SKIP_ROWS,
114            help = 'The number of header rows to skip (default: %(default)s).')
115
116    return parser
CONFIG_FILENAME: str = 'autograder.json'
LOCAL_CONFIG_FILENAME: str = 'config.json'
ENV_CONFIG_PREFIX: str = 'AG__'
DEFAULT_ENCRYPTION_KEY: str = 'LynxGrader'
DEFAULT_SKIP_ROWS: int = 0
def get_parser( description: str, api_params: Optional[List[autograder.api.config.APIParam]] = None, include_output_format: bool = False, include_net: bool = True, include_skip_rows: bool = False) -> argparse.ArgumentParser:
 39def get_parser(
 40        description: str,
 41        api_params: typing.Union[typing.List[autograder.api.config.APIParam], None] = None,
 42        include_output_format: bool = False,
 43        include_net: bool = True,
 44        include_skip_rows: bool = False,
 45        ) -> argparse.ArgumentParser:
 46    """
 47    Get an argument parser specialized for autograder-py.
 48    """
 49
 50    if (api_params is None):
 51        api_params = []
 52
 53    # Set config options.
 54    edq.config.settings.set_config_filename(CONFIG_FILENAME)
 55    edq.config.settings.set_application_config_class(autograder.model.config.Config)
 56    edq.config.settings.set_env_prefix(ENV_CONFIG_PREFIX)
 57    edq.config.settings.set_default_encryption_key(DEFAULT_ENCRYPTION_KEY)
 58    edq.config.settings.set_load_order([
 59        edq.config.source.LocalSpec(filename = LOCAL_CONFIG_FILENAME),
 60        edq.config.source.GlobalSpec(),
 61        edq.config.source.ProjectSpec(),
 62        edq.config.source.ENVSpec(),
 63        edq.config.source.CLIFileSpec(),
 64        edq.config.source.CLIImplicitSpec(),
 65        edq.config.source.CLIExplicitSpec(),
 66    ])
 67
 68    parser = edq.core.argparser.get_default_parser(
 69            description,
 70            version = f"v{autograder.__version__}",
 71            include_net = include_net,
 72    )
 73
 74    parser.register_callbacks('autograder-py', None, _post_parse)
 75
 76    # Add arguments according to the given API params.
 77    group = parser.add_argument_group('command-specific options')
 78    for api_param in api_params:
 79        api_param.add_to_parser(group)
 80
 81    group = parser.add_argument_group('testing options')
 82    group.add_argument('--testing-mode', dest = 'testing_mode',
 83        action = 'store_true', default = False,
 84        help = 'Run as if a test is being run (default: %(default)s).')
 85
 86    # Ensure that responses are cleaned as API responses.
 87    if (include_net):
 88        if (_set_exchanges_clean_response_func):
 89            edq.net.settings.set_exchanges_clean_response_func(edq.util.reflection.get_qualified_name(autograder.util.net.clean_api_response))
 90
 91    if (include_output_format):
 92        group = parser.add_argument_group('output formatting options')
 93
 94        group.add_argument('--format', dest = 'output_format',
 95            action = 'store', type = str,
 96            default = lms.model.constants.OutputFormat.TEXT.value,
 97            choices = [choice.value for choice in lms.model.constants.OutputFormat],
 98            help = 'The format to display the output as (default: %(default)s).')
 99
100        group.add_argument('--include-extra-fields', dest = 'include_extra_fields',
101            action = 'store_true', default = False,
102            help = 'Include uncommon fields in results (default: %(default)s).')
103
104        group.add_argument('--pretty-headers', dest = 'pretty_headers',
105            action = 'store_true', default = False,
106            help = 'When displaying headers, try to make them look "pretty" (default: %(default)s).')
107
108        group.add_argument('--skip-headers', dest = 'skip_headers',
109            action = 'store_true', default = False,
110            help = 'Skip headers when outputting results, will not apply to all formats (default: %(default)s).')
111
112    if (include_skip_rows):
113        parser.add_argument('--skip-rows', dest = 'skip_rows',
114            action = 'store', type = int, default = DEFAULT_SKIP_ROWS,
115            help = 'The number of header rows to skip (default: %(default)s).')
116
117    return parser

Get an argument parser specialized for autograder-py.