CLI Reference¶
This reference is generated from the course argument parser
(course_hoanganhduc/core.py plus Classroom50 flags from
course_hoanganhduc/c50_flags.py) and lists CLI flags grouped by section.
Agent-restricted entrypoints (python -m course_hoanganhduc.c50_agent,
canvas_agent, gclass_agent, db_agent) are documented under
Usage and are not the full interactive course surface.
Automation¶
--generate-weekly-workflow: Generate a sample GitHub Actions workflow for weekly automation--run-weekly-automation: Run weekly automation for a closed assignment--run-weekly-local: Run weekly automation locally and archive reports--weekly-assignment-id: Canvas assignment ID for weekly automation--weekly-category: Assignment group/category filter for missing-submission reminders--weekly-dest-dir: Output directory for weekly downloads--weekly-local-root: Local folder for weekly report archiving (default: cwd)--weekly-meaningful-threshold: Meaningfulness threshold for weekly automation--weekly-notify-missing: Send reminders for missing submissions after due date--weekly-ocr-lang: OCR language for weekly automation--weekly-ocr-service: OCR service for weekly automation--weekly-refine: AI refinement method for weekly notices--weekly-score: Score to assign to clean submissions (default: 10)--weekly-similarity-threshold: Similarity threshold for weekly automation--weekly-teacher-canvas-id: Canvas user ID for summary notifications--workflow-assignment-id: Assignment ID placeholder for workflow--workflow-course-code: Course code placeholder for workflow--workflow-course-id: Course ID placeholder for workflow--workflow-students-branch: Deprecated alias for –workflow-toolkit-branch--workflow-students-repo: Deprecated alias for –workflow-toolkit-repo--workflow-teacher-canvas-id: Teacher Canvas ID placeholder for workflow--workflow-toolkit-branch: Branch for course toolkit repo--workflow-toolkit-repo: Repo URL for course toolkit
Canvas: Admin Tools¶
--canvas-deadline-category(-cdc): Assignment category (group) to filter when changing deadlines--canvas-lock-category(-clc): Assignment category (group) to filter when changing lock dates--change-canvas-deadlines(-ccd): Change deadlines for one or more Canvas assignments (provide assignment IDs, or leave blank to select interactively)--change-canvas-lock-dates(-ccl): Change lock dates (lock_at) for one or more Canvas assignments (provide assignment IDs, or leave blank to select interactively)--create-canvas-groups: Create groups in a Canvas course group set--delete-empty-canvas-groups(-deg): Delete all empty groups (groups with no members) from a Canvas course group set--grade-resubmission(-grs): List resubmissions and regrade them (optionally provide assignment IDs)--group-name-pattern: Pattern for group names, e.g., ‘Group {i}’ (default: ‘Group {i}’)--group-set-id: Canvas group set ID to create groups in (leave blank to select interactively)--keep-old-grade: Keep previous grade for resubmissions without prompting--new-canvas-due-date(-ncd): New due date for Canvas assignments (format: YYYY-MM-DD HH:MM)--new-canvas-lock-date(-ncl): New lock date for Canvas assignments (format: YYYY-MM-DD HH:MM)--no-restricted(-nres): Disable restricted mode for grading Canvas assignments (list all assignments with submissions and all students who submitted)--num-groups: Number of groups to create (default: 5)
Canvas: People and Communication¶
--add-canvas-announcement(-aa): Create a new announcement in Canvas course--announcement-file: TXT file with announcement body--announcement-message: Short message for Canvas announcement--announcement-title: Title for Canvas announcement--canvas-assignment-category(-cac): Assignment category (group) to filter when listing Canvas assignments--canvas-course-id(-cc): Canvas course ID (overrides default)--canvas-unenroll-all: Unenroll all matched Canvas students without selection--canvas-unenroll-domain: Email domain(s) to match for Canvas unenroll (comma-separated)--canvas-unenroll-email: Email(s) to match for Canvas unenroll (comma-separated)--canvas-unenroll-missing-student-id: Unenroll Canvas students missing Student ID in local database--canvas-unenroll-select: Select Canvas students to unenroll from a list--comment-canvas-submission(-cs): Add a comment to a Canvas assignment submission--download-canvas-assignment(-da): Download all submission files for a Canvas assignment (optionally provide assignment ID)--download-dest-dir(-dd): Destination directory for downloaded Canvas assignment files--edit-canvas-pages(-ep): List and edit Canvas course pages--fetch-canvas-messages(-fm): Fetch and reply to Canvas inbox messages--grade-canvas-assignment(-ga): Grade Canvas assignment submissions interactively--invite: Invite students after –add-file import (skips those already enrolled)--invite-canvas-email(-ie): Invite a single user to Canvas course by email--invite-canvas-file(-if): Invite multiple users to Canvas course from a TXT file or string of pairs/emails--invite-canvas-name: Name for Canvas invite (for single user)--invite-canvas-role(-ir): Role for Canvas invite (student/teacher/ta, default: student)--invite-role: Role for –invite (student/teacher/ta, default: student).--invite-roteis accepted as an alias for the common typo--invite-section: Default Canvas section name for –invite (optional)--list-canvas-assignments: List all assignments on Canvas LMS--list-canvas-members(-cm): List all members (teachers, TAs, students) of a Canvas course--list-multiple-submissions-on-time(-lm): List students who submitted twice or more to an assignment and the first submission is on time (optionally provide assignment ID)--notify-incomplete-reviews(-nr): Find and notify students who have not completed required peer reviews for a Canvas assignment--review-assignment-id(-rai): Canvas assignment ID for peer review notification--search-canvas-user(-cu): Search for a user in Canvas by name or email--sync-canvas(-sc): Sync Canvas course members to local database--unenroll-canvas: Unenroll Canvas students by domain/email/select/missing-id
Canvas: Rubrics and Grading¶
--add-canvas-grading-scheme(-ags): Add a grading scheme to Canvas course from JSON file--check-student-submission-similarity(-css): Check similarities between submissions of the same student for different assignments. Optionally provide a Canvas student ID or a comma-separated list of IDs. If not provided, will prompt for selection interactively.--export-canvas-grading-scheme(-egs): List and export Canvas grading schemes (grading standards) to JSON--export-canvas-rubrics(-er): Export Canvas rubrics to TXT/CSV file--final-evals-announce(-fea): Also create a course announcement after sending final evaluations.--final-evals-course-id(-fec): Canvas course ID to use when sending final evaluations (overrides default CANVAS_LMS_COURSE_ID).--import-canvas-rubrics(-imr): Import rubrics from TXT/CSV file to Canvas course--list-canvas-rubrics(-lr): List all unique rubrics used in Canvas course--rubric-assignment-id(-rid): Assignment ID to filter rubrics--send-final-evaluations(-sfe): Send final evaluation results to students via Canvas. Optionally provide directory with evaluation files (default: final_evaluations).--update-canvas-rubric-id(-uri): Rubric ID to associate with assignments (leave blank to select interactively)--update-canvas-rubrics(-ur): Update rubric for one or more Canvas assignments (provide assignment IDs, or leave blank to select interactively)
Classroom50¶
Assignment administration (separate command)¶
Installing the package creates course-c50-admin
(course_hoanganhduc.c50_admin_cli:main), the dedicated Classroom50 operator CLI.
The equivalent source-tree invocation is
python -m course_hoanganhduc.c50_admin_cli. This mirrors the
course-gclass-admin boundary: the course flags listed below keep their read,
roster-sync, export, and human-download workflows, while every operation that changes
remote Classroom50 state lives on the separate command. The restricted
python -m course_hoanganhduc.c50_agent entrypoint continues to expose
preflight, list-*, allowlisted sync, read-only import-scores, and
export; it explicitly refuses
assignment-add, assignment-remove, invite, roster-import, and
roster-add. download is refused on the same entrypoint by its own guard.
Every subcommand refuses in agent mode, requires an interactive terminal unless
--dry-run is given, and builds one fixed gh teacher command line. There is no
free-form argument passthrough. “The pinned CLI” below means gh teacher v1.45.0
(commit a5a51293b65d), the version these argv builders were verified against; the
extension is pinned rather than tracking latest, and the constants that can drift on an
upgrade are listed under “Version coupling with gh teacher” in the README. The
subcommands are:
assignment-add --org ORG --classroom SHORT-NAME --slug SLUG --name NAMEregisters an assignment. Optional--description,--template,--mode {individual,group},--max-group-size N(required with--mode group),--available-from,--due,--empty-repo,--tests,--feedback-pr/--no-feedback-pr,--pass-threshold,--allowed-files(repeatable, order preserved), and--student-permission.--testsmust name a readable JSON file holding a bare array of test specs; the pinned CLI’s-stdin form is not offered, because no operand may begin with-.--empty-repois refused together with--template,--tests,--feedback-pr,--allowed-files, or--pass-threshold, matching the pinned CLI.--autograder,--runtime, and the schema’slockedfield have no flag here and stay with the reviewed raw command.gh teacher assignment addreplaces an existing entry in place and the pinned CLI cannot set submission mode, so re-running it restores the default every-push mode and discards a tagged-commit setting made in the web form. An existing slug is therefore refused; overriding needs both--allow-overwriteand an interactive confirmation.assignment-remove --org ORG --classroom SHORT-NAME --slug SLUGdeletes the entry fromassignments.json. It does not delete student repositories, and re-adding the same slug is not a clean reset; the confirmation states both. An absent slug is refused rather than silently succeeding.invite --target ORG[/REPO] --username LOGIN [--username LOGIN ...]sends invitations. Use--adminfor an organization owner invitation, or--permission {pull,triage,push,maintain,admin}for a repository invitation; the two are mutually exclusive and each is valid for only one target kind. Repository invitations are idempotent, organization invitations are not, so organization targets are preflighted againstgh teacher member listand logins that are already members or hold a pending invitation are skipped. That read needs theadmin:orgscope.roster-import --org ORG --classroom SHORT-NAME (--db PATH | --csv PATH)writes the roster.--dbrenders the CSV from the local database;--csvtakes a file, such as the output ofcourse --export-classroom50-roster.gh teacher roster importis an upsert: rows already on the roster are updated and rows absent from the CSV are left untouched, so a partial CSV is safe and rows that exist only on the remote roster are reported underremoteOnlyrather than removed. It also has a second effect the name does not suggest — once the commit lands, every listed student who is not already an organization member (and holds no pending invitation) is invited — and the confirmation states both. The remote roster is read first, but a matching roster does not by itself mean the work is done: the commit lands before the invitations go out, so a run that died in between leaves the roster matching and nobody invited. When nothing would change the command therefore reads the organization membership as well, and short-circuits withroster already matches the local database and every listed student is already in the organization; nothing to importonly if everyone is in. Otherwise the missing logins are reported undernotYetMembersand the import runs, which is what sends the invitations. A failed membership read (typically a token withoutadmin:org) still exits 0, setsmembershipNotVerified, and points at--force, which imports a matching roster without the check. Students with no GitHub username are listed underskippedNoUsernameand do not change the exit code, since skipping them is a deliberate non-write the operator saw before confirming. The generated CSV lives in atempfile.mkdtempdirectory that is removed even whenghfails, unless--keep-csvis given;--keep-csvtogether with--csvis refused as an invalid combination, because that path creates no temporary file.--csvfiles are read as strict UTF-8, so a Windows-1252 roster is refused here rather than transliterated.--dry-runmakes noghcall at all, so it reports aplaninstead of a roster diff, and the--dbform prints noargvbecause the CSV path does not exist yet.roster-add --org ORG --classroom SHORT-NAME --username LOGINupserts a single row, with optional--first-name,--last-name,--email, and--section. It has the same invitation side effect asroster-importand exists so that one late student does not require a full CSV round trip.download --org ORG --classroom SHORT-NAME --assignment SLUG --dest DIRcollects submissions.--by-patternskips the team lookup, so it fetches noresult.jsonand writes noscores.csv. It is permitted only after the assignment record reports empty-repository mode, and refused otherwise.
Exit codes are 0 success, 2 validation failure or refusal, 3 the gh call
failed and the remote outcome is unverified, and 4 a batch invite completed with
failures. roster-import uses 3 in earnest: the CLI commits the roster before it
sends invitations, so a non-zero gh exit really does leave the outcome unknown, and
its own advice to re-run is the recovery path, because the import is idempotent. Student acceptance and student submission are not provided: both run under a
student’s own credentials.
Toolkit flags¶
--classroom50-assignment: Classroom50 assignment slug (human download)--classroom50-classroom: Classroom50 classroom short-name--classroom50-download-dest: Destination directory for Classroom50 downloads--classroom50-group-assignment: Limit the group import to one assignment slug (default: every mode=group assignment)--classroom50-groups-report: Write the group-import JSON report to PATH--classroom50-org: Classroom50 GitHub organization--classroom50-preflight: Run Classroom50 auth preflight (whoami)--classroom50-read-team-json: Also read team.json from each group repository (one extra read per repository)--classroom50-report: Write Classroom50 JSON report to PATH--classroom50-scores-report: Write the score-import JSON report to PATH--download-classroom50: Download student submissions (human CLI only)--export-classroom50-roster: Export local roster to Classroom50 CSV (default: classroom50_roster.csv)--import-classroom50-groups: Read group membership of the mode=group assignments into the local database--import-classroom50-scores: Read the classroom’s collected scores into the local database--import-project-issues: Read the mini-project topic board’s issues into the local database--list-classroom50-assignments: List Classroom50 assignments--list-classroom50-classrooms: List Classroom50 classrooms--list-classroom50-roster: List Classroom50 roster--project-issues-read-proposal: Also read proposal/proposal.md at each proposal’s pinned commit (one extra read per group repository)--project-issues-repo: Topic board as OWNER/REPO (orCLASSROOM50_PROJECT_ISSUES_REPO)--project-issues-report: Write the issue-import JSON report to PATH--sync-classroom50(-sc50): Sync Classroom50 roster into local student database
The three --import-* flags above read; none of them writes anything back to
Classroom50, to a group repository, or to the topic board. Each one updates the local
database only, each writes its JSON report to the matching --*-report path, and each
honours --dry-run, which prints the same report and then stops before the save.
final-project has autograding switched off and an empty starter repository, so the
upstream collector skips it and the assignment never gets a bucket in the classroom’s
scores.json – not even an empty one. Asking for that slug is therefore not an error:
--import-classroom50-scores --classroom50-assignment final-project reports that the
assignment has no automatic grade, points at --load-override-grades, and exits 0.
Those marks are entered from the grader’s spreadsheet instead, which also carries the
free-text reason column.
scores.json is only as fresh as the last collection a teacher triggered by hand –
the Sync now button, or the collect-scores workflow run from the Actions tab.
Nothing collects on a schedule, so an import run today can legitimately return an empty
report. Every import therefore records the file’s own last-commit date, not the time the
import ran, in Classroom50 Scores Collected At; it is printed in the report and
exported with the rest of the student record. When that date falls before an assignment’s
deadline, a student with no submission in the snapshot is recorded as unknown (stale)
rather than not submitted, because a snapshot that old cannot tell the two apart;
before the assignment opened at all, the state is not collected yet.
Configuration¶
--backup-config: Back up config.json to a timestamped file (optional: backup dir)--clear-config(-ccfg): Delete stored config.json from the default location--clear-credentials(-ccred): Delete stored credentials.json and token.pickle from the default location--config(-cfg): Load config from JSON file and save to default location--config-backup-keep: Number of config backups to retain (default from config)--course-code(-ccode): Course code for config folder (e.g., MAT3500)--detect-local-ai: Detect locally installed AI models (Ollama-compatible)--list-ai-models(-lam): List available AI models for a provider (‘gemini’, ‘huggingface’, ‘local’, or ‘all’)--local-llm-args: Extra args for local LLM command--local-llm-command: Command to run the local LLM (default: ollama)--local-llm-gguf-dir: Directory to scan for .gguf models (llama.cpp)--local-llm-model: Local LLM model name (default from config/settings)--restore-config: Restore config.json from a backup (default: latest)--student-sort-method: Student sort method for detail outputs (first_last, last_first, id)--test-ai(-tai): Test AI services (‘gemini’, ‘huggingface’, ‘local’, or ‘all’)--test-ai-gemini-model: Override Gemini model name for –test-ai all--test-ai-huggingface-model: Override HuggingFace model name for –test-ai all--test-ai-model(-tam): Override model name for –test-ai (provider-specific)
Course Calendar¶
--build-course-calendar: Build course calendar and export to TXT/MD/ICS--calendar-course-code: Course code for calendar title--calendar-course-name: Course name for calendar summaries--calendar-extra-holidays: Comma-separated extra holiday dates (YYYY-MM-DD,YYYY-MM-DD)--calendar-extra-week: Allow one make-up week when holidays skip sessions--calendar-input: TXT file with first-week schedule and optional holidays--calendar-output-base: Output base name for calendar files (default: course_calendar)--calendar-output-dir: Output directory for calendar exports (default: cwd)--calendar-weeks: Number of official weeks (default: 15)--force: Force Canvas calendar import (do not skip duplicates)--import-canvas-calendar-ics: Import an iCal (.ics) file and create Canvas calendar events--skip-duplicates: Skip Canvas calendar events that match existing entries
Exams (Multichoice)¶
--evaluate-multichoice-answers: Evaluate student answers for multiple-choice exam (provide exam type: midterm/final, default: global EXAM_TYPE)--extract-multichoice-answers(-ema): Extract student answers from scanned multi-choice exam sheet PDF--extract-multichoice-solutions(-ems): Extract multiple-choice exam solutions from PDF (each page is one sheet code)--sync-multichoice-evaluations(-sme): Sync multichoice exam evaluations to Canvas assignment (provide exam type: midterm/final, default: global EXAM_TYPE)
General¶
--dry-run: Preview actions without writing files or databases--list-cli-aliases: List auto-generated short aliases for long-only CLI flags, then exit--log-backups: Number of rotated log files to keep--log-dir: Directory for log files (default: config folder)--log-level: Logging level (default: INFO)--log-max-bytes: Max size in bytes for rotating logs--refine: Refine generated messages/announcements with AI--verbose(-v): Enable verbose output--version: Show package name and version, then exit
Google Classroom¶
Assignment administration (separate command)¶
Installing the package creates two different console commands:
courseruns the general toolkit CLI (course_hoanganhduc.cli:main). It is not an alias for assignment administration.course-gclass-adminruns the dedicated assignment administration CLI (course_hoanganhduc.gclass_admin_cli:main). The equivalent source-tree or module invocation ispython -m course_hoanganhduc.gclass_admin_cli.
This is a capability boundary, not a wholesale Google Classroom CLI replacement.
course-gclass-admin owns assignment preview, isolated coursework OAuth, and
assignment creation only. The legacy course flags listed later in this section
continue to own their read, roster-sync, grading, submission-download, and unenroll
workflows. The restricted
python -m course_hoanganhduc.gclass_agent entrypoint continues to expose
preflight, list-courses, list-students, and allowlisted sync; it
explicitly refuses create, grade, download, and unenroll operations. Any future
migration is outside the current implementation; use the command ownership above as
the supported routing.
Use either form consistently in the commands below. The dedicated CLI exposes five subcommands:
auth-status --account EMAILinspects the isolated coursework credentials offline. It does not refresh a token, contact Google, or write files. Add--show-pathsto disclose resolved paths; otherwise output contains only safe names and fingerprints.--credentialsand--tokenoverride path resolution. Without those flags, resolution checksCOURSE_GCLASS_CREDENTIALSandCOURSE_GCLASS_COURSEWORK_TOKENbefore the platform-specific default config directory.authorize --account EMAILruns installed-app OAuth in an interactive terminal. There is no localAUTH ...phrase to type: Google browser consent and account verification are the authorization. Where a browser is registered it runs the loopback server and opens it there. Where none is, it starts no listener: it prints the consent URL to open elsewhere and finishes in the same terminal by taking back thehttp://127.0.0.1:8911/redirect that browser fails to load, at a hidden prompt.--no-open-browsertakes that path on a host that does have a browser.--replace-tokenis required before an existing isolated token can be replaced;--credentialsand--tokenselect explicit files.complete-loopback --port PORTdelivers a browser redirect to an authorization already listening on this host, which is the browser path started where that browser cannot reach the listener. It reads the URL from a hidden prompt, validates the exact loopback boundary, and delivers it without placing its code or state in shell history or process arguments. A host with no browser does not need it, sinceauthorizetakes the pasted redirect itself.prepare-agent-safe-draft --account EMAIL --course-id CANONICAL_ID --spec FILEvalidates a narrowly constrained draft in explicit agent mode. It requires an existing token, exact account and course allowlists, and a canonical course ID; it never opens a browser or starts fresh OAuth. It may refresh and persist an expired token or verification metadata, socredentialStateMayChangecan be true, butclassroomMutationis false. Its JSON approval envelope binds the account, OAuth client, token location, course, and operation. Preparation is neither Classroom mutation nor approval to mutate.create-assignment --course-id ID_OR_ALIAS --spec FILEvalidates and creates one assignment.--dry-runneeds neither--accountnor credentials. A live human run requires--accountand normally displays one readable summary followed byCreate assignment? [y/N]:; noCREATEorSHAREdigest phrase is required.--no-open-browsercontrols fresh interactive OAuth when no token exists.
-y / --yes skips the normal confirmation only when all of the following are
true: the assignment is a DRAFT, it has no Drive-sharing effects, and an isolated
coursework token already exists. This mode disables browser authorization. Published,
scheduled, and Drive-sharing plans still require the normal interactive confirmation.
General mutation remains forbidden in agent mode.
The separate --agent-safe-draft path permits only a minimal all-students draft
with a title and optional description; attachments, due or scheduled times, points,
topics, grading periods, individual targeting, and rubrics are rejected. It requires
COURSE_AGENT_MODE=1, exact GCLASS_ACCOUNT_ALLOWLIST and
GCLASS_COURSE_ALLOWLIST values, a canonical course ID, an existing token,
--yes, and the full --expect-approval-digest emitted by a separately reviewed
preparation. It does not open a browser. An identical developer-associated draft can
be reused after strict read-back; conflicting same-title work is rejected.
Every Classroom mutation request uses the one-shot transport: response-triggered
OAuth replay, HTTP retries, and redirects are disabled. An ambiguous mutation returns
error: outcome_unknown with exit status 3; inspect Classroom before deciding
whether to run anything again. A known partial result returns error: partial_create
with exit status 4 and available receipt fields. A failed mutation is not replayed or
deleted automatically. No automatic rerun is attempted after an ambiguous initial
create; inspect Classroom manually before deciding what to do next.
Examples (all identities and IDs are placeholders):
course-gclass-admin auth-status \
--account ACCOUNT_EMAIL
python -m course_hoanganhduc.gclass_admin_cli authorize \
--account ACCOUNT_EMAIL \
--no-open-browser
course-gclass-admin create-assignment \
--course-id COURSE_ID_OR_ALIAS \
--spec sample/google_classroom/assignment-minimal.sample.json \
--dry-run
course-gclass-admin create-assignment \
--account ACCOUNT_EMAIL \
--course-id COURSE_ID_OR_ALIAS \
--spec sample/google_classroom/assignment-minimal.sample.json \
--yes
For the agent-safe path, first run preparation and separately review its JSON
envelope. Then pass its full approvalDigest to the live command:
COURSE_AGENT_MODE=1 \
GCLASS_ACCOUNT_ALLOWLIST=ACCOUNT_EMAIL \
GCLASS_COURSE_ALLOWLIST=CANONICAL_COURSE_ID \
course-gclass-admin prepare-agent-safe-draft \
--account ACCOUNT_EMAIL \
--course-id CANONICAL_COURSE_ID \
--spec sample/google_classroom/assignment-test-draft.sample.json
COURSE_AGENT_MODE=1 \
GCLASS_ACCOUNT_ALLOWLIST=ACCOUNT_EMAIL \
GCLASS_COURSE_ALLOWLIST=CANONICAL_COURSE_ID \
course-gclass-admin create-assignment \
--account ACCOUNT_EMAIL \
--course-id CANONICAL_COURSE_ID \
--spec sample/google_classroom/assignment-test-draft.sample.json \
--agent-safe-draft \
--yes \
--expect-approval-digest APPROVAL_DIGEST
The existing flags below still use the legacy Google credential/token flow. They do not create assignments.
--download-google-classroom-submissions(-dgcs): Download latest Google Classroom submissions and run checks--gc-apply-all: Apply grading to all listed submissions without selection--gc-coursework-id: Google Classroom coursework ID(s) to grade (optional)--gc-download-coursework-id: Google Classroom coursework ID(s) to download (optional)--gc-download-dest-dir: Download folder for Google Classroom submissions (optional)--gc-grade-score: Score to assign to selected submissions (optional)--gc-include-graded: Include already graded submissions--gc-invite-all: Invite all matched students without selection--gc-invite-class: Class to match for Google Classroom invite--gc-invite-domain: Email domain(s) to match for Google Classroom invite (comma-separated)--gc-invite-email: Email(s) from the local database to invite (comma-separated)--gc-invite-role: Role to invite matched people as,STUDENTorTEACHER(default:STUDENT)--gc-invite-section: Section to match for Google Classroom invite--gc-meaningful-threshold: Meaningfulness threshold for Google Classroom checks--gc-ocr-lang: OCR language for Google Classroom checks--gc-ocr-service: OCR service for Google Classroom checks (ocrspace/tesseract/paddleocr)--gc-similarity-threshold: Similarity threshold for Google Classroom checks--gc-unenroll-all: Unenroll all matched Google Classroom students without selection--gc-unenroll-domain: Email domain(s) to match for Google Classroom unenroll (comma-separated)--gc-unenroll-email: Email(s) to match for Google Classroom unenroll (comma-separated)--gc-unenroll-missing-student-id: Unenroll Google Classroom students missing Student ID in local database--gc-unenroll-select: Select Google Classroom students to unenroll from a list--google-course-id(-gci): Google Classroom course ID (prompts if None)--google-credentials-path(-gcp): Path to Google Classroom credentials JSON file--google-token-path(-gtp): Path to Google Classroom token pickle file--grade-google-classroom(-ggc): Grade Google Classroom assignment submissions--invite-google-classroom(-igc): Invite local database students to a Google Classroom course (skips anyone already enrolled or invited)--list-google-courses(-lgc): List Google Classroom courses for the current account--list-google-students: List Google Classroom students for a course (uses –google-course-id or prompts)--sync-google-classroom(-sgc): Sync students in the local database with active students from Google Classroom course--unenroll-google-classroom(-ugc): Unenroll Google Classroom students by email domain
OCR and PDFs¶
--add-blackboard-counts(-b): Extract and add blackboard counts from PDF to database--export-blackboard-counts(-B): Export blackboard counts by date for all students to TXT/Markdown file (use .txt or .md extension, default: TXT)--extract-text(-t): Extract handwriting text from PDF and save to TXT file--ocr-lang(-L): OCR language for PDF extraction (default: auto)--ocr-service(-O): OCR service to use for PDF extraction (default: ‘ocrspace’). The ‘ocrspace’ service uses the OCR.space API and works better for handwriting text. The other two services work better for printed text and require additional local installation.--print-blackboard-counts(-p): Print blackboard counts by date for all students--simple-text(-T): Extract simple text (no layout) from PDF OCR
Student Database¶
--add-csv: Import students from a roster CSV with fixed columns into the database.Student IDandNameare required, as is at least one ofEmailandGitHub Username;GitHub ID,SectionandClassare read when present and other columns are ignored. Header names are matched case- and accent-insensitively, and a header matching nothing is refused with the columns that were read. The file is decoded as UTF-8 (BOM or not), then Windows-1252, then Latin-1, naming the encoding whenever it falls back. Unlike--add-filethe columns are not auto-detected, and--dry-runpreviews without writing--add-file(-a): Import students from Excel, CSV, or PDF file into the database--add-google-sheet(-gsh): Import students from Google Sheet URL (optional: URL, default from config).--dry-runreads and merges the sheet exactly as a real import would, prints every field a newer submission would replace, and writes nothing--all-details(-A): Show details of all students--backup-db: Back up students.db to a timestamped file (optional: backup dir)--db(-db): Database file name (default: students.db, saved in script folder)--db-backup-keep: Number of database backups to retain (default from config)--details(-d): Show details of a student by name, student id, or email--dry-run-rows: Number of preview rows to show with –dry-run + –add-file (default: 5)--duplicate-name-field: Field to detect duplicates (name/google/canvas or custom field name)--duplicate-name-format: Output format for duplicate-name report (default: txt)--duplicate-name-output: Output path for duplicate-name report (optional; extension inferred from format if missing)--export-all-details(-E): Export all student or company details (including submission attachments) to TXT file--export-anonymized(-ean): Export anonymized roster to CSV (optional: output path)--export-companies: Export company list to Excel file--export-emails(-e): Export all student emails to TXT file (avoids duplicates)--export-emails-and-names(-en): Export all student emails and names to TXT file (default: emails_and_names.txt)--export-excel(-x): Export student list to Excel file--export-final-grade-distribution: Export final grade distribution to a TXT file. Optionally provide output path (default: ./final_grade_distribution.txt).--export-grade-diff: Export grade updates to CSV when updating MAT files (optional: output path)--export-roster(-ero): Export classroom roster to CSV file (default: classroom_roster.csv)--export-type(-et): Entity type to export with –export-all-details (student/company, default: student)--export-vcf(-vcf): Export student contact info to VCF (iOS compatible). Default: students_contacts.vcf--filter-file(-ff): Filter export by identifiers in this file (TXT/CSV/XLSX)--generate-final-evaluations(-gfe): Generate per-student final evaluation TXT reports (optional: output dir, default: ./final_evaluations).--import-companies: Import company data from Excel/CSV to companies.db--import-internships: Import student internship data from Google Sheet URL or local CSV/Excel file (optional: URL/Path, default from config)--import-mini-projects: Import mini-project data from Google Sheets (lecturer topics + student registrations)--import-progress-reports: Import student progress reports from their linked Google Sheets--import-registrations: Import student registration data from Google Sheet URL or local CSV/Excel file (optional: URL/Path, default from config)--list-duplicate-names: List students who share the same full name--list-email-domain(-led): List students whose email matches domain(s) (comma-separated, e.g., gmail.com,outlook.com)--list-missing-ids: List students missing Google/Canvas/Student IDs (optional: google,canvas,student,all or comma-separated)--list-submission-status: List students by submission status (shows attachment details; prefix with google: or canvas:, optional @assignment title)--load(-l): Load students from database file--load-override-grades(-log): Load override_grades.xlsx and persist overrides to the database (default: override_grades.xlsx).--mini-project-lecturer-sheet: Google Sheet URL for lecturer mini-project topics (optional; default from config)--mini-project-registration-sheet: Google Sheet URL for student mini-project registrations (optional; default from config)--missing-ids-format: Output format for missing-ids report (default: txt)--missing-ids-output: Output path for missing-ids report (optional; extension inferred from format if missing)--modify(-m): Interactively modify the student database--onboard: Interactive onboarding from a registration CSV to both platforms: pick a Google Classroom course and/or a Classroom50 classroom, pick the CSV, validate it, and add whoever is missing. Either platform can be skipped, and skipping both loads the CSV into the database and reports what it contains. Uses--google-course-id,--classroom50-org,--classroom50-classroom, and--classroom50-reportwhen given, so nothing is prompted twice. Google Form headers are matched, addresses and GitHub usernames are validated per student, and bad rows are skipped with a reason rather than failing the run. Everything is read and shown as a comparison table before the one confirmation;--dry-runcalls neither platform--onboard-csv: Registration CSV for--onboard, skipping the file prompt--onboard-skip-github-check: For--onboard: validate GitHub usernames by syntax only, without calling the API (offline)--no-open-browser: For--onboard: never open a browser for Google authorization; print the URL to open elsewhere and finish it in the same terminal by pasting back thehttp://127.0.0.1:8910/redirect the browser fails to load. A machine with no browser registered already takes this path on its own--restore-db: Restore students.db from a backup (default: latest)--save(-s): Save current students to database file--search(-S): Search for students by keyword (name, student id, email, etc.)--sheet-name(-sn): Specific sheet name to import from Excel file--sheet-selection(-ss): Sheet selection mode: first (default), select (interactive), all, merge--sync-mat-canvas: Sync CC/GK/CK scores from MAT*.xlsx to Canvas assignments (uses configured assignment IDs)--sync-mat-types: Comma-separated list of score types to sync (CC,GK,CK). Default: all available.--update-mat-excel(-ume): Update MAT*.xlsx file(s) with grades from database (provide one or more file paths)--validate-data: Validate student data and write a report (optional: output path)