Skip to main content

BbRest

Blackboard REST APIs... for humans? (TM)

Purpose

This Python library was created to make the Blackboard REST API more accessible. Specifically, it helps solve a few problems:

Token Management

Blackboard tokens expire in one hour, and cannot be expired manually.
It's possible that two uses of one app would be called within an hour of starting the other - in this case, the session expires in less than an hour. A call with an expired token returns a 401 error.

This wrapper has a self healing session that renews the token when needed.

API availability by version

All APIs documented on developer.blackboard.com are not available for all versions of self and managed hosted clients. The terminology is even a bit hard to decipher, as it doesn't match the QX 20XX format most admins are used to.

This wrapper will create functions that only allows calling available functions, depending on the version of Blackboard it connects to. This has recently been improved by the distinct versions for .json.

Finding APIs

It can be difficult to find the correct API on developers.blackboard.com, and this wrapper allows you to tab complete generated APIs and to get hints about expected inputs.

Convenience APIs

This wrapper also has some convenience APIs that make getting information easier. This is also a work in progress, and probably will be built out separately.

Installation

Install poetry and bbrest

$ poetry init
$ poetry add bbrest

This will create a virtual environment with python 3 and the dependencies of this project

#Install and run JupyterLab

$ poetry add --dev jupyterlab
$ poetry run jupyter lab

Usage

Setup

The key and secret are from your registration on developer.blackboard.com. The url is the base url for your campus ie: https://blackboard.school.edu

from bbrest import BbRest
bb = BbRest(key, secret, url)

Session Management

bb.expiration()

'6 minutes ago'

r = bb.GetUser(userId='test_user')
r.status_code

200

The call method checks if the session is expired, and renews the token if so. Other methods around token management:

r = bb.is_expired() #returns boolean
r = bb.refresh_token() #manually refreshes the token

Note, refresh_token will receive the same token from Blackboard if the token is not yet expired, even if there's only seconds left.

REST call discovery / usage with Tab completion

Find all endpoints available in the current version that have 'GetUs' in the name.

r = bb.GetUs<Tab>
  • bb.GetUser
  • bb.GetUserGrades
  • bb.GetUserMemberships
  • bb.GetUsers

Find the parameters of 'GetColumnGrade'

r = bb.GetColumnGrade(<Shift-Tab>)
  • columnId=
  • courseId=
  • userId=

All available endpoints can be accessed this way. Params should be entered as params={'key':'value'} Payload should be entered as payload={'key1':'value1','key2':'value2', etc}

Calling API endpoints

#Some convenience tricks for common calls
r = bb.GetCourse(courseId='2832102')

#same as above
r = bb.call('GetCourse',courseId='courseId:2832102')
r.json()

r = bb.UpdateCourseMembership(courseId='2832102',
                              userId='test_user',
                              payload={'availability':{'available':'No'}})

#same as above
r = bb.call('UpdateCourseMembership',courseId='courseId:2832102',userId='userName:test_user',payload={'availability':{'available':'No'}})
r.json()

Asynchronous calls!

One of the big advantages of javascript over python was the idea of promises and asynchronous information gathering. Python now has await and async capabilities, but using it can be tricky.

I've tried to make using it with BbRest to be as easy as possible.

user_info = await bb.GetUser('test_user', sync=False)

NOTE: Based on how this is setup - you get back a dict object on success or failure. The failure has a status, but the success only has the info. This is slightly different than how it works synchronously, and has the potential to cause logic errors in the code.

Here's an example of multiple calls:

#Assume users is a list of userNames
tasks = []
for user in users:
  tasks.append(bb.GetUser(user), sync=False)
resps = await asynchio.gather(*tasks)

Since these calls are asynchronous, it's MUCH faster than synchronously going through all users.

Working on

[x] Matching up the responses of Async and Sync functions (This is in place as of 3.7) [ ] Better exception handling, and a way to view failure history. [x] Calls will always be authenticated, if the session is expired, it will renew the session.

Metadata

Release files for bbrest 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bbrest 0.5.0
File Size Uploaded Provenance Actions
bbrest-0.5.0.tar.gz 18.7 kB Without provenance Details for bbrest-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bbrest 0.5.0
File Interpreter ABI Platform Actions
bbrest-0.5.0-py3-none-any.whl Python 3 none any Details for bbrest-0.5.0-py3-none-any.whl

Total release size: 35.2 kB

Release files / bbrest-0.5.0.tar.gz

Download URL bbrest-0.5.0.tar.gz
Size 18.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9b54856a7f827c6632abfb1f32bcd13344583aff4dae106c8839817a18d5ea27
BLAKE2b-256 checksum
How to use checksums
0b01b3072509c02e04e1567bc7b2fdd17f0b0863f6054a6d3720015836188703
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.11 CPython/3.9.7 Darwin/20.6.0

Release files / bbrest-0.5.0-py3-none-any.whl

Download URL bbrest-0.5.0-py3-none-any.whl
Size 16.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7b2d0e764f48e11f204272d584528e93730011fbb6323dfbe4f6cc064fe111bb
BLAKE2b-256 checksum
How to use checksums
5bb5b97654437b6b47d445d01b9eca8372be23d5b6e4f08598bcffc620ba5a6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.11 CPython/3.9.7 Darwin/20.6.0

Security for bbrest 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page