Architecture

Staffeli has a layered architecture, staring with a low-level API wrapper, wrapped in an object model.

Low-level API Wrapper

The Canvas object, defined in canvas.py, implements a number of low-level wrappers for the Canvas LMS REST API. It makes few abstractions, and is mainly a functional reflection of the REST API.

Object Model

There are two fundamental classes:

1. A ListedEntity has a name, or id, and occurs in some listing on canvas. For instance, both courses and assignments are “listed entities”.

2. A CachableEntity may be “cached” on disk, to avoid excessive REST API requests, which can otherwise be a drag.

Python allows multiple inheritance, so some objects are both an instance of ListedEntity and CachableEntity. For instance, both Course and Assignment inherit from the two.

NB! ListedEntity and CachableEntity have conflicting constructors. One will reach for the containing list on Canvas, while the other will reach for the disk. The choice between these is made at runtime. The former is chosen if any identifying information is given. For instance, if the user is cloning a given course, or fetching a given assignment, then we reach for Canvas regardless of what may be on disk.

Listed Entities

Todo

Coming soon.

Cachable Entities

Cachable entities are cached on disk. They are stored in a dedicated directory, in a YAML file called .staffeli.yml. (Note the leading .: The file remains hidden to many Unix-style utilities. You might find this useful.)

Cachable entities have a cachename. This identifies a cache entry (some .staffeli.yml file) as belonging to this particular cachable entity. This is used to distinguish different cachable entities (e.g., course and assignment).

Cachable entities can be initialized with a path, which is optionally walked up to find a matching cache entry:

  • If initialized with a path to a cache entry, or its containing directory, the file is loaded without further a due (failing if the cachename does not match).

  • If allowed to walk, staffeli walks up in the filesystem hierarchy, until a matching cache entry is found, if any. staffeli eventually gives up at /, if not earlier.

    This walk is useful if you would like to find some containing cache entry while deep inside the file system hierarchy (e.g., find the course while marking a submission).

  • By default, the path is set to . i.e., the current working directory.

Cachable entities which have no backing cache entry yet, should simply not call the constructor.