Skip to content

Instantly share code, notes, and snippets.

@cherryblossom000
Last active January 6, 2022 09:52
Show Gist options
  • Save cherryblossom000/83930808c498265782f44f9cea215351 to your computer and use it in GitHub Desktop.
Save cherryblossom000/83930808c498265782f44f9cea215351 to your computer and use it in GitHub Desktop.
Get grades from Canvas
#!/usr/bin/env bash
set -euo pipefail
# The GraphQL query could also be inlined instead of referencing the file, but
# I kept it in a separate file for syntax highlighting and stuff
xhs \
--check-status --ignore-stdin --timeout 2.5 \
example.instructure.com/api/graphql Authorization:"Bearer $CANVAS_TOKEN" query=@query.graphql \
| fx .data Object.entries '.forEach(([subject, {grades: {currentScore}}]) => console.log(`${subject}: ${currentScore === null ? "--" : `${String(currentScore).padEnd(5, "0")}%`}`))' 2> /dev/null \
| column -t
{
Subject1: node(id: "<enrollmentId1>") { ...grade }
Subject2: node(id: "<enrollmentId2>") { ...grade }
# ...
}
fragment grade on Node {
...on Enrollment {
grades { currentScore }
}
}
$ ./grades
English:  12.34%
Maths:    56.78%
Science:  90.12%
History:  --

See also the Elvish version.

Requirements

Tested on xh v0.10.0–v0.14.1 and fx v20.0.2.

Setup

1. Environment Variables

  • Get an API token
    • https://example.instructure.com/profile/settings → ‘Approved Integrations’ → ‘New Access Token’
export HOST=example.instructure.com # replace with actual host
export CANVAS_TOKEN='<your API access token>'

2. Enrollment Ids

Replace <courseId1>, <courseId2>, etc. with the ids of the courses that you want to get the grades of. The id of the course can be found by looking at the course’s URL: https://example.instructure.com/courses/courseId.

xhs $HOST/api/graphql Authorization:"Bearer $CANVAS_TOKEN" query="{
  legacyNode(_id: \"$(xhs $HOST/api/v1/users/self Authorization:"Bearer $CANVAS_TOKEN" | fx .id)\", type: User) {
    ...on User {
      Subject1: enrollments(courseId: \"<courseId1>\") { id }
      Subject2: enrollments(courseId: \"<courseId2>\") { id }
    }
  }
}" | fx .data.legacyNode

The result will be something like this:

{
  "Subject1": [
    {
      "id": "<enrollmentId1>"
    }
  ],
  "Subject2": [
    {
      "id": "<enrollmentId2>"
    }
  ]
}

Use these ids (<enrollmentId1>, <enrollmentId2>, etc.) in query.graphql.

Todo

  • Align 100%/<10% grades correctly
  • Automate getting enrollment IDs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment