edq-lms-toolkit 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. edq_lms_toolkit-0.1.0/LICENSE +21 -0
  2. edq_lms_toolkit-0.1.0/PKG-INFO +400 -0
  3. edq_lms_toolkit-0.1.0/README.md +354 -0
  4. edq_lms_toolkit-0.1.0/edq_lms_toolkit.egg-info/PKG-INFO +400 -0
  5. edq_lms_toolkit-0.1.0/edq_lms_toolkit.egg-info/SOURCES.txt +71 -0
  6. edq_lms_toolkit-0.1.0/edq_lms_toolkit.egg-info/dependency_links.txt +1 -0
  7. edq_lms_toolkit-0.1.0/edq_lms_toolkit.egg-info/requires.txt +9 -0
  8. edq_lms_toolkit-0.1.0/edq_lms_toolkit.egg-info/top_level.txt +1 -0
  9. edq_lms_toolkit-0.1.0/lms/__init__.py +1 -0
  10. edq_lms_toolkit-0.1.0/lms/__main__.py +8 -0
  11. edq_lms_toolkit-0.1.0/lms/api/__init__.py +0 -0
  12. edq_lms_toolkit-0.1.0/lms/api/assignment/__init__.py +0 -0
  13. edq_lms_toolkit-0.1.0/lms/api/assignment/common.py +27 -0
  14. edq_lms_toolkit-0.1.0/lms/api/assignment/fetch.py +33 -0
  15. edq_lms_toolkit-0.1.0/lms/api/assignment/fetchscores.py +70 -0
  16. edq_lms_toolkit-0.1.0/lms/api/assignment/fetchsubmissionfiles.py +124 -0
  17. edq_lms_toolkit-0.1.0/lms/api/assignment/list.py +19 -0
  18. edq_lms_toolkit-0.1.0/lms/api/assignment/resolve.py +12 -0
  19. edq_lms_toolkit-0.1.0/lms/api/assignment/uploadscores.py +73 -0
  20. edq_lms_toolkit-0.1.0/lms/api/common.py +146 -0
  21. edq_lms_toolkit-0.1.0/lms/api/gradebook/__init__.py +0 -0
  22. edq_lms_toolkit-0.1.0/lms/api/gradebook/fetch.py +137 -0
  23. edq_lms_toolkit-0.1.0/lms/api/gradebook/upload.py +80 -0
  24. edq_lms_toolkit-0.1.0/lms/api/group/__init__.py +0 -0
  25. edq_lms_toolkit-0.1.0/lms/api/group/common.py +4 -0
  26. edq_lms_toolkit-0.1.0/lms/api/group/listgroupingmembership.py +41 -0
  27. edq_lms_toolkit-0.1.0/lms/api/group/listgroupings.py +19 -0
  28. edq_lms_toolkit-0.1.0/lms/api/group/listgroupmembers.py +36 -0
  29. edq_lms_toolkit-0.1.0/lms/api/group/listgroups.py +47 -0
  30. edq_lms_toolkit-0.1.0/lms/api/group/resolve.py +34 -0
  31. edq_lms_toolkit-0.1.0/lms/api/resolve.py +121 -0
  32. edq_lms_toolkit-0.1.0/lms/api/user/__init__.py +0 -0
  33. edq_lms_toolkit-0.1.0/lms/api/user/common.py +69 -0
  34. edq_lms_toolkit-0.1.0/lms/api/user/fetch.py +37 -0
  35. edq_lms_toolkit-0.1.0/lms/api/user/list.py +23 -0
  36. edq_lms_toolkit-0.1.0/lms/api/user/resolve.py +13 -0
  37. edq_lms_toolkit-0.1.0/lms/cli/__init__.py +0 -0
  38. edq_lms_toolkit-0.1.0/lms/cli/__main__.py +16 -0
  39. edq_lms_toolkit-0.1.0/lms/cli/assignment/__init__.py +0 -0
  40. edq_lms_toolkit-0.1.0/lms/cli/assignment/__main__.py +15 -0
  41. edq_lms_toolkit-0.1.0/lms/cli/assignment/common.py +9 -0
  42. edq_lms_toolkit-0.1.0/lms/cli/assignment/fetch-scores.py +46 -0
  43. edq_lms_toolkit-0.1.0/lms/cli/assignment/fetch-submission-files.py +34 -0
  44. edq_lms_toolkit-0.1.0/lms/cli/assignment/fetch.py +45 -0
  45. edq_lms_toolkit-0.1.0/lms/cli/assignment/list.py +37 -0
  46. edq_lms_toolkit-0.1.0/lms/cli/assignment/upload-score.py +41 -0
  47. edq_lms_toolkit-0.1.0/lms/cli/assignment/upload-scores.py +82 -0
  48. edq_lms_toolkit-0.1.0/lms/cli/common.py +98 -0
  49. edq_lms_toolkit-0.1.0/lms/cli/gradebook/__init__.py +0 -0
  50. edq_lms_toolkit-0.1.0/lms/cli/gradebook/__main__.py +15 -0
  51. edq_lms_toolkit-0.1.0/lms/cli/gradebook/fetch.py +89 -0
  52. edq_lms_toolkit-0.1.0/lms/cli/gradebook/upload.py +116 -0
  53. edq_lms_toolkit-0.1.0/lms/cli/group/__init__.py +0 -0
  54. edq_lms_toolkit-0.1.0/lms/cli/group/__main__.py +15 -0
  55. edq_lms_toolkit-0.1.0/lms/cli/group/list-group-members.py +37 -0
  56. edq_lms_toolkit-0.1.0/lms/cli/group/list-grouping-membership.py +36 -0
  57. edq_lms_toolkit-0.1.0/lms/cli/group/list-groupings.py +33 -0
  58. edq_lms_toolkit-0.1.0/lms/cli/group/list-groups.py +36 -0
  59. edq_lms_toolkit-0.1.0/lms/cli/user/__init__.py +0 -0
  60. edq_lms_toolkit-0.1.0/lms/cli/user/__main__.py +15 -0
  61. edq_lms_toolkit-0.1.0/lms/cli/user/common.py +9 -0
  62. edq_lms_toolkit-0.1.0/lms/cli/user/fetch.py +46 -0
  63. edq_lms_toolkit-0.1.0/lms/cli/user/list.py +37 -0
  64. edq_lms_toolkit-0.1.0/lms/config.py +138 -0
  65. edq_lms_toolkit-0.1.0/lms/log.py +25 -0
  66. edq_lms_toolkit-0.1.0/lms/util/__init__.py +0 -0
  67. edq_lms_toolkit-0.1.0/lms/util/cli.py +100 -0
  68. edq_lms_toolkit-0.1.0/lms/util/code.py +12 -0
  69. edq_lms_toolkit-0.1.0/lms/util/file.py +86 -0
  70. edq_lms_toolkit-0.1.0/pyproject.toml +46 -0
  71. edq_lms_toolkit-0.1.0/requirements-dev.txt +4 -0
  72. edq_lms_toolkit-0.1.0/requirements.txt +3 -0
  73. edq_lms_toolkit-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Eriq Augustine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,400 @@
1
+ Metadata-Version: 2.4
2
+ Name: edq-lms-toolkit
3
+ Version: 0.1.0
4
+ Summary: A suite of CLI tools and Python library interfacing with Learning Management Systems (LMSs).
5
+ Author-email: Eriq Augustine <eriq@edulinq.org>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2023 Eriq Augustine
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/edulinq/lms-toolkit
29
+ Project-URL: Repository, https://github.com/edulinq/lms-toolkit
30
+ Keywords: education,lms,canvas,api
31
+ Classifier: Intended Audience :: Education
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Programming Language :: Python :: 3.8
34
+ Requires-Python: >=3.8
35
+ Description-Content-Type: text/markdown
36
+ License-File: LICENSE
37
+ Requires-Dist: json5>=0.9.14
38
+ Requires-Dist: platformdirs>=3.10.0
39
+ Requires-Dist: requests>=2.31.0
40
+ Provides-Extra: dev
41
+ Requires-Dist: build; extra == "dev"
42
+ Requires-Dist: packaging>=21.3; extra == "dev"
43
+ Requires-Dist: twine; extra == "dev"
44
+ Requires-Dist: vermin; extra == "dev"
45
+ Dynamic: license-file
46
+
47
+ # LMS Tools
48
+
49
+ A suite of tools and Python interface for different Learning Management Systems (LMSs).
50
+
51
+ This project is not affiliated with any LMS developer/provider.
52
+
53
+ Documentation Table of Contents:
54
+ - [Installation](#installation)
55
+ - [CLI Configuration](#cli-configuration)
56
+ - [Usage Notes](#usage-notes)
57
+ - [Users](#users)
58
+ - [Assignments](#assignments)
59
+ - [Groupings and Groups](#groupings-and-groups)
60
+ - [Tables](#tables)
61
+ - [CLI Tools](#cli-tools)
62
+ - [List Course Users](#list-course-users)
63
+ - [Fetch a Single User](#fetch-a-single-user)
64
+ - [List Assignments](#list-assignments)
65
+ - [Fetch a Single Assignment](#fetch-a-single-assignment)
66
+ - [Fetch Assignment Scores](#fetch-assignment-scores)
67
+ - [Fetch Assignment Submission Files](#fetch-assignment-submission-files)
68
+ - [Upload Assignment Scores](#upload-assignment-scores)
69
+ - [Upload Single Assignment Score](#upload-single-assignment-score)
70
+ - [Fetch Gradebook](#fetch-gradebook)
71
+ - [Upload Gradebook](#upload-gradebook)
72
+ - [List Groupings](#list-groupings)
73
+ - [List Groups](#list-groups)
74
+ - [List Membership in a Grouping](#list-membership-in-a-grouping)
75
+ - [List Members in a Group](#list-members-in-a-group)
76
+
77
+ ## Installation
78
+
79
+ The project (tools and API) can be installed from PyPi with:
80
+ ```
81
+ pip install edq-lms-toolkit
82
+ ```
83
+
84
+ Standard Python requirements are listed in `pyproject.toml`.
85
+ The project and Python dependencies can be installed from source with:
86
+ ```
87
+ pip3 install .
88
+ ```
89
+
90
+ ### CLI Configuration
91
+
92
+ Before discussing specific tools, you should know some general information about
93
+ configuring and sending options to each CLI tool.
94
+
95
+ To know who you are and what you are working on the package needs a few configuration options:
96
+ - `server` -- The LMS server to connect to.
97
+ - `course` -- The LMS ID for the course you are working with.
98
+ - `token` -- Your LMS API token (for Canvas, see the [Canvas documentation](https://community.canvaslms.com/t5/Admin-Guide/How-do-I-manage-API-access-tokens-as-an-admin/ta-p/89).
99
+ - `assignment` -- A query for the current assignment you are working on (does not always apply).
100
+
101
+ All these options can be set on the command line when invoking on of these tools, e.g.,:
102
+ ```sh
103
+ python3 -m lms.cli.user.list --server lms.test.com --course 12345 --token abc123
104
+ ```
105
+ However, it will generally be more convenient to hold these common options in a more reusable location.
106
+
107
+ There are several other places that config options can be specified,
108
+ with each later location overriding any earlier options.
109
+ Here are the places options can be specified in the order that they are checked:
110
+ 1. `./edq-lms.json` -- If a `edq-lms.json` exists in the current directory, it is loaded.
111
+ 2. `<platform-specific user config location>/edq-lms.json` -- A directory which is considered the "proper" place to store user-related config for the platform you are using (according to [platformdirs](https://github.com/platformdirs/platformdirs)). Use `--help` to see the exact place in your specific case. This is a great place to store login credentials.
112
+ 3. Files specified by `--config` -- These files are loaded in the order they appear on the command-line.
113
+ 4. Bare Options -- Options specified directly like `--course` or `--token`. These will override all previous options.
114
+
115
+ Using the default config file (`edq-lms.json`):
116
+ ```sh
117
+ # `./edq-lms.json` will be looked for and loaded if it exists.
118
+ python3 -m lms.cli.user.list
119
+ ```
120
+
121
+ Using a custom config file (`my_config.json`):
122
+ ```sh
123
+ # `./my_config.json` will be used.
124
+ python3 -m lms.cli.user.list --config my_config.json
125
+ ```
126
+
127
+ A sample config file is provided in this repo at [sample-edq-lms.json](./sample-edq-lms.json).
128
+
129
+ For brevity, all future commands in this document will assume that all standard config options are in the default
130
+ config files (and thus will not need to be specified).
131
+
132
+ ## Usage Notes
133
+
134
+ ### Users
135
+
136
+ When a user is required, tools and API functions accept a "user query" (unless specified).
137
+ A user query is any object that can be used to uniquely identify a user.
138
+ Valid user queries are:
139
+ - LMS User ID (as an integer or string of digits)
140
+ - Email
141
+ - Full Name
142
+ - "email (id)" where "email" is an email and "id" is a LMS ID
143
+
144
+ User queries must be unambiguous within the pool of possible users (e.g., students in a course).
145
+ It is recommended to use an email or LMS ID as a user query.
146
+ Resolving a user query that is not a LMS ID will take longer,
147
+ because a list of users must be fetched from the LMS.
148
+
149
+ ### Assignments
150
+
151
+ When an assignment is required, tools and API functions accept an "assignment query" (unless specified).
152
+ An assignment query is any object that can be used to uniquely identify an assignment.
153
+ Valid assignment queries are:
154
+ - LMS Assignment ID (as an integer or string of digits)
155
+ - Full Name
156
+ - "name (id)" where "name" is a full assignment name and "id" is a LMS ID
157
+
158
+ Assignment queries must be unambiguous within the pool of possible assignments (e.g., assignments in a course).
159
+ Resolving an assignment query that is not a LMS ID will take longer,
160
+ because a list of assignments must be fetched from the LMS.
161
+
162
+ ### Groupings and Groups
163
+
164
+ A "grouping", also called a "group set" or "group category" in LMS,
165
+ is a set of groups created for a specific purpose (like for a specific assignment).
166
+ A grouping has a name and contains groups.
167
+ A "group" is a collection of users (usually students).
168
+ The hierarchy goes "grouping" -> "group" -> "user".
169
+
170
+ When a group is required, tools and API functions accept a "group query" (unless specified).
171
+ (All information about group queries also applies to grouping queries.)
172
+ A group query is any object that can be used to uniquely identify a group.
173
+ Valid group queries are:
174
+ - LMS Group ID (as an integer or string of digits)
175
+ - Full Name
176
+ - "name (id)" where "name" is a full group name and "id" is a LMS ID
177
+
178
+ Group queries must be unambiguous within the pool of possible groups (e.g., groups in a course).
179
+
180
+ ### Tables
181
+
182
+ Most commands that list results can also output results into a tab-separated table (on stdout)
183
+ using the `-t` / `--table` option.
184
+ To skip the header row, you can use the `--skip-headers` option.
185
+
186
+ ### JSON Output
187
+
188
+ Most commands that list results can output them as JSON to stdout using the `--json` option.
189
+
190
+ ## CLI Tools
191
+
192
+ All CLI tools can be invoked with `-h` / `--help` to see the full usage and all options.
193
+
194
+ ### List Course Users
195
+
196
+ Course users can be listed using the `lms.cli.user.list` tool.
197
+ For example:
198
+ ```
199
+ python3 -m lms.cli.user.list
200
+ ```
201
+
202
+ ### Fetch a Single User
203
+
204
+ To fetch information about a single course user, use the `lms.cli.user.fetch` tool.
205
+ For example:
206
+ ```
207
+ python3 -m lms.cli.user.fetch 12345
208
+
209
+ # Or
210
+ python3 -m lms.cli.user.fetch alice@uni.edu
211
+ ```
212
+
213
+ ### List Assignments
214
+
215
+ Course assignments can be listed using the `lms.cli.assignment.list` tool.
216
+ For example:
217
+ ```
218
+ python3 -m lms.cli.assignment.list
219
+ ```
220
+
221
+ ### Fetch a Single Assignment
222
+
223
+ Fetch information about a single assignment using the `lms.cli.assignment.fetch` tool.
224
+ For example:
225
+ ```
226
+ python3 -m lms.cli.assignment.fetch 123456
227
+
228
+ # Or
229
+ python3 -m lms.cli.assignment.fetch 'My Assignment'
230
+ ```
231
+
232
+ ### Fetch Assignment Scores
233
+
234
+ To fetch the scores for a specific assignment, use the `lms.cli.assignment.fetch-scores` tool.
235
+ For example:
236
+ ```
237
+ python3 -m lms.cli.assignment.fetch-scores 123456
238
+
239
+ # Or
240
+ python3 -m lms.cli.assignment.fetch-scores 'My Assignment'
241
+ ```
242
+
243
+ The student's email and score will be written to stdout as a tab-separated row.
244
+
245
+ ### Fetch Assignment Submission Files
246
+
247
+ To fetch the files students have submitted for an assignment, use the `lms.cli.assignment.fetch-submission-files` tool.
248
+ For example:
249
+ ```
250
+ python3 -m lms.cli.assignment.fetch-submission-files 123456
251
+
252
+ # Or
253
+ python3 -m lms.cli.assignment.fetch-submission-files 'My Assignment'
254
+ ```
255
+
256
+ Only assignment with a submission type of "Online - Text Entry" or "Online - File Uploads" will be downloaded.
257
+
258
+ By default, files will be written to the `out` directory.
259
+ This can be controlled with the `--out-dir` argument.
260
+
261
+ ### Upload Assignment Scores
262
+
263
+ Uploading scores for an assignment can be done with the `lms.cli.assignment.upload-scores` tool:
264
+ ```
265
+ python3 -m lms.cli.assignment.upload-scores <assignment query> <path>
266
+ ```
267
+
268
+ Where `<path>` points to a tab-separated file where each row has 2-3 columns: email, score, and comment (optional).
269
+ Each row does not need to have the same length (i.e., some rows can have comments where others do not).
270
+ Empty comments are ignored.
271
+
272
+ The `--skip-rows` argument can be used to skip a specified number of header rows.
273
+ For example:
274
+ ```
275
+ python3 -m lms.cli.assignment.upload-scores 'My Assignment' grades.txt --skip-rows 1
276
+ ```
277
+
278
+ Where `grades.txt` looks like:
279
+ ```
280
+ user score comment?
281
+ 1001 75
282
+ alice@uni.edu 100 Great Job!
283
+ ```
284
+
285
+ ### Upload Single Assignment Score
286
+
287
+ To upload just one assignment score without a file, you can use the `lms.cli.assignment.upload-score` tool:
288
+ ```
289
+ python3 -m lms.cli.assignment.upload-score <assignment query> <user query> <score> [comment]
290
+ ```
291
+
292
+ Note that the comment is optional.
293
+
294
+ For example:
295
+ ```
296
+ python3 -m lms.cli.assignment.upload-score 'My Assignment' alice@uni.edu 100 'Great Job!'
297
+ ```
298
+
299
+ ### Fetch Gradebook
300
+
301
+ To fetch the full gradebook for a course, use the `lms.cli.gradebook.fetch` tool.
302
+ For example:
303
+ ```
304
+ python3 -m lms.cli.gradebook.fetch
305
+ ```
306
+
307
+ A gradebook will be written to stdout as a tab-separated file.
308
+ To output the gradebook to a file, you can redirect stdout to a file.
309
+ Expect this command to take a few minutes for larger classes.
310
+
311
+ You can limit to gradebook to only specific students by specifying their IDs on the command line.
312
+ Any number of students can be specified.
313
+ ```
314
+ python3 -m lms.cli.gradebook.fetch 12345 67890
315
+ ```
316
+
317
+ By default, assignments and users without submissions will be pruned.
318
+ They can be included by using the respective `--include-empty-assignments` and `--include-empty-users` flags.
319
+
320
+ For example, you can write a gradebook with all assignments and users to `grades.txt` using the following command:
321
+ ```
322
+ python3 -m lms.cli.gradebook.fetch --include-empty-assignments --include-empty-users > grades.txt
323
+ ```
324
+
325
+ To include scores that are computed by the LMS (such as the final score), use the `--include-computed-scores` flag:
326
+ ```
327
+ python3 -m lms.cli.gradebook.fetch --include-computed-scores
328
+ ```
329
+
330
+ ### Upload Gradebook
331
+
332
+ To upload a gradebook, use the `lms.cli.gradebook.upload` tool:
333
+ ```
334
+ python3 -m lms.cli.gradebook.upload <path>
335
+ ```
336
+
337
+ Where `<path>` points to a gradebook file that has the same format as the output from `lms.cli.gradebook.fetch`:
338
+ a tab-separated file with users down the rows and assignments along the columns.
339
+ The first column is user queries where the first cell is ignored,
340
+ the first row is assignment queries where the first cell is ignored,
341
+ and the remaining cells are the associated scores.
342
+ Any number of users and assignments can be specified as long as they exist in the course.
343
+ Empty cells will not be uploaded.
344
+
345
+ A gradebook file can look like:
346
+ ```
347
+ user 98765 Assignment 2
348
+ 1001 1 2
349
+ alice@uni.edu 3
350
+ ```
351
+
352
+ ### List Groupings
353
+
354
+ Groups in a course can be listed using the `lms.cli.group.list-groupings` tool.
355
+ For example:
356
+ ```
357
+ python3 -m lms.cli.group.list-groupings
358
+ ```
359
+
360
+ Note that this lists the groupings themselves,
361
+ not groups in the groupings or the users in those groups.
362
+
363
+ ### List Groups
364
+
365
+ To list the groups (not groupings) in a course, use the `lms.cli.group.list-groups` tool.
366
+ For example:
367
+ ```
368
+ python3 -m lms.cli.group.list-groups
369
+ ```
370
+
371
+ To limit the results based on grouping, provide a query for that grouping.
372
+ For example:
373
+ ```
374
+ python3 -m lms.cli.group.list-groups 12345
375
+
376
+ # Or
377
+ python3 -m lms.cli.group.list-groups 'My Grouping'
378
+ ```
379
+
380
+ ### List Membership in a Grouping
381
+
382
+ To list the users inside each group within a grouping, use the `lms.cli.group.list-grouping-membership` tool.
383
+ For example:
384
+ ```
385
+ python3 -m lms.cli.group.list-grouping-membership 12345
386
+
387
+ # Or
388
+ python3 -m lms.cli.group.list-grouping-membership 'My Grouping'
389
+ ```
390
+
391
+ ### List Members in a Group
392
+
393
+ To list the users inside a specific group (not a grouping), use the `lms.cli.group.list-group-members` tool.
394
+ For example:
395
+ ```
396
+ python3 -m lms.cli.group.list-group-members 12345
397
+
398
+ # Or
399
+ python3 -m lms.cli.group.list-group-members 'My Group'
400
+ ```