npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

canvas-api-wrapper

v3.3.5

Published

Simplifies the already simple canvas api calls, and handles pagenation

Downloads

57

Readme

Super simple to use

This module wraps the Canvas Api handling pagination and throttling. Giving easy access to the main CRUD operations, and making the other more specific calls easier as well.

// Example: Publish all Modules
const canvas = require('canvas-api-wrapper')
canvas.subdomain = 'example' // default:byui

// Gets the course shell (doesn't send any requests)
const course = canvas.getCourse(19284)

// Gets the data for all modules for this course
await course.modules.get()

// modules inherits from Array, so Array methods work
course.modules.forEach(module => {
	module.published = true
})

// Updates everything in the course that has been changed
await course.update()

Table of contents

Get Started

Install

npm i --save canvas-api-wrapper

Setup

var canvas = require('canvas-api-wrapper')
//  https://<subdomain>.instructure.com (default: byui)
canvas.subdomain = '<subdomain>' 

Authorization:

canvas.apiToken = "<TOKEN>"
# Powershell
$env:CANVAS_API_TOKEN="<TOKEN>"

# CMD
set CANVAS_API_TOKEN=<TOKEN>

# Linux & Mac
export CANVAS_API_TOKEN="<TOKEN>"

Settings

This library handles all of the throttling, so that you won't go over your rate limit. But you may want to tweek the settings to speed it up or slow it down

// the subdomain to be used in the default baseUrl
//  https://<subdomain>.instructure.com
canvas.subdomain = 'byui';

// The baseUrl to be used. Useful to overwrite when running
// a dev/local version of the canvas-lms. 
// 
//   canvas.baseUrl = https://localhost:8080
//
// The default will use the 
// subdomain setting as the subdomain, this functionality
// is not avaliable if over written
canvas.baseUrl = 'https://<subdomain>.instructure.com'

// Canvas uses a rate-limit point system to handle spamming. Canvas
// currently fills your account to 700 'points' though subject to change
// then subtracts from your 'points' every time you make a call. If 
// you go below 0 then canvas will start sending you 403 (unauthorized) 
// statuses. So when your account goes under the 'rateLimitBuffer'
// this module will halt the requests until it gets filled back to 
// the 'rateLimitBuffer'. Give it a pretty large buffer, it tends to 
// go quite a ways past the buffer before this module catches it.
canvas.rateLimitBuffer = 300;

// How many to send synchronously at the same time, the higher this
// number, the more it will go over your rateLimitBuffer
canvas.callLimit = 30;

// How much the calls are staggered (milliseconds) especially at the
// beginning so that it doesn't send the callLimit all at the same time
canvas.minSendInterval = 10;

// After it goes under the rateLimitBuffer, how often (in milliseconds) 
// to check what the buffer is at now, this should be pretty high because
// there will be a lot of threads checking at the same time.
canvas.checkStatusInterval = 2000;

Debugging

This library ambiguates which calls it's making quite a bit, especially with the wrapped calls. So to make sure it's not making excess calls. Or to just making sure it's doing what it should be you can assign canvas.oncall a function as an event handler.

canvas.oncall = function(e){
	console.log(e)
}
await canvas.getCourse(11310).pages.create({
	title:'Hello World',
	body:'<h1>Hello World</h1>',
	published: true
})
/*
{ method: 'POST',
  url: 'https://byui.instructure.com/api/v1/courses/11310/pages/',
  body:
   { wiki_page:
      { title: 'Hello World',
        body: '<h1>Hello World</h1>',
	published: true } } }
*/

Standard Calls

Use awaits or the optional callback

var modules = await canvas('/api/v1/courses/10698/modules')

/* ----------- OR -------------- */

canvas('/api/v1/courses/10698/modules', function(err,modules){
	if(err) {
		console.error(err);
		return 
	}
	console.log(modules)
})

If a post, put, or delete request the second argument is the request body

await canvas.post('/api/v1/courses/10698/modules',{
	module:{
		name:"New Module"
	}
})

If a get request, the second argument is the query object

var queriedModules = await canvas('/api/v1/courses/10698/modules',{
		search_term:'New Module'
})

Signatures

canvas(url[,query object][,callback]) // uses a GET request

canvas.get(url[,query object][,callback])

canvas.post(url[,body][,callback])

canvas.put(url[,body][,callback])

canvas.delete(url[,body][,callback])

canvas.getCourse(id)

Wrapped Calls

The CRUD operations for files, folders, assignments, discussions, modules, pages, and quizzes are wrapped for convenience. The can be accessed through the Course Class which is created through canvas.getCourse(id)

Course extends Item

var course = canvas.getCourse(17829)

// this will get the course object and attach the properties to the course
await course.get()
// allowing you to do 
course.getTitle()
course.is_public = true
await course.update()

// using getComplete, will retrieve every single item and 
// their sub items in the course. This is not recommended (of course) but 
// can be helpful in certain situations where you need every item
await course.getComplete()
course.quizzes[0].questions[0].getTitle()
course.modules[0].moduleItems[0].getTitle()
course.assignments[0].getTitle()

// Update searches through all of the children for changes, and updates
// only those with changes. So just doing course.update() will push all
// changes made anywhere in the course.
await course.update()

Items extends Array

The abstract class which all of the lists of items inherit from

  • async update( [callback] )
    • Updates all of the items that have had changes made to them or their children
const course = canvas.getCourse(19823)
await course.assignments.get()
course.assignments.forEach(assignment => {
	if(assignment.getTitle() == 'potato'){
		assignment.setTitle('Baked Potato')
		assignment.published = true
	}
})
// Only updates items named potato, because those were the only ones changed
await course.assignments.update()
  • async create( data, [callback] ) <Item>
    • Creates the item in canvas, with the given data. And adds it to the items property
    • data <Object> the properties to add to the created item
const course = canvas.getCourse(19823)
const page = await course.pages.create({
	title:'Hello World',
	body:'<h1>Hello World</h1>',
	published: true
})
console.log(page.getId())
  • async get( [callback] ) <[Item]>
    • Retrieves all of the children items from canvas
const course = canvas.getCourse(19823)
// you don't have to save it to a variable, 
// you can also just access the array through `course.modules`
// this just saves you from writing `course` everywhere
const modules = await course.modules.get()
console.log(modules)
  • async getComplete( [callback] ) <[Item]>
    • Retrieves all of the children items from canvas and all of their sub items such as the questions in a quiz or the body in a page
const course = canvas.getCourse(19823)
const modules = await course.modules.getComplete()
// normally you would have to call `get()` on each of the
// modules ( modules[0].get() ) in order to get the moduleItems
console.log(modules[0].moduleItems)
  • async getOne( id, [callback] ) <Item>
    • Retrieves a single item from canvas by id
    • id <number> the id of the item to grab
const course = canvas.getCourse(19823)
const folder = course.folders.getOne(114166)
console.log(folder)
  • async getOneComplete( id, [callback] ) <Item>
    • Retrieves a single item from canvas by id including all of it's sub items such as the questions in a quiz ( the body in page is already included because your only getting a single item )
    • id <number> the id of the item to grab
const course = canvas.getCourse(19823)
const quiz = course.quizzes.getOneComplete(114166)
console.log(quiz.questions[0])
  • async delete( id , [callback] )
    • Removes an item from canvas, and from the local list
    • id <number> the id of the item to delete
const course = canvas.getCourse(19823)
await course.quizzes.get()
const questions = await course.quizzes[0].questions.get()
await questions.delete(questions[0].getId())

Item

The abstract class for the items to inherit from

  • getId() <number>
  • getTitle() <string>
  • setTitle( title )
  • getHtml() <string>
  • setHtml( html )
  • getUrl() <string>
  • getSubs() <[Items]> - Array of children Items
  • async get( [callback] ) <Item>
    • Retrieves the item from canvas
  • async getComplete( [callback] ) <Item>
    • Retrieves the item from canvas including the sub items such as the questions in a quiz ( the body in page is already included because your only getting a single item )
  • async update( [callback] )
    • Only updates if properties have been changed on the Item since it was last gotten, also updates all of it's sub children who have been changed
  • async delete( [callback] )
    • Will delete item, and remove it from it's parent list

Assignments extends Items

Assignment extends Item

Discussions extends Items

Discussion extends Item

Files extends Items

  • Doesn't have a create method

File extends Item

Folders extends Items

Folders extends Item

Modules extends Items

Module extends Item

  • moduleItems <ModuleItems>

ModuleItems extends Items

ModuleItem extends Item

Pages extends Items

Page extends Item

Quizzes extends Items

Quiz extends Item

  • questions <QuizQuestions>

QuizQuestions extends Items

QuizQuestion extends Item

Item Gets and Sets

| Type | getId | getTitle/setTitle | getHtml/setHtml | getUrl | getSubs | |------------|-------|------|-----|------|---| | Course | id | name | | /courses/<course> | [ files<Files>, folders<Folders>, assignments<Assignments>, discussions<Discussions>, modules<Modules>, pages<Pages>, quizzes<Quizzes> ] | | Assignment | id | name | description | html_url | | | Discussion | id | title | message | html_url | | | File | id | display_name | | /files/?preview=<id> | | | Folder | id | name | | folders_url | | | Module | id | name | | /modules#context_module_<id> | [ moduleItems<ModuleItems> ] | | ModuleItem | id | title | | html_url | | | Page | page_id | title | body | html_url | | | Quizzes | id | title | description | html_url | [ questions<QuizQuestions> ] | | QuizQuestion | id | question_name | question_text | /quizzes/<quiz>/edit#question_<id> | |