danvas
danvas is a safety-focused command-line tool for day-to-day Canvas course
operations. It helps instructors inspect courses, manage authored content,
download submissions, reconcile grades, and retain evidence for consequential
changes.
Status: signed release v0.20.0 is the latest public beta, not a 1.0 stability
promise. This is an unofficial project.
It is not affiliated with or endorsed by Instructure.
The source tree currently contains the reviewed 0.21.0 Classic Quiz analysis
export candidate. Canvas field acceptance has passed; it is not released until
its independent-review and exact-ref gates pass. The bounded agent scenario has
also passed.
What It Does
- initializes course projects and snapshots Canvas metadata;
- audits assignments, Pages, files, and gradebook exports;
- creates and updates assignments, announcements, discussions, and Pages from local sources;
- downloads rosters, submissions, feedback material, and course files;
- plans and verifies grade, comment, feedback, quiz-import, and file-upload transactions;
- scores discussions into a private
grades post-compatible plan; - acquires verified private Classic Quiz student-analysis CSVs for local inspection;
- experimentally downloads Panopto captions through a Canvas LTI launch;
- provides workflow-rich help, offline task guides, and versioned JSON command discovery; and
- packages a portable Agent Skill with an explicit no-clobber installer.
It intentionally does not manage archival ledger or history databases.
Requirements
- Linux or macOS;
- Python 3.12, 3.13, or 3.14; and
uvfor the supported installation path.
Windows is unsupported because danvas cannot enforce its POSIX private-file permission contract there.
Install
Install the current public beta from PyPI:
uv tool install danvas-cli
For an exact Git-ref installation directly from the repository instead:
uv tool install \
"danvas-cli @ git+https://github.com/olearydj/danvas.git@v0.20.0"
The Python distribution is named danvas-cli; the installed command and import
package remain danvas. Users upgrading from 0.19.x should follow the
0.20.0 agent-interface migration. Users still on
0.18.x must first follow the
0.19.0 credential-boundary migration, and users on
0.17.x must also follow the
0.18.0 distribution migration rather than forcing
one distribution over the other.
Verify the installation outside a source checkout:
uv tool list
danvas --version
danvas --help
danvas auth doctor
Five-Minute Setup
Create a user profile containing non-secret instance and credential references.
The configuration file is danvas/config.toml beneath your platform-standard
user configuration directory.
default_profile = "example-university"
[profiles.example-university]
api_url = "https://canvas.example.edu/"
timezone = "America/New_York"
api_key_env = "CANVAS_EXAMPLE_API_KEY"
Set the referenced token without writing it into either configuration file:
read -rs CANVAS_EXAMPLE_API_KEY
export CANVAS_EXAMPLE_API_KEY
danvas auth doctor --profile example-university --check-canvas
unset CANVAS_EXAMPLE_API_KEY
Danvas consumes the selected variable but does not own the secret store. A credential file or an external runner such as SecretSpec or 1Password can provide the same process boundary. See Authentication.
Initialize a course project. New projects materialize the standard-v1 source
layout in .danvas/config.toml; they do not move or create authored files.
mkdir example-course
cd example-course
danvas init 101 --profile example-university
danvas status
Course IDs, permissions, and available endpoints come from your Canvas deployment. Danvas cannot bypass institutional policy or Canvas authorization.
Safety Model
Canvas-changing commands plan by default. Omitting both flags never authorizes a Canvas mutation:
danvas assignments update content/assignments/week-01.md
danvas assignments update content/assignments/week-01.md --apply
--dry-run is the explicit spelling for the same plan mode. Some higher-risk
commands also require a command-specific --confirm value. Local-writing sync
commands keep their own --dry-run behavior and never gain --apply merely for
writing local sources.
Review generated evidence before applying and after any uncertain outcome. Do not blindly retry a request reported as accepted but unverified.
Private artifacts default beneath .danvas/private/ in initialized projects.
On supported POSIX systems, danvas creates private directories as 0700 and
files as 0600, including temporary files. It does not overwrite private
artifacts by default. Outside a project, private-output commands require an
explicit destination before authentication begins.
Operators remain responsible for institutional data-handling, sharing, and retention requirements.
Common Workflows
# Refresh the local course snapshot without changing Canvas.
danvas refresh --diff
# Validate authored sources without Canvas access.
danvas sources lint
# Plan and then apply one assignment update.
danvas assignments update content/assignments/week-01.md
danvas assignments update content/assignments/week-01.md --apply
# Create a private discussion-grade plan, review it, then use the grade engine.
danvas discussions score \
https://canvas.example.edu/courses/101/discussion_topics/202 2 1 1 5
danvas grades post .danvas/private/discussions/topic-202/grade-plan.csv
danvas grades post \
.danvas/private/discussions/topic-202/grade-plan.csv --apply
# Inspect retained report runs.
danvas reports list
danvas reports latest
# Plan an official Classic Quiz analysis report, then apply after authorization.
danvas quiz export-analysis --course-id 101 --quiz-id 202
danvas quiz export-analysis --course-id 101 --quiz-id 202 --apply
danvas quiz analysis \
.danvas/private/quizzes/quiz-202/student-analysis.csv
Use danvas --help, group help such as danvas assignments --help, and leaf
command help for the current option surface. For longer or structured discovery:
danvas guide list
danvas guide safety
danvas describe assignments update --format json
danvas skill show
danvas skill install --agent shared --dry-run
danvas skill doctor
skill install is an explicit local write, not a Canvas mutation. It installs
only the version-matched bundled danvas skill at one selected allowlisted
agent location. Preview first; modified or unowned targets are refused.
Documentation
- Configuration
- Authentication
- Privacy and retained artifacts
- Compatibility and support
- Authored sources
- Classic Quiz workflows
- Mutation safety
- Course policy YAML
- 0.18.0 migration guide
- 0.19.0 credential-boundary migration
- 0.20.0 agent-interface migration
- 0.21.0 Classic Quiz analysis-export migration
- Changelog
- Contributing
- Security policy
Sprint notes and the backlog record design history; they are not required user instructions.
Development
From a trusted checkout:
uv sync --frozen
uv run ruff check .
uv run ty check
uv run pytest --cov=danvas --cov-branch --cov-fail-under=82
uv run python scripts/check-docs.py
scripts/release-smoke.sh --expected-version 0.21.0
See CONTRIBUTING.md for the complete local gate, safe fixture rules, and the no-live-Canvas default.
License
MIT. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file danvas_cli-0.21.0.tar.gz.
File metadata
- Download URL: danvas_cli-0.21.0.tar.gz
- Upload date:
- Size: 231.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d9b4eb6c111a390b0ba21bacca7c05f13220e5e61c19f32a3e2c1d21feb0e4a
|
|
| MD5 |
c7c83b3c50fc5d2d7eaca9563b949c0c
|
|
| BLAKE2b-256 |
46e0dcf53d0d4a7ebf0c2182ca5381fe647e20e5b32a2094346684ee3ec0ea7e
|
Provenance
The following attestation bundles were made for danvas_cli-0.21.0.tar.gz:
Publisher:
publish-pypi.yml on olearydj/danvas
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
danvas_cli-0.21.0.tar.gz -
Subject digest:
6d9b4eb6c111a390b0ba21bacca7c05f13220e5e61c19f32a3e2c1d21feb0e4a - Sigstore transparency entry: 2470615464
- Sigstore integration time:
-
Permalink:
olearydj/danvas@0953757208a6662ec6e1be3bc3e89ddd4667d212 -
Branch / Tag:
refs/tags/v0.21.0 - Owner: https://github.com/olearydj
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@0953757208a6662ec6e1be3bc3e89ddd4667d212 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file danvas_cli-0.21.0-py3-none-any.whl.
File metadata
- Download URL: danvas_cli-0.21.0-py3-none-any.whl
- Upload date:
- Size: 264.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27163bacd06649bd1b5ea9eb47653da0c383fd19f3fcb25e34c865e80ab92341
|
|
| MD5 |
930e2be4f3cdb22118a6cb5463805db1
|
|
| BLAKE2b-256 |
f5b8d44d286dd7f153237c5caaf11f08fe02691ff91af10ab1b7d3a879df2325
|
Provenance
The following attestation bundles were made for danvas_cli-0.21.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on olearydj/danvas
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
danvas_cli-0.21.0-py3-none-any.whl -
Subject digest:
27163bacd06649bd1b5ea9eb47653da0c383fd19f3fcb25e34c865e80ab92341 - Sigstore transparency entry: 2470615799
- Sigstore integration time:
-
Permalink:
olearydj/danvas@0953757208a6662ec6e1be3bc3e89ddd4667d212 -
Branch / Tag:
refs/tags/v0.21.0 - Owner: https://github.com/olearydj
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@0953757208a6662ec6e1be3bc3e89ddd4667d212 -
Trigger Event:
workflow_dispatch
-
Statement type: