cass.apis¶
Typed Canvas LMS client and response schemas (msgspec.Struct types, Canvas-prefixed).
cass.apis ¶
External service API clients and response schemas.
canvas ¶
Canvas LMS integration — API client, roster matching, eGrades export.
auth ¶
Canvas authentication — API token or browser session cookie.
Two ways to authenticate against the Canvas API:
TokenAuth: a personal API token sent as a Bearer header. Read from.canvastokenor$CANVAS_TOKEN.SessionAuth: thecanvas_sessionand_csrf_tokencookies copied from a logged-in browser. Read from.canvascreds. Useful when no API token is available; cookies expire after roughly a day.
find_auth picks whichever is configured, preferring .canvastoken
because a token lasts months while browser cookies last about a day.
CanvasAuthError ¶
Bases: RuntimeError
Canvas rejected our credentials, with instructions on how to fix them.
Browser ¶
Bases: StrEnum
Supported browser imports on macOS.
BrowserSource
dataclass
¶
Browser profile and Canvas origin authorized to refresh a credential file.
TokenAuth
dataclass
¶
Bearer-token authentication.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
Canvas personal API token. |
required |
source
|
str
|
Where the token came from (file name or |
required |
SessionAuth
dataclass
¶
SessionAuth(
session: str,
csrf_token: str,
source: str,
browser_source: BrowserSource | None = None,
)
Browser session-cookie authentication.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
str
|
Value of the |
required |
csrf_token
|
str
|
URL-decoded value of the |
required |
source
|
str
|
File the cookies were read from. |
required |
browser_source
|
BrowserSource | None
|
Browser and profile to refresh an imported session from. |
None
|
parse_creds ¶
Parse a .canvascreds file of name=value cookie lines.
Values may be quoted (as copied from browser devtools) and the CSRF token may be URL-encoded or decoded; both forms are normalised.
Raises:
| Type | Description |
|---|---|
SystemExit
|
If |
find_auth ¶
Locate Canvas credentials for the project at root.
Order: .canvastoken, .canvascreds (session cookie), $CANVAS_TOKEN.
Returns:
| Type | Description |
|---|---|
CanvasAuth | None
|
The configured auth, or |
check_request ¶
Fail fast before sending a request the credentials cannot satisfy.
Raises:
| Type | Description |
|---|---|
CanvasAuthError
|
For a write with a session cookie but no CSRF token. |
check_response ¶
Translate credential failures into a CanvasAuthError with guidance.
Raises:
| Type | Description |
|---|---|
CanvasAuthError
|
On 401, or on a CSRF-rejected write under session auth. |
browser ¶
Import a Canvas session from Brave or Google Chrome on macOS.
read_browser_session ¶
Read Canvas cookies from one profile, using macOS Keychain access.
validate_session ¶
validate_session(
auth: SessionAuth,
origin: str,
*,
transport: BaseTransport | None = None,
) -> None
Check authentication with a read-only request before replacing credentials.
save_browser_session ¶
Atomically replace the credential file with owner-only permissions.
login_from_browser ¶
login_from_browser(
root: Path,
base_url: str,
profile: str = "Default",
*,
browser: Browser = Browser.BRAVE,
transport: BaseTransport | None = None,
) -> SessionAuth
Import, validate, and save a refreshable browser session for this project.
client ¶
Canvas LMS API client — typed CRUD for every Canvas resource.
Provides CanvasClient, a typed httpx client with course_id baked in.
All methods return msgspec.Struct instances, never raw dicts. The client is
assembled from one mixin per resource; base holds the transport, auth
lookup, pagination, and the shared _resolve helper.
BaseClient ¶
BaseClient(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Typed Canvas LMS API client with course_id baked in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str | None
|
Canvas instance URL (e.g. |
None
|
token
|
str | None
|
Canvas API bearer token (shortcut for |
None
|
course_id
|
int | None
|
Canvas course ID for all requests. |
None
|
auth
|
CanvasAuth | None
|
Credentials to use; defaults to whatever |
None
|
transport
|
BaseTransport | None
|
HTTP transport override (tests inject a mock here). |
None
|
time_zone
|
str | None
|
IANA course time zone; defaults to |
None
|
time_zone
property
¶
IANA time zone of the course (from cass.toml, else fetched once).
request ¶
Send any request with cass's auth and retry handling.
Use self._course(path) for course-relative paths. Raises
httpx.HTTPStatusError on a 4xx/5xx response.
publish ¶
Publish a resource (module, assignment, or quiz).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
resource
|
str
|
Resource type ( |
required |
resource_id
|
int
|
Canvas resource ID. |
required |
unpublish ¶
Unpublish a resource (module, assignment, or quiz).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
resource
|
str
|
Resource type ( |
required |
resource_id
|
int
|
Canvas resource ID. |
required |
RetryTransport ¶
RetryTransport(
*,
auth: CanvasAuth,
retries: int = 0,
wrapped: BaseTransport | None = None,
refresh: Callable[[], SessionAuth] | None = None,
)
Bases: BaseTransport
Wraps a transport with 429 retry, backoff, throttling, and auth checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
auth
|
CanvasAuth
|
Credentials in use; credential failures (401, CSRF rejection)
are raised as |
required |
retries
|
int
|
Connection-level retries for the underlying HTTP transport. |
0
|
wrapped
|
BaseTransport | None
|
Transport to delegate to (defaults to |
None
|
refresh
|
Callable[[], SessionAuth] | None
|
Import fresh credentials after a 401, at most once per request. |
None
|
CanvasClient ¶
CanvasClient(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: CourseMixin, ModulesMixin, AssignmentsMixin, GradesMixin, QuizzesMixin, FilesMixin, AnnouncementsMixin, CalendarMixin, TabsMixin, BaseClient
Typed Canvas LMS API client with course_id baked in.
See BaseClient for constructor arguments.
get_auth ¶
Locate Canvas credentials for the current project.
Prefers .canvastoken, then .canvascreds (browser session cookie),
then $CANVAS_TOKEN.
Raises:
| Type | Description |
|---|---|
SystemExit
|
If no credentials are found. |
get_token ¶
Read the Canvas API token from .canvastoken or $CANVAS_TOKEN.
Raises:
| Type | Description |
|---|---|
SystemExit
|
If no token is found. |
resource_key ¶
Map a plural resource name to Canvas API parameter key.
announcements ¶
Announcements (discussion topics flagged as announcements).
AnnouncementsMixin ¶
AnnouncementsMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Announcements (discussion topics flagged as announcements).
List course announcements.
Returns:
| Type | Description |
|---|---|
list[CanvasAnnouncement]
|
Announcements sorted by posted_at descending. |
Create an announcement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Announcement title. |
required |
message
|
str
|
HTML body. |
required |
Returns:
| Type | Description |
|---|---|
CanvasAnnouncement
|
The created announcement. |
Update an announcement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
topic_id
|
int
|
Discussion topic ID. |
required |
**kwargs
|
object
|
Fields to update (title, message). |
{}
|
Returns:
| Type | Description |
|---|---|
CanvasAnnouncement
|
The updated announcement. |
assignments ¶
Assignments and assignment groups.
AssignmentsMixin ¶
AssignmentsMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Assignments and assignment groups.
List all course assignments.
Returns:
| Type | Description |
|---|---|
list[CanvasAssignmentResponse]
|
Assignments from all assignment groups. |
Get a single assignment by ID.
create_assignment(
name: str,
*,
points_possible: float = 0.0,
due_at: str | None = None,
submission_types: list[str] | None = None,
published: bool = False,
assignment_group_id: int | None = None,
description: str | None = None,
grading_type: str = "points",
) -> CanvasAssignmentResponse
Create a new assignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Assignment name. |
required |
points_possible
|
float
|
Total points. |
0.0
|
due_at
|
str | None
|
Due date in ISO 8601 format. |
None
|
submission_types
|
list[str] | None
|
Allowed submission types. |
None
|
published
|
bool
|
Whether to publish immediately. |
False
|
assignment_group_id
|
int | None
|
Assignment group to place in. |
None
|
description
|
str | None
|
HTML description. |
None
|
grading_type
|
str
|
Grading type (points, letter_grade, etc.). |
'points'
|
Returns:
| Type | Description |
|---|---|
CanvasAssignmentResponse
|
The created assignment. |
Update an assignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assignment_id
|
int
|
Canvas assignment ID. |
required |
**kwargs
|
object
|
Fields to update (name, points_possible, due_at, published, etc.). |
{}
|
Returns:
| Type | Description |
|---|---|
CanvasAssignmentResponse
|
The updated assignment. |
List assignment groups (grade categories).
Returns:
| Type | Description |
|---|---|
list[CanvasAssignmentGroup]
|
Assignment groups with weights and rules. |
create_assignment_group(
name: str,
*,
position: int | None = None,
group_weight: float | None = None,
) -> CanvasAssignmentGroup
Create a new assignment group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Group name. |
required |
position
|
int | None
|
Optional position in the group list. |
None
|
group_weight
|
float | None
|
Optional percentage weight for weighted grades. |
None
|
Returns:
| Type | Description |
|---|---|
CanvasAssignmentGroup
|
The created assignment group. |
Delete an assignment group (Canvas also deletes its assignments).
Resolve an assignment group by numeric ID or name (case-insensitive).
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no group matches; the message lists the available groups. |
Resolve an assignment by numeric ID or name (case-insensitive).
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no assignment matches. |
base ¶
Canvas client foundation — auth lookup, HTTP transport, and BaseClient.
Resource mixins in this package subclass BaseClient and are combined into
CanvasClient in __init__.
RetryTransport ¶
RetryTransport(
*,
auth: CanvasAuth,
retries: int = 0,
wrapped: BaseTransport | None = None,
refresh: Callable[[], SessionAuth] | None = None,
)
Bases: BaseTransport
Wraps a transport with 429 retry, backoff, throttling, and auth checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
auth
|
CanvasAuth
|
Credentials in use; credential failures (401, CSRF rejection)
are raised as |
required |
retries
|
int
|
Connection-level retries for the underlying HTTP transport. |
0
|
wrapped
|
BaseTransport | None
|
Transport to delegate to (defaults to |
None
|
refresh
|
Callable[[], SessionAuth] | None
|
Import fresh credentials after a 401, at most once per request. |
None
|
BaseClient ¶
BaseClient(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Typed Canvas LMS API client with course_id baked in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str | None
|
Canvas instance URL (e.g. |
None
|
token
|
str | None
|
Canvas API bearer token (shortcut for |
None
|
course_id
|
int | None
|
Canvas course ID for all requests. |
None
|
auth
|
CanvasAuth | None
|
Credentials to use; defaults to whatever |
None
|
transport
|
BaseTransport | None
|
HTTP transport override (tests inject a mock here). |
None
|
time_zone
|
str | None
|
IANA course time zone; defaults to |
None
|
property
¶IANA time zone of the course (from cass.toml, else fetched once).
Send any request with cass's auth and retry handling.
Use self._course(path) for course-relative paths. Raises
httpx.HTTPStatusError on a 4xx/5xx response.
Publish a resource (module, assignment, or quiz).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
resource
|
str
|
Resource type ( |
required |
resource_id
|
int
|
Canvas resource ID. |
required |
Unpublish a resource (module, assignment, or quiz).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
resource
|
str
|
Resource type ( |
required |
resource_id
|
int
|
Canvas resource ID. |
required |
get_auth ¶
Locate Canvas credentials for the current project.
Prefers .canvastoken, then .canvascreds (browser session cookie),
then $CANVAS_TOKEN.
Raises:
| Type | Description |
|---|---|
SystemExit
|
If no credentials are found. |
get_token ¶
Read the Canvas API token from .canvastoken or $CANVAS_TOKEN.
Raises:
| Type | Description |
|---|---|
SystemExit
|
If no token is found. |
resource_key ¶
Map a plural resource name to Canvas API parameter key.
calendar ¶
Course calendar events.
CalendarMixin ¶
CalendarMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Course calendar events.
list_calendar_events(
*,
start_date: str | None = None,
end_date: str | None = None,
) -> list[CanvasCalendarEvent]
List calendar events on this course's calendar.
Canvas defaults to today's events only, so without a date range this requests every event on the course calendar.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_date
|
str | None
|
Inclusive lower bound (YYYY-MM-DD or ISO 8601). |
None
|
end_date
|
str | None
|
Inclusive upper bound (YYYY-MM-DD or ISO 8601). |
None
|
Returns:
| Type | Description |
|---|---|
list[CanvasCalendarEvent]
|
Calendar events (assignment due dates are not included). |
create_calendar_event(
title: str,
*,
start_at: str,
end_at: str | None = None,
description: str | None = None,
location_name: str | None = None,
all_day: bool = False,
) -> CanvasCalendarEvent
Create a calendar event on this course's calendar.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Event title. |
required |
start_at
|
str
|
Start date/time (ISO 8601). |
required |
end_at
|
str | None
|
End date/time (ISO 8601). |
None
|
description
|
str | None
|
HTML description. |
None
|
location_name
|
str | None
|
Location name. |
None
|
all_day
|
bool
|
Ignore times and span the whole day. |
False
|
Returns:
| Type | Description |
|---|---|
CanvasCalendarEvent
|
The created event. |
Update a calendar event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_id
|
int
|
Calendar event ID. |
required |
**kwargs
|
object
|
Fields to update (title, start_at, end_at, description, location_name, all_day). |
{}
|
Returns:
| Type | Description |
|---|---|
CanvasCalendarEvent
|
The updated event. |
course ¶
Course, people, sections, enrollments, and grading standards.
CourseMixin ¶
CourseMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Course, people, sections, enrollments, and grading standards.
List course users with enrollments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enrollment_type
|
str | None
|
Filter by role (e.g. |
None
|
Returns:
| Type | Description |
|---|---|
list[CanvasUser]
|
Users sorted by name. |
List students enrolled in the course.
Returns:
| Type | Description |
|---|---|
list[CanvasStudentResponse]
|
Students sorted by Canvas enrollment order. |
List all course sections.
Returns:
| Type | Description |
|---|---|
list[CanvasSection]
|
Sections with SIS IDs (if available). |
List enrollments with computed scores.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enrollment_type
|
str
|
Filter by type (default: StudentEnrollment). |
'StudentEnrollment'
|
Returns:
| Type | Description |
|---|---|
list[CanvasEnrollment]
|
Enrollments including computed_final_score. |
List grading standards available for this course.
Returns:
| Type | Description |
|---|---|
list[CanvasGradingStandard]
|
Grading standards with scheme entries. |
files ¶
Files and folders.
FilesMixin ¶
FilesMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Files and folders.
List files in the course or a specific folder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder_id
|
int | None
|
Optional folder ID to scope the listing. |
None
|
Returns:
| Type | Description |
|---|---|
list[CanvasFile]
|
File metadata sorted by name. |
List all folders in the course.
Returns:
| Type | Description |
|---|---|
list[CanvasFolder]
|
Folders with hierarchy info. |
Upload a file to the course.
Uses Canvas's 3-step file upload flow: 1. Notify Canvas to get an upload URL 2. POST the file to the upload URL 3. Confirm the upload
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
local_path
|
str
|
Path to the local file. |
required |
folder
|
str
|
Destination folder path in Canvas (e.g. |
''
|
Returns:
| Type | Description |
|---|---|
CanvasFile
|
The uploaded file metadata. |
grades ¶
Submissions, grade pushes, progress polling, and grade posting.
GradesMixin ¶
GradesMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Submissions, grade pushes, progress polling, and grade posting.
List submissions for an assignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assignment_id
|
int
|
Canvas assignment ID. |
required |
Returns:
| Type | Description |
|---|---|
list[CanvasSubmissionResponse]
|
All submissions for the assignment. |
Push a single grade to Canvas.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assignment_id
|
int
|
Canvas assignment ID. |
required |
student_canvas_id
|
int
|
Student's Canvas user ID. |
required |
grade
|
str
|
Grade string to post. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True on success, False on failure. |
Push grades in bulk for one assignment via the update_grades endpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assignment_id
|
int
|
Canvas assignment ID. |
required |
grade_data
|
dict[int, str]
|
Mapping of student_canvas_id → posted_grade string. |
required |
Returns:
| Type | Description |
|---|---|
CanvasProgress
|
Progress object for tracking completion. |
Check the status of an async Canvas operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_id
|
int
|
Progress object ID. |
required |
Returns:
| Type | Description |
|---|---|
CanvasProgress
|
Current progress state. |
Poll a progress object until completion or timeout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_id
|
int
|
Progress object ID. |
required |
timeout
|
float
|
Maximum seconds to wait. |
120.0
|
Returns:
| Type | Description |
|---|---|
CanvasProgress
|
Completed or failed progress object. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the progress times out or fails. |
Post (reveal) grades to students for a manual-post assignment.
Uses the Canvas GraphQL postAssignmentGrades mutation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assignment_id
|
int
|
Canvas assignment ID. |
required |
graded_only
|
bool
|
If True, only post grades for graded submissions. |
True
|
Returns:
| Type | Description |
|---|---|
CanvasProgress | None
|
Progress object for tracking, or None if no progress was started. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the mutation returns validation errors. |
Hide grades from students for a manual-post assignment.
Uses the Canvas GraphQL hideAssignmentGrades mutation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assignment_id
|
int
|
Canvas assignment ID. |
required |
Returns:
| Type | Description |
|---|---|
CanvasProgress | None
|
Progress object for tracking, or None if no progress was started. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the mutation returns validation errors. |
modules ¶
Modules and module items.
ModulesMixin ¶
ModulesMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Modules and module items.
List items in a module.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module_id
|
int
|
Canvas module ID. |
required |
Returns:
| Type | Description |
|---|---|
list[CanvasModuleItem]
|
Module items sorted by position. |
Create a new module.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Module name. |
required |
position
|
int | None
|
Optional position in the module list. |
None
|
Returns:
| Type | Description |
|---|---|
CanvasModule
|
The created module. |
Update a module.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module_id
|
int
|
Canvas module ID. |
required |
**kwargs
|
object
|
Fields to update (name, position, published). |
{}
|
Returns:
| Type | Description |
|---|---|
CanvasModule
|
The updated module. |
create_module_item(
module_id: int,
*,
item_type: str,
content_id: int,
title: str | None = None,
) -> CanvasModuleItem
Add an item to a module.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
module_id
|
int
|
Canvas module ID. |
required |
item_type
|
str
|
Item type (Assignment, Quiz, File, etc.). |
required |
content_id
|
int
|
ID of the linked content. |
required |
title
|
str | None
|
Item title; Canvas uses the content's name when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
CanvasModuleItem
|
The created module item. |
Resolve a module by numeric ID or name (case-insensitive).
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no module matches. |
quizzes ¶
Classic quizzes, quiz questions, reports, and quiz submissions.
QuizzesMixin ¶
QuizzesMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Classic quizzes and quiz questions.
Create a quiz with its questions.
Posts the quiz unpublished, posts each question in order, then re-saves
the quiz (applying spec.published) so Canvas recomputes
question_count and points_possible. If a question post fails
the partial quiz is deleted and the error re-raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
QuizSpec
|
Settings and questions; times are parsed in the course zone. |
required |
assignment_group_id
|
int | None
|
Assignment group to place the quiz in. |
None
|
Returns:
| Type | Description |
|---|---|
CanvasQuiz
|
The quiz as re-fetched after the re-save. |
Update quiz settings.
Only the given Canvas fields are sent; questions are never touched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quiz_id
|
int
|
Canvas quiz ID. |
required |
changes
|
dict[str, object]
|
Canvas field name → new value (see |
required |
Returns:
| Type | Description |
|---|---|
CanvasQuiz
|
The updated quiz. |
List a quiz's questions in position order.
Concluded courses return 403 from the questions endpoint; then the
questions are rebuilt from /statistics, which carries text and
which answers are correct but no answer weights or names.
Returns:
| Type | Description |
|---|---|
tuple[list[CanvasQuizQuestion], bool]
|
|
create_quiz_question(
quiz_id: int,
question: QuestionSpec,
position: int,
*,
quiz_type: str = "assignment",
) -> CanvasQuizQuestion
Add one question to a quiz.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quiz_id
|
int
|
Canvas quiz ID. |
required |
question
|
QuestionSpec
|
Question spec; |
required |
position
|
int
|
1-based position; also the default name ( |
required |
quiz_type
|
str
|
Decides the default points (0 for surveys, else 1). |
'assignment'
|
Returns:
| Type | Description |
|---|---|
CanvasQuizQuestion
|
The created question. |
Ask Canvas to generate a student analysis report.
Canvas returns the existing report when one is already current, so repeating the call is cheap. Works on concluded courses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quiz_id
|
int
|
Canvas quiz ID. |
required |
all_versions
|
bool
|
Report every attempt instead of only the latest. |
False
|
Returns:
| Type | Description |
|---|---|
CanvasQuizReport
|
The report; |
Get a quiz report with its file and progress.
download_quiz_report(
quiz_id: int,
*,
all_versions: bool = False,
timeout: float = 300.0,
interval: float = 2.0,
) -> str
Generate a student analysis report, wait for it, and download it.
Generation typically takes about 30 seconds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
quiz_id
|
int
|
Canvas quiz ID. |
required |
all_versions
|
bool
|
Report every attempt instead of only the latest. |
False
|
timeout
|
float
|
Maximum seconds to wait for Canvas to build the file. |
300.0
|
interval
|
float
|
Seconds between polls. |
2.0
|
Returns:
| Type | Description |
|---|---|
str
|
The report CSV text. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If generation fails or times out. |
List each student's latest attempt on a quiz.
Returns:
| Type | Description |
|---|---|
list[CanvasQuizSubmission]
|
One quiz submission per student who opened the quiz. |
Resolve a quiz by numeric ID or title (case-insensitive).
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no quiz matches. |
tabs ¶
Course navigation tabs.
TabsMixin ¶
TabsMixin(
base_url: str | None = None,
token: str | None = None,
course_id: int | None = None,
*,
auth: CanvasAuth | None = None,
transport: BaseTransport | None = None,
time_zone: str | None = None,
)
Bases: BaseClient
Course navigation tabs.
List course navigation tabs.
Returns:
| Type | Description |
|---|---|
list[CanvasTab]
|
Tabs with visibility and position. |
Show or hide a navigation tab.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tab_id
|
str
|
Tab ID string. |
required |
hidden
|
bool
|
True to hide, False to show. |
required |
Returns:
| Type | Description |
|---|---|
CanvasTab
|
The updated tab. |
Resolve a navigation tab by ID (e.g. syllabus) or label.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no tab matches. |
egrades ¶
eGrades CSV export — UCSD final grade submission format.
Generates the 5-column CSV required by UCSD's eGrades system:
Last Name, First Name, Student ID, SectionId, Final_Assigned_Egrade
Uses the Canvas enrollments API for computed_final_score and the
course grading standard to convert percentages to letter grades.
score_to_letter ¶
Convert a percentage score to a letter grade using a grading scheme.
Canvas grading schemes are lists of {name, value} entries sorted
descending by value. Each entry means "scores >= value * 100 earn
this letter."
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pct
|
float | None
|
Percentage score (0-100), or None for missing. |
required |
scheme
|
list[CanvasGradingSchemeEntry]
|
Grading scheme entries (will be sorted internally). |
required |
Returns:
| Type | Description |
|---|---|
str
|
Letter grade string, or |
parse_sortable_name ¶
Parse Canvas sortable_name into (last_name, first_name).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sortable_name
|
str
|
Name in "Last, First" format. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Tuple of (last_name, first_name). Falls back to full string |
str
|
as last name if no comma found. |
generate_egrades ¶
Generate an eGrades CSV file from Canvas data.
Fetches enrollments with computed_final_score, resolves the active grading scheme, and writes the UCSD eGrades format CSV.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output
|
str | Path
|
Output file path. |
'egrades.csv'
|
Returns:
| Type | Description |
|---|---|
tuple[Path, int, list[str]]
|
Tuple of (path, row_count, warnings). |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no grading standard is configured or no students found. |
matching ¶
Canvas LMS integration — roster fetching, submission retrieval, and grade push.
All raw API calls are delegated to CanvasClient in client.py.
get_token ¶
Read the Canvas API token from .canvastoken or $CANVAS_TOKEN.
Raises:
| Type | Description |
|---|---|
SystemExit
|
If no token is found. |
fetch_students ¶
Fetch all students enrolled in a Canvas course.
fetch_course_name ¶
Fetch the course name from the Canvas API.
fetch_course_time_zone ¶
Read the course's IANA time zone from Canvas.
fetch_students_with_sections ¶
fetch_students_with_sections(
course_id: int,
) -> tuple[list[CanvasStudentResponse], dict[int, str]]
Fetch students and build a canvas_id -> sis_section_id mapping.
Uses the users endpoint (with enrollments) and sections endpoint to resolve each student's SIS section ID.
Returns:
| Type | Description |
|---|---|
list[CanvasStudentResponse]
|
Tuple of (students, sis_section_map) where sis_section_map maps |
dict[int, str]
|
canvas_id to sis_section_id. |
fetch_canvas_assignments ¶
fetch_canvas_assignments(
course_id: int,
) -> tuple[list[CanvasAssignmentResponse], dict[int, str]]
Fetch all assignments and assignment group names from Canvas.
Returns:
| Type | Description |
|---|---|
list[CanvasAssignmentResponse]
|
Tuple of (assignments, group_names) where group_names maps |
dict[int, str]
|
assignment_group_id to group name. |
fetch_canvas_submissions ¶
fetch_canvas_submissions(
course_id: int,
canvas_assignment_id: int,
known_canvas_ids: set[int],
) -> list[CanvasSubmission]
Fetch submissions for a Canvas assignment, filtered to known students.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
course_id
|
int
|
Canvas course ID. |
required |
canvas_assignment_id
|
int
|
Canvas assignment ID. |
required |
known_canvas_ids
|
set[int]
|
Set of canvas_ids from the students table. |
required |
Returns:
| Type | Description |
|---|---|
list[CanvasSubmission]
|
CanvasSubmission domain objects for known students. |
push_grade ¶
Push a single grade to Canvas. Returns True on success, False on failure.
schema ¶
Canvas LMS API response types.
CanvasCourse ¶
Bases: Struct
Canvas course details.
CanvasStudentResponse ¶
Bases: Struct
Canvas student (user enrolled as student).
CanvasEnrollmentGrades ¶
Bases: Struct
Nested grades object inside a Canvas enrollment.
CanvasEnrollment ¶
CanvasUser ¶
Bases: Struct
Canvas user with optional enrollments.
CanvasSection ¶
Bases: Struct
Canvas course section.
CanvasGradingSchemeEntry ¶
Bases: Struct
Single entry in a Canvas grading scheme (e.g. A = 0.94).
CanvasGradingStandard ¶
Bases: Struct
Canvas grading standard with scheme entries.
CanvasModuleItem ¶
Bases: Struct
Single item within a Canvas module.
CanvasModule ¶
Bases: Struct
Canvas module (content grouping).
CanvasAssignmentResponse ¶
Bases: Struct
Canvas assignment.
CanvasAssignmentGroup ¶
Bases: Struct
Canvas assignment group (weighted grade category).
CanvasQuiz ¶
Bases: Struct
Canvas quiz.
CanvasQuizAnswer ¶
Bases: Struct
One answer on a Canvas quiz question.
CanvasQuizQuestion ¶
Bases: Struct
Canvas quiz question with its answers.
CanvasQuizReportFile ¶
Bases: Struct
File attached to a generated quiz report.
CanvasQuizReport ¶
Bases: Struct
Canvas quiz report (include[]=file,progress).
file is None until Canvas finishes generating the CSV.
CanvasQuizSubmission ¶
Bases: Struct
A student's latest classic quiz attempt (/quizzes/:id/submissions).
CanvasFile ¶
Bases: Struct
Canvas file metadata.
CanvasFolder ¶
Bases: Struct
Canvas folder in the file hierarchy.
CanvasAnnouncement ¶
Bases: Struct
Canvas announcement (discussion_topic with is_announcement=true).
CanvasCalendarEvent ¶
Bases: Struct
Canvas calendar event (type=event; assignment due dates are not included).
CanvasTab ¶
Bases: Struct
Canvas course navigation tab.
CanvasSubmissionResponse ¶
Bases: Struct
Canvas submission API response.
CanvasProgress ¶
Bases: Struct
Canvas async operation progress tracker.
sync ¶
Canvas sync primitives — push grades and assignments to Canvas LMS.
Shared by both the CLI (cass gradebook push) and the NiceGUI viewer.
same_instant ¶
Compare two ISO timestamps by the moment they name, not their spelling.
Canvas returns UTC (...Z) while cass.toml may use a local offset.
Unparseable values fall back to plain string comparison.
values_equal ¶
Compare values loosely, handling datetime/string equivalence.
resolve_row_name ¶
Resolve a pending-change pk_key to a human-readable row name.
is_valid_grade ¶
Return True if grade is non-empty and not a placeholder.
build_grade_push_data ¶
Build {aid: {uid: grade}} from CanvasGrade list, filtering placeholders.
Returns:
| Type | Description |
|---|---|
tuple[dict[int, dict[int, str]], int]
|
Tuple of (grade_data_by_aid, skipped_count). |
get_post_manually_map ¶
Load {canvas_assignment_id: post_manually} from DB.
build_push_preview ¶
build_push_preview(
conn: Database,
grade_data_by_aid: dict[int, dict[int, str]],
grades: list[CanvasGrade],
) -> list[dict[str, object]]
Build a preview summary per assignment for push display.
Returns:
| Type | Description |
|---|---|
list[dict[str, object]]
|
List of dicts with |
push_grades ¶
push_grades(
client: CanvasClient,
conn: Database,
grade_data_by_aid: dict[int, dict[int, str]],
) -> list[dict[str, object]]
Bulk-push grades to Canvas, handling progress tracking and post_manually.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CanvasClient
|
Authenticated Canvas API client. |
required |
conn
|
Database
|
SQLite database connection (for post_manually lookup). |
required |
grade_data_by_aid
|
dict[int, dict[int, str]]
|
|
required |
Returns:
| Type | Description |
|---|---|
list[dict[str, object]]
|
List of result dicts with |
list[dict[str, object]]
|
and optionally |
resolve_group_ids ¶
Map assignment group names to IDs, case-insensitively.
Returns:
| Type | Description |
|---|---|
tuple[dict[str, int], list[str]]
|
|
push_assignments ¶
push_assignments(
client: CanvasClient,
updates_by_id: dict[int, dict[str, object]],
) -> list[dict[str, object]]
Push assignment field updates to Canvas.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CanvasClient
|
Authenticated Canvas API client. |
required |
updates_by_id
|
dict[int, dict[str, object]]
|
|
required |
Returns:
| Type | Description |
|---|---|
list[dict[str, object]]
|
List of result dicts with |
times ¶
Course-local time handling for Canvas timestamps.
Canvas stores instants in UTC. Users type times in the course's own zone.
parse_when turns a user string into an ISO 8601 instant with an offset;
format_when renders a Canvas instant in the course zone.
parse_when ¶
Parse a user-entered time into ISO 8601 with an offset.
Accepts YYYY-MM-DD, YYYY-MM-DD HH:MM, YYYY-MM-DDTHH:MM and
full ISO 8601. Naive values are localized to tz; a date alone means
midnight. Values that already carry an offset are returned unchanged.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the value cannot be parsed or tz is empty. |
format_when ¶
Render an ISO instant in tz as YYYY-MM-DD HH:MM (or the date).
same_instant ¶
Compare two ISO timestamps by the moment they name, not their spelling.
Canvas returns UTC (...Z) while cass.toml may use a local offset.
Unparseable values fall back to plain string comparison.