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.