lms.cli.parser

Customize an argument parser for LMS Toolkit.

  1"""
  2Customize an argument parser for LMS Toolkit.
  3"""
  4
  5import argparse
  6import typing
  7
  8import edq.core.argparser
  9import edq.net.exchange
 10import edq.util.reflection
 11
 12import lms
 13import lms.model.constants
 14import lms.util.net
 15
 16CONFIG_FILENAME: str = 'edq-lms.json'
 17
 18DEFAULT_SKIP_ROWS: int = 0
 19
 20_set_exchanges_clean_func: bool = True  # pylint: disable=invalid-name
 21"""
 22Whether to set the exchanges clean function when creating the parser.
 23This may be disabled for testing.
 24"""
 25
 26def get_parser(description: str,
 27        include_server: bool = True,
 28        include_auth: bool = True,
 29        include_output_format: bool = False,
 30        include_course: bool = False,
 31        include_assignment: bool = False,
 32        include_quiz: bool = False,
 33        include_user: bool = False,
 34        include_groupset: bool = False,
 35        include_group: bool = False,
 36        include_net: bool = True,
 37        include_skip_rows: bool = False,
 38        include_strict: bool = False,
 39        ) -> argparse.ArgumentParser:
 40    """
 41    Get an argument parser specialized for LMS Toolkit.
 42    """
 43
 44    config_options = {
 45        'config_filename': CONFIG_FILENAME,
 46        'cli_arg_config_map': {
 47            'server': 'server',
 48            'backend_type': 'backend_type',
 49            'auth_user': 'auth_user',
 50            'auth_password': 'auth_password',
 51            'auth_token': 'auth_token',
 52            'course': 'course',
 53            'assignment': 'assignment',
 54            'quiz': 'quiz',
 55            'user': 'user',
 56            'group': 'group',
 57            'groupset': 'groupset',
 58        },
 59    }
 60
 61    parser = edq.core.argparser.get_default_parser(
 62            description,
 63            version = f"v{lms.__version__}",
 64            include_net = include_net,
 65            config_options = config_options,
 66    )
 67
 68    # Ensure that responses are cleaned as LMS responses.
 69    if (include_net):
 70        if (_set_exchanges_clean_func):
 71            edq.net.exchange._exchanges_clean_func = edq.util.reflection.get_qualified_name(lms.util.net.clean_lms_response)
 72
 73    if (include_server):
 74        group = parser.add_argument_group('server options')
 75
 76        group.add_argument('--server', dest = 'server',
 77            action = 'store', type = str, default = None,
 78            help = 'The address of the LMS server to connect to.')
 79
 80        group.add_argument('--server-type', dest = 'backend_type',
 81            action = 'store', type = str,
 82            default = None, choices = lms.model.constants.BACKEND_TYPES,
 83            help = 'The type of LMS being connected to (this can normally be guessed from the server address).')
 84
 85    if (include_auth):
 86        group = parser.add_argument_group('authentication options')
 87
 88        group.add_argument('--auth-user', dest = 'auth_user',
 89            action = 'store', type = str, default = None,
 90            help = 'The user to authenticate with.')
 91
 92        group.add_argument('--auth-password', dest = 'auth_password',
 93            action = 'store', type = str, default = None,
 94            help = 'The password to authenticate with.')
 95
 96        group.add_argument('--auth-token', dest = 'auth_token',
 97            action = 'store', type = str, default = None,
 98            help = 'The token to authenticate with.')
 99
100    if (include_course):
101        parser.add_argument('--course', dest = 'course',
102            action = 'store', type = str, default = None,
103            help = 'The course to target for this operation.')
104
105    if (include_assignment):
106        parser.add_argument('--assignment', dest = 'assignment',
107            action = 'store', type = str, default = None,
108            help = 'The assignment to target for this operation.')
109
110    if (include_quiz):
111        parser.add_argument('--quiz', dest = 'quiz',
112            action = 'store', type = str, default = None,
113            help = 'The quiz to target for this operation.')
114
115    if (include_user):
116        parser.add_argument('--user', dest = 'user',
117            action = 'store', type = str, default = None,
118            help = 'The user to target for this operation.')
119
120    if (include_groupset):
121        parser.add_argument('--groupset', dest = 'groupset',
122            action = 'store', type = str, default = None,
123            help = 'The group set to target for this operation.')
124
125    if (include_group):
126        parser.add_argument('--group', dest = 'group',
127            action = 'store', type = str, default = None,
128            help = 'The group to target for this operation.')
129
130    if (include_output_format):
131        group = parser.add_argument_group('output formatting options')
132
133        group.add_argument('--format', dest = 'output_format',
134            action = 'store', type = str,
135            default = lms.model.constants.OUTPUT_FORMAT_TEXT, choices = lms.model.constants.OUTPUT_FORMATS,
136            help = 'The format to display the output as (default: %(default)s).')
137
138        group.add_argument('--include-extra-fields', dest = 'include_extra_fields',
139            action = 'store_true', default = False,
140            help = 'Include non-common (usually LMS-specific) fields in results (default: %(default)s).')
141
142        group.add_argument('--pretty-headers', dest = 'pretty_headers',
143            action = 'store_true', default = False,
144            help = 'When displaying headers, try to make them look "pretty" (default: %(default)s).')
145
146        group.add_argument('--skip-headers', dest = 'skip_headers',
147            action = 'store_true', default = False,
148            help = 'Skip headers when outputting results, will not apply to all formats (default: %(default)s).')
149
150    if (include_skip_rows):
151        parser.add_argument('--skip-rows', dest = 'skip_rows',
152            action = 'store', type = int, default = DEFAULT_SKIP_ROWS,
153            help = 'The number of header rows to skip (default: %(default)s).')
154
155    if (include_strict):
156        parser.add_argument('--strict', dest = 'strict',
157            action = 'store_true', default = False,
158            help = 'Enable strict mode, which is stricter about what counts as an error (default: %(default)s).')
159
160    return typing.cast(argparse.ArgumentParser, parser)
CONFIG_FILENAME: str = 'edq-lms.json'
DEFAULT_SKIP_ROWS: int = 0
def get_parser( description: str, include_server: bool = True, include_auth: bool = True, include_output_format: bool = False, include_course: bool = False, include_assignment: bool = False, include_quiz: bool = False, include_user: bool = False, include_groupset: bool = False, include_group: bool = False, include_net: bool = True, include_skip_rows: bool = False, include_strict: bool = False) -> argparse.ArgumentParser:
 27def get_parser(description: str,
 28        include_server: bool = True,
 29        include_auth: bool = True,
 30        include_output_format: bool = False,
 31        include_course: bool = False,
 32        include_assignment: bool = False,
 33        include_quiz: bool = False,
 34        include_user: bool = False,
 35        include_groupset: bool = False,
 36        include_group: bool = False,
 37        include_net: bool = True,
 38        include_skip_rows: bool = False,
 39        include_strict: bool = False,
 40        ) -> argparse.ArgumentParser:
 41    """
 42    Get an argument parser specialized for LMS Toolkit.
 43    """
 44
 45    config_options = {
 46        'config_filename': CONFIG_FILENAME,
 47        'cli_arg_config_map': {
 48            'server': 'server',
 49            'backend_type': 'backend_type',
 50            'auth_user': 'auth_user',
 51            'auth_password': 'auth_password',
 52            'auth_token': 'auth_token',
 53            'course': 'course',
 54            'assignment': 'assignment',
 55            'quiz': 'quiz',
 56            'user': 'user',
 57            'group': 'group',
 58            'groupset': 'groupset',
 59        },
 60    }
 61
 62    parser = edq.core.argparser.get_default_parser(
 63            description,
 64            version = f"v{lms.__version__}",
 65            include_net = include_net,
 66            config_options = config_options,
 67    )
 68
 69    # Ensure that responses are cleaned as LMS responses.
 70    if (include_net):
 71        if (_set_exchanges_clean_func):
 72            edq.net.exchange._exchanges_clean_func = edq.util.reflection.get_qualified_name(lms.util.net.clean_lms_response)
 73
 74    if (include_server):
 75        group = parser.add_argument_group('server options')
 76
 77        group.add_argument('--server', dest = 'server',
 78            action = 'store', type = str, default = None,
 79            help = 'The address of the LMS server to connect to.')
 80
 81        group.add_argument('--server-type', dest = 'backend_type',
 82            action = 'store', type = str,
 83            default = None, choices = lms.model.constants.BACKEND_TYPES,
 84            help = 'The type of LMS being connected to (this can normally be guessed from the server address).')
 85
 86    if (include_auth):
 87        group = parser.add_argument_group('authentication options')
 88
 89        group.add_argument('--auth-user', dest = 'auth_user',
 90            action = 'store', type = str, default = None,
 91            help = 'The user to authenticate with.')
 92
 93        group.add_argument('--auth-password', dest = 'auth_password',
 94            action = 'store', type = str, default = None,
 95            help = 'The password to authenticate with.')
 96
 97        group.add_argument('--auth-token', dest = 'auth_token',
 98            action = 'store', type = str, default = None,
 99            help = 'The token to authenticate with.')
100
101    if (include_course):
102        parser.add_argument('--course', dest = 'course',
103            action = 'store', type = str, default = None,
104            help = 'The course to target for this operation.')
105
106    if (include_assignment):
107        parser.add_argument('--assignment', dest = 'assignment',
108            action = 'store', type = str, default = None,
109            help = 'The assignment to target for this operation.')
110
111    if (include_quiz):
112        parser.add_argument('--quiz', dest = 'quiz',
113            action = 'store', type = str, default = None,
114            help = 'The quiz to target for this operation.')
115
116    if (include_user):
117        parser.add_argument('--user', dest = 'user',
118            action = 'store', type = str, default = None,
119            help = 'The user to target for this operation.')
120
121    if (include_groupset):
122        parser.add_argument('--groupset', dest = 'groupset',
123            action = 'store', type = str, default = None,
124            help = 'The group set to target for this operation.')
125
126    if (include_group):
127        parser.add_argument('--group', dest = 'group',
128            action = 'store', type = str, default = None,
129            help = 'The group to target for this operation.')
130
131    if (include_output_format):
132        group = parser.add_argument_group('output formatting options')
133
134        group.add_argument('--format', dest = 'output_format',
135            action = 'store', type = str,
136            default = lms.model.constants.OUTPUT_FORMAT_TEXT, choices = lms.model.constants.OUTPUT_FORMATS,
137            help = 'The format to display the output as (default: %(default)s).')
138
139        group.add_argument('--include-extra-fields', dest = 'include_extra_fields',
140            action = 'store_true', default = False,
141            help = 'Include non-common (usually LMS-specific) fields in results (default: %(default)s).')
142
143        group.add_argument('--pretty-headers', dest = 'pretty_headers',
144            action = 'store_true', default = False,
145            help = 'When displaying headers, try to make them look "pretty" (default: %(default)s).')
146
147        group.add_argument('--skip-headers', dest = 'skip_headers',
148            action = 'store_true', default = False,
149            help = 'Skip headers when outputting results, will not apply to all formats (default: %(default)s).')
150
151    if (include_skip_rows):
152        parser.add_argument('--skip-rows', dest = 'skip_rows',
153            action = 'store', type = int, default = DEFAULT_SKIP_ROWS,
154            help = 'The number of header rows to skip (default: %(default)s).')
155
156    if (include_strict):
157        parser.add_argument('--strict', dest = 'strict',
158            action = 'store_true', default = False,
159            help = 'Enable strict mode, which is stricter about what counts as an error (default: %(default)s).')
160
161    return typing.cast(argparse.ArgumentParser, parser)

Get an argument parser specialized for LMS Toolkit.