Download files, folders and assignments from Canvas — CLI and desktop GUI
Project description
canvas-dl
Download your files, full course file tree, and assignments (with instructions as PDF) from Canvas — from a friendly desktop app or a powerful CLI. Optionally merge lecture PDFs into one document and zip everything up.
Demo
Download all your Canvas course files in seconds 🚀
Features
- 🖥️ Desktop GUI — a simple window for non-technical users (no terminal needed)
- 📦 Standalone binaries — download & run, no Python install required
- 📚 Download everything — module files, the complete course file tree (with folders), and assignments
- 📝 Assignment instructions as PDF — each assignment's description saved as a readable PDF, plus any attached files
- 🔗 Merge PDFs — combine lecture slides per-module or for the whole course
- 🗜️ Zip output — bundle the whole course into a single archive
- 🔐 Secure token storage — local config,
.env, or environment variables - ⚡ Incremental & polite — skips unchanged files and respects Canvas rate limits
- 🎯 Smart filtering — by file type, glob, or regex
Installation
Option A — Standalone app (easiest, no Python)
Download the latest build for your OS from the Releases page:
- Windows —
canvas-dl-windows.zip→ unzip → runcanvas-dl-gui.exe(GUI) orcanvas-dl.exe(CLI) - macOS —
canvas-dl-macos.tar.gz→ extract → runcanvas-dl-gui - Linux —
canvas-dl-linux.tar.gz→ extract → run./canvas-dl-gui
Option B — Install from PyPI (for Python users)
# with pipx (isolated, recommended)
pipx install canvas-course-dl # CLI only
pipx install "canvas-course-dl[gui]" # CLI + desktop GUI
# or with uv
uv tool install "canvas-course-dl[gui]"
# or plain pip
pip install "canvas-course-dl[gui]"
The installed commands are still canvas-dl and canvas-dl-gui — only the
package name on PyPI differs.
Option C — From source
git clone https://github.com/iasonsky/canvas-dl
cd canvas-dl
uv venv && uv pip install -e ".[gui]"
Quick start
- Get a Canvas access token (see Getting your token).
- Launch the GUI or configure the CLI:
canvas-dl gui # open the desktop app
# or
canvas-dl auth # save your token for the CLI
canvas-dl courses --published
canvas-dl download --course-id 45952 # download everything for a course
The desktop GUI
Run canvas-dl gui (or launch the canvas-dl-gui binary). Paste your token, click
Save, pick a course, choose what to download and where, then hit Download.
Progress and a log are shown live.
┌─ Canvas Downloader ───────────────┐
│ Token: [••••••••••] [Save] │
│ Course: [ Causality ▼ ] │
│ [x] Modules [x] Files [x] Assign. │
│ Only types: [pdf,ipynb ] │
│ [x] Merge PDFs [x] Zip output │
│ Save to: [ ~/Downloads ] [Browse] │
│ [ Download ] ▓▓▓▓▓░░░░ 62% │
└───────────────────────────────────┘
CLI usage
# Download everything (modules + all files + assignments) — the default
canvas-dl download --course-id 45952
# Only the complete file tree, PDFs only
canvas-dl download --course-id 45952 --content files --only pdf
# Only assignments (attachments + instructions.pdf)
canvas-dl download --course-id 45952 --content assignments
# Merge lecture PDFs and zip the result
canvas-dl download --course-id 45952 --merge --merge-scope both --zip
# Pick a course interactively, filter by name, choose a destination
canvas-dl download --name "*lecture*" --dest ~/UVA/Causality
--content sources
| value | what it grabs | layout |
|---|---|---|
modules |
files linked from course modules, organised by module | Modules/<module>/ |
files |
every file in the course, mirroring the Canvas folder tree | Files/<folder>/ |
assignments |
each assignment's attachments + instructions.pdf |
Assignments/<n - name>/ |
all |
all of the above (default) | all of the above |
Pass a comma list (e.g. --content files,assignments) to combine specific sources.
Output layout
downloads/
└── Causality/
├── Modules/
│ └── Week 1/lecture1.pdf
├── Files/
│ └── Lectures/slides.pdf
├── Assignments/
│ └── 01 - Homework 1/
│ ├── instructions.pdf
│ └── handout.pdf
└── Merged/ # with --merge
├── Week 1.pdf
└── Course - all lectures.pdf
A file that appears in several places (e.g. in a module and an assignment) is downloaded only once and copied locally — friendly to Canvas's rate limits.
Getting your token
- Log into Canvas → Account → Settings.
- Under Approved Integrations, click + New Access Token.
- Give it a name, (optionally) an expiry, and Generate Token.
- Copy it (you won't see it again) and paste it into the GUI or
canvas-dl auth.
Configuration
Token & settings are read from (in order): command-line flags → environment →
.env in the current directory → the config file.
- Environment variables:
ACCESS_TOKEN,API_URL - Config file:
- macOS:
~/Library/Application Support/canvas-dl/config.toml - Linux:
~/.config/canvas-dl/config.toml - Windows:
%LOCALAPPDATA%\canvas-dl\config.toml
- macOS:
The default Canvas instance is https://canvas.uva.nl/api/v1; override with
--api-url or API_URL.
Notes & troubleshooting
- "Course Files area is restricted for your account" — some courses hide the
bulk Files tab from students, so
--content filescan't enumerate them. The tool automatically falls back to module/assignment files, which still works. - Rate limits — Canvas throttles per token. canvas-dl makes metadata calls sequentially with a small delay and downloads file content with modest concurrency, so you're very unlikely to be throttled. If you ever are, just re-run — completed files are skipped.
- Assignment instructions are rendered with a built-in PDF engine (no native
dependencies). Embedded images are omitted; if a description can't be rendered
to PDF it's saved as
instructions.htmlinstead.
Roadmap
- ☁️ Save to Google Drive / other cloud storage (planned follow-up)
Development
uv venv && uv pip install -e ".[dev]"
pytest -q
Building the standalone binaries
# Linux/macOS
./scripts/build_binaries.sh
# Windows (PowerShell)
./scripts/build_binaries.ps1
Outputs land in dist/ (canvas-dl one-file CLI, canvas-dl-gui/ GUI folder).
CI builds these for all three OSes and attaches them to a GitHub Release on each
v* tag (see .github/workflows/release.yml).
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
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 canvas_course_dl-0.2.1.tar.gz.
File metadata
- Download URL: canvas_course_dl-0.2.1.tar.gz
- Upload date:
- Size: 37.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
490d46bd24febb8dfc47c3846b6eac23225076f5e8ec0f43f350808675b0088d
|
|
| MD5 |
90026dc20d247e95061aca6c31bdcbd6
|
|
| BLAKE2b-256 |
ddd59eb057b6fc397c8f712b0a344d6a8e99277b76a36dad4ebde53949c77019
|
Provenance
The following attestation bundles were made for canvas_course_dl-0.2.1.tar.gz:
Publisher:
release.yml on iasonsky/canvas-dl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
canvas_course_dl-0.2.1.tar.gz -
Subject digest:
490d46bd24febb8dfc47c3846b6eac23225076f5e8ec0f43f350808675b0088d - Sigstore transparency entry: 2213313534
- Sigstore integration time:
-
Permalink:
iasonsky/canvas-dl@6f6720113549546d857309d497132434f5e7f22c -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/iasonsky
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6f6720113549546d857309d497132434f5e7f22c -
Trigger Event:
push
-
Statement type:
File details
Details for the file canvas_course_dl-0.2.1-py3-none-any.whl.
File metadata
- Download URL: canvas_course_dl-0.2.1-py3-none-any.whl
- Upload date:
- Size: 36.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c2a004a088fdf88892df627579be783c64b6cb348869a0d9df208eb372534b0
|
|
| MD5 |
b7cb364c37ba1587326c8c0a72c7a126
|
|
| BLAKE2b-256 |
cbb6381a9a4b0e4630d5cb5ad537d8de166bfeb38d45800d703972e0ba9fb644
|
Provenance
The following attestation bundles were made for canvas_course_dl-0.2.1-py3-none-any.whl:
Publisher:
release.yml on iasonsky/canvas-dl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
canvas_course_dl-0.2.1-py3-none-any.whl -
Subject digest:
1c2a004a088fdf88892df627579be783c64b6cb348869a0d9df208eb372534b0 - Sigstore transparency entry: 2213313545
- Sigstore integration time:
-
Permalink:
iasonsky/canvas-dl@6f6720113549546d857309d497132434f5e7f22c -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/iasonsky
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6f6720113549546d857309d497132434f5e7f22c -
Trigger Event:
push
-
Statement type: