Skip to main content

LMS Tools

A suite of tools and a Python interface for interacting with different Learning Management Systems (LMSs).

This project is not affiliated with any LMS developer/provider.

Installation

The project (tools and API) can be installed from PyPi with:

pip install edq-lms-toolkit

Standard Python requirements are listed in pyproject.toml. The project and Python dependencies can be installed from source with:

pip3 install .

Cloning

This repository includes submodules. To fetch these submodules on clone, add the --recurse-submodules flag. For example:

git clone --recurse-submodules git@github.com:edulinq/lms-toolkit.git

To fetch the submodules after cloning, you can use:

git submodule update --init --recursive

Usage Notes

Authentication

Different LMSs may require different information for authentication. The below table lists what each LMS needs. Note that values only need to be provided once (in the config or CLI).

LMS Config Keys CLI Options
Blackboard auth_user, auth_password --auth-user, --auth-password
Canvas token --token
Moodle auth_user, auth_password --auth-user, --auth-password

For example, a Canvas config file may look like:

{
    "server": "https://canvas.edulinq.org",
    "token": "abc123"
}

Whereas a Blackboard/Moodle config file may look like:

{
    "server": "https://canvas.edulinq.org",
    "auth_user": "sammy",
    "auth_password": "abc123"
}

Canvas Access Tokens

Canvas access tokens are generated tokens (random numbers/letters) unique to a specific Canvas user. A token provides a means of authenticating a user and password in one piece of information. To acquire a Canvas access token, see Instructure's directions. The standard procedure for obtaining a new token is to go to your account settings ("Account" -> "Settings"), and under "Approved Integrations" click "+ New Access Token". This process may be different for your specific institution and you should contact your institution's Canvas administrators for support.

Object Queries

LMS's typically require that you refer to objects using their specified identifier. Because this may be difficult, the LMS Toolkit provides a way for users to instead refer to object by other identifying fields. Fields with this behavior are referred to as "queries". Unless specified, all inputs into the CLI can be assumed to be queries.

A query can be the LMS identifier, another identifying field, or a combination of the two (referred to as a "label"). The allowed identifying fields varies depending on the object you are referring to, but is generally straightforward. For example, a user can also be identified by their email or full name, while an assignment can be identified by its full name. Labels combine the identifying field with the LMS id, and are most commonly used by the LMS Toolkit when outputting information. For example, a user may be identified by any of the following:

Query Type Query
Email sslug@test.edulinq.org
Name Sammy Slug
ID 123
Label (Email) sslug@test.edulinq.org (123)
Label (Name) Sammy Slug (123)

Output Formats

Many commands can output data in three different formats:

  • Text (--format text) -- A human-readable format (usually the default).
  • Table (--format table) -- A tab-separated table.
  • JSON (--format json) -- A JSON object/list.

Retrieval Operations

When retrieving data from the LMS, this project tends to use two different types of operations:

  • list -- List out all the available entries, e.g., list all the users in a course.
  • get -- Get a collection of entries by query, e.g., get several users by their email.

Groups vs Group Sets

When dealing with groups, there are two structures you need to be familiar with: Groups and Group Sets. A group is a collection of students. A group set (sometimes denoted as "groupset") is a collection of groups, often created for a single purpose (e.g., a set of groups created for a specific assignment). All groups must exist within a group set.

TSV Files

Various operations may require TSV files (tab-separated) files as input. When used, they are usually paired with a --skip-rows option to allow you to skip the desired number of header rows (the default value is generally 0). Empty lines are ignored, and will not be counted against the --skip-rows count.

CLI Tools

All CLI tools can be invoked with -h / --help to see the full usage and all options.

Examples listed here will assume that your authentication information is already defined in your global config file (use --help for more information on that).

Examples listed here are not exhaustive in terms of the available tools or the full functionality of each comment.

The data used in these examples are part of the official test data used for this repo (and other LMS test images).

Retrieve Courses

List all courses associated with a user with lms.cli.courses.list:

python3 -m lms.cli.courses.list

You can get a single course with lms.cli.courses.get:

python3 -m lms.cli.courses.get 'Course 101'

Retrieve Assignments

List all assignments associated with a course with lms.cli.courses.assignments.list:

python3 -m lms.cli.courses.assignments.list --course 'Course 101'

You can get a single assignment with lms.cli.courses.assignments.get:

python3 -m lms.cli.courses.assignments.get --course 'Course 101' 'Homework 0'

Retrieve Assignment Scores

List all student scores for an assignment with lms.cli.courses.assignments.scores.list:

python3 -m lms.cli.courses.assignments.scores.list --course 'Course 101' --assignment 'Homework 0'

The table format is especially useful for listing scores:

python3 -m lms.cli.courses.assignments.scores.list --course 'Course 101' --assignment 'Homework 0' --format table

Upload Assignment Scores

Upload a single score for an assignment and user with lms.cli.courses.assignments.scores.upload-score. For example, to upload a score of 1.0 for user course-student and assignment `Homework 0', use:

python3 -m lms.cli.courses.assignments.scores.upload-score --course 'Course 101' --assignment 'Homework 0' --user 'course-student' 1.0

To upload multiple scores for a single assignment, use lms.cli.courses.assignments.scores.upload. This tool takes a TSV file as input. Each data row can have two or three columns (different rows can have different number of columns). The values are as follows:

  1. User Query
  2. Numeric Score
  3. (Optional) Comment

For example, assume we have a file scores.txt with the following contents:

User	Score	Comment
extra-course-student-1@test.edulinq.org	1
extra-course-student-2@test.edulinq.org	1.5
extra-course-student-3@test.edulinq.org	2	foo
extra-course-student-4@test.edulinq.org	2.5	foo

We can upload these scores for Assignment 1 in the course Extra Course using:

python3 -m lms.cli.courses.assignments.scores.upload --course 'Extra Course' --assignment 'Assignment 1' scores.txt

Retrieve Gradebook

List all gradebook entries associated with a course with lms.cli.courses.gradebook.list:

python3 -m lms.cli.courses.gradebook.list --course 'Course 101'

Gradebooks are always output as TSV tables.

Upload Gradebook

Upload a gradebook with lms.cli.courses.gradebook.upload. The gradebook file must be the same format that is outputted by lms.cli.courses.gradebook.list.

For example, assume we have a file gradebook.txt with the following contents:

User	Assignment 1 (130000100)	Assignment 2 (130000200)
extra-course-student-1@test.edulinq.org (100060000)	1.0	1.0
extra-course-student-2@test.edulinq.org (100070000)		0.5

We can upload these three scores to course Extra Course with:

python3 -m lms.cli.courses.gradebook.upload --course 'Extra Course' gradebook.txt

A gradebook does not need to represent all assignments or students in a course. Only the assignments and students of interest need to be included. An empty cell (missing score) will be ignored, but all rows must have the correct number of cells (tabs).

Retrieve Quiz Metadata

List all quizzes associated with a course with lms.cli.courses.quizzes.list:

python3 -m lms.cli.courses.quizzes.list --course 'Course 101'

Note that this will only retrieve information about a quiz, not the full quiz itself (see Downoad Quizzes for that).

You can get a single quiz with lms.cli.courses.quizzes.get:

python3 -m lms.cli.courses.quizzes.get --course 'Course 101' 'Regular Expressions'

Download Quizzes

Download all quizzes in a course to a directory (in the Quiz Composer format) with lms.cli.courses.quizzes.download:

python3 -m lms.cli.courses.quizzes.download --course 'Course 101' --out-dir 'out'

You can also specify specific quizzes to download instead of all quizzes:

python3 -m lms.cli.courses.quizzes.download --course 'Course 101' --out-dir 'out' 'Regular Expressions'

Upload Quizzes

Upload a quiz (in the Quiz Composer format) with lms.cli.courses.quizzes.upload:

python3 -m lms.cli.courses.quizzes.upload --course 'Course 101' --out-dir 'out'

You can also specify specific quizzes to upload instead of all quizzes:

python3 -m lms.cli.courses.quizzes.upload --course 'Course 101' my-quiz/quiz.json

Retrieve Quiz Questions

Remove a quiz from the LMS with lms.cli.courses.quizzes.remove:

python3 -m lms.cli.courses.quizzes.remove --course 'Course 101' 'Regular Expressions'

You can remove multiple quizzes at once by specifying each quiz you want to remove:

python3 -m lms.cli.courses.quizzes.remove --course 'Course 101' 'Regular Expressions' 'Some Other Quiz'

Retrieve Syllabus

Get a course's syllabus with lms.cli.courses.syllabus.get:

python3 -m lms.cli.courses.syllabus.get --course 'Course 101'

If a course has no syllbus, a message like the following will be output:

<No syllabus found for course: 'Course 101'.>

Retrieve Group Sets

List all groups sets in a course lms.cli.courses.groupsets.list:

python3 -m lms.cli.courses.groupsets.list --course 'Extra Course'

Create Group Sets

Create a new group set with: lms.cli.courses.groupsets.create:

python3 -m lms.cli.courses.groupsets.create --course 'Extra Course' 'My New Group Set'

Delete Group Sets

Delete group sets with: lms.cli.courses.groupsets.delete:

python3 -m lms.cli.courses.groupsets.delete --course 'Extra Course' --groupset 'Group Set 1'

Retrieve Group Set Memberships

List all memberships in a group set with: lms.cli.courses.groupsets.memberships.list:

python3 -m lms.cli.courses.groupsets.memberships.list --course 'Extra Course' --groupset 'Group Set 1'

Add Users to a Group Set

Add users to a group set with: lms.cli.courses.groupsets.memberships.add. This tool takes a TSV file as input. Each data row must have two columns: group query and user query. If a group does not exist, it will be created.

For example, assume we have a file groupset-members.txt with the following contents:

Group	User
My New Group 1	extra-course-student-1@test.edulinq.org
My New Group 1	extra-course-student-2@test.edulinq.org
My New Group 2	extra-course-student-3@test.edulinq.org
My New Group 2	extra-course-student-4@test.edulinq.org

We can add these user to the specified groups using:

python3 -m lms.cli.courses.groupsets.memberships.add --course 'Extra Course' --groupset 'Group Set 3' groupset-members.txt

Subtract Users from a Group Set

Add users to a group set with: lms.cli.courses.groupsets.memberships.subtract. This tool takes a TSV file as input. Each data row must have two columns: group query and user query.

For example, assume we have a file groupset-members.txt with the following contents:

Group	User
Group 1-1	extra-course-student-1@test.edulinq.org
Group 1-2	extra-course-student-3@test.edulinq.org

We can subtract these users from the specified groups using:

python3 -m lms.cli.courses.groupsets.memberships.subtract --course 'Extra Course' --groupset 'Group Set 1' groupset-members.txt

Set Memberships for a Group Set

Set the memberships for an entire group set with: lms.cli.courses.groupsets.memberships.set. This tool takes a TSV file as input. Each data row must have two columns: group query and user query. The group set will be modfied to match your file exactly. This may involve creating or deleting groups.

For example, assume we have a file groupset-members.txt with the following contents:

Group	User
New Group 1	extra-course-student-1@test.edulinq.org
New Group 2	extra-course-student-2@test.edulinq.org
New Group 3	extra-course-student-3@test.edulinq.org
New Group 4	extra-course-student-4@test.edulinq.org

We can use this file to set the group set memberships with:

python3 -m lms.cli.courses.groupsets.memberships.set --course 'Extra Course' --groupset 'Group Set 1' groupset-members.txt

This command will do several things in this case:

  • Create new groups.
  • Remove users from their current groups.
  • Add users to their new groups.
  • Delete old (now empty) groups.

Retrieve Groups

List all the groups for a group set with lms.cli.courses.groups.list:

python3 -m lms.cli.courses.groups.list --course 'Extra Course' --groupset 'Group Set 1'

Create Groups

Create a new group with: lms.cli.courses.groups.create:

python3 -m lms.cli.courses.groups.create --course 'Extra Course' --groupset 'Group Set 1' 'My New Group'

Delete Groups

Delete groups with: lms.cli.courses.groups.delete:

python3 -m lms.cli.courses.groups.delete --course 'Extra Course' --groupset 'Group Set 1' --group 'Group 1-1'

Retrieve Group Memberships

List all memberships in a group with: lms.cli.courses.groups.memberships.list:

python3 -m lms.cli.courses.groups.memberships.list --course 'Extra Course' --groupset 'Group Set 1' --group 'Group 1-1'

Add Users to a Group

Add users to a group with: lms.cli.courses.groups.memberships.add:

python3 -m lms.cli.courses.groups.memberships.add --course 'Extra Course' --groupset 'Group Set 3' --group 'Group 3-1' extra-course-student-1

You can specify as many users as you want.

Subtract Users from a Group

Subtract users from a group with: lms.cli.courses.groups.memberships.subtract:

python3 -m lms.cli.courses.groups.memberships.subtract --course 'Extra Course' --groupset 'Group Set 1' --group 'Group 1-1' extra-course-student-1

You can specify as many users as you want.

Set Users for a Group

Set the users in a group with: lms.cli.courses.groups.memberships.set:

python3 -m lms.cli.courses.groups.memberships.set --course 'Extra Course' --groupset 'Group Set 1' --group 'Group 1-1' extra-course-student-2 extra-course-student-3

This operation will add and subtract any users necessary to make the group have exactly the users specified.

Retrieve Users

List all users associated with a course with lms.cli.courses.users.list:

python3 -m lms.cli.courses.users.list --course 'Course 101'

You can get a single user with lms.cli.courses.users.get:

python3 -m lms.cli.courses.users.get --course 'Course 101' 'course-student'

Retrieve User Scores

List all scores for a student with lms.cli.courses.users.scores.list:

python3 -m lms.cli.courses.users.scores.list --course 'Extra Course' --user 'extra-course-student-1'

The table format is especially useful for listing scores:

python3 -m lms.cli.courses.users.scores.list --course 'Extra Course' --user 'extra-course-student-1' --format table

LMS Coverage

The LMS Toolkit is constantly expanding its support with hopes for supporting all major LMSs.

Legend:

  • ✅ -- Supported
  • - -- Not Yet Supported
  • x -- Support Impossible (See Notes)
Tool Blackboard Canvas Moodle
lms.cli.courses.get
lms.cli.courses.list
lms.cli.courses.assignments.get - -
lms.cli.courses.assignments.list - -
lms.cli.courses.assignments.scores.get - -
lms.cli.courses.assignments.scores.list - -
lms.cli.courses.assignments.scores.upload - -
lms.cli.courses.assignments.scores.upload-score - -
lms.cli.courses.gradebook.get - -
lms.cli.courses.gradebook.list - -
lms.cli.courses.gradebook.upload - -
lms.cli.courses.groups.create - -
lms.cli.courses.groups.delete - -
lms.cli.courses.groups.get - -
lms.cli.courses.groups.list - -
lms.cli.courses.groups.memberships.add - -
lms.cli.courses.groups.memberships.list - -
lms.cli.courses.groups.memberships.set - -
lms.cli.courses.groups.memberships.subtract - -
lms.cli.courses.groupsets.create - -
lms.cli.courses.groupsets.delete - -
lms.cli.courses.groupsets.get - -
lms.cli.courses.groupsets.list - -
lms.cli.courses.groupsets.memberships.add - -
lms.cli.courses.groupsets.memberships.list - -
lms.cli.courses.groupsets.memberships.set - -
lms.cli.courses.groupsets.memberships.subtract - -
lms.cli.courses.quizzes.download - -
lms.cli.courses.quizzes.get - -
lms.cli.courses.quizzes.list - -
lms.cli.courses.quizzes.remove - -
lms.cli.courses.quizzes.upload - -
lms.cli.courses.syllabus.get - -
lms.cli.courses.users.get
lms.cli.courses.users.list
lms.cli.courses.users.scores.get - -
lms.cli.courses.users.scores.list - -
lms.cli.server.identify

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

edq_lms_toolkit-2.0.0.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

edq_lms_toolkit-2.0.0-py3-none-any.whl (256.4 kB view details)

Uploaded Python 3

File details

Details for the file edq_lms_toolkit-2.0.0.tar.gz.

File metadata

  • Download URL: edq_lms_toolkit-2.0.0.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for edq_lms_toolkit-2.0.0.tar.gz
Algorithm Hash digest
SHA256 ab06276300e0511a773400cd1253cd01dcb01664f177461f99bd49151915450d
MD5 47bbf2d97a28a0078a6080ba234165d4
BLAKE2b-256 62df85a24a2c74a117677ac0d30cc379891bf2d202dccfe63f7f0ca5711057a4

See more details on using hashes here.

File details

Details for the file edq_lms_toolkit-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: edq_lms_toolkit-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 256.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for edq_lms_toolkit-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a6580717d5218a6d6def1a2a1c076617baa68cd24c9d56eb5fdf60b1cd77f624
MD5 64684f47c0289abddaf9f787af61c080
BLAKE2b-256 68231c28e26b7fb2ca3490c518ee7ed3394ca0d784acefa201d0ddb25ffc588a

See more details on using hashes here.

Release history Release notifications | RSS feed

2.0.2

2 files

2.0.1

2 files

This release

2.0.0 This release

2 files

1.2.1

2 files

1.2.0

2 files

1.1.9

2 files

1.1.8

2 files

1.1.7

2 files

1.1.6

2 files

1.1.5

2 files

1.1.4

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.9

2 files

1.0.8

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page