Well, it's not the prettiest way to do it, but while I see in the API where we can sort the returned course list with a couple of parameters passed on the request, it looks like you can only sort on a few fields, none of which are the date or the ID. If someone has more info and shows you can say sort descending in a way that uses the ID, I'd be interested to hear it as well.
In the mean time, here's a Python script that just pulls them all into a hashed array, and sorts the array based on the key, which is the course ID.
#!/usr/bin/python3
###################################################################################
# listcourses.py
# A sample Python script that lists the courses in our Canvas install.
# ajh 2018-08-15
# For this to work you'll need the requests module installed, which isn't part
# of Python Core. Also, this is written and tested in Python3, I haven't tried
# to see if it works in Python2 and honestly don't much care to.
###################################################################################
# Pull in the module with tools like exit(). (Why is this not in by default?)
import sys
# Pull in the modules that allow the RESTful API access (https), and JSON parsing.
import requests
import json
# Create and initialize a dictionary (hashed array) to hold the courses for sorting
global courselist
courselist = {}
# The token here is the key to accessing things in our Canvas install. It's a per-user token
# so you'll want to have an admin generate it to get the required access. To generate one
# you go to Account, Settings, and under Approved Integrations, get a new access token.
# !!Note!! When you generate the token, copy and paste it somewhere!! You will never see that
# token again, and if you lose it, you'll have to delete it and generate a new one because you
# cannot get the actual token value shown to you ever again.
token = '(fill in you token here)'
# We'll need to pass the token to Canvas using a custom header on the https request, with
# a name of Authorization and a value of the word Bearer, a space, and the token you generated.
headers = {'Authorization': 'Bearer ' + token}
# This is the URL for the API call we want. You can get the whole list of these, with descriptions
# of the JSON object returned and any parameters you can pass in (also via JSON usually), by logging
# into Canvas and then going to https://(your.canvas.url)/doc/api/live (there is no link to this
# inside Canvas so you'll have to go directly to that URL).
# Note that we can't just call api/v1/courses, as that only gives the courses for the user whose
# token we're using. We have to specify accounts plus the main account id (always 1) plus "courses"
# to get all the courses. If you only want the courses in one of the sub accounts, specify that
# account's id instead of the main account id.
courseurl = 'https://(your.canvas.url)/api/v1/accounts/1/courses'
# Now the meat of the process. We're going to loop here to get each of the 10-record pages
# the Canvas API will give us in response to our request.
keepgoing = True
while keepgoing:
# Make the call to the API URL and pass in our custom header.
r = requests.get(courseurl, headers=headers)
# Make sure the call worked, and if not, we want to throw an error.
if r.status_code != 200:
print("ERROR: Status code returned={} for {} -- Exiting.\n".format(r.status_code, courseurl))
sys.exit()
# Since there are a lot of these, we'll need to paginate. That means getting the link
# header to the next page out of the LINK header. If there isn't one, then this is the
# last page.
linkheader = r.headers['Link']
# The header has an array of links, separated by commas...
linklist = linkheader.split(",")
# Loop through. We're looking for the "next" link, if there is one...
nexturl = None
for linkitem in linklist:
# Each link item is really two things, the actual URL, and a rel= that tells us what the link is to...
onelink = linkitem.split(";")
# If we have a next...
# Otherwise, if no next, empty nexturl so we'll know.
if "next" in onelink[1]:
# Get it, strip the first character (a "<") and the last letter (a ">").
nexturl = onelink[0]
nexturl = nexturl[1:]
nexturl = nexturl[:-1]
# End of for loop
# Now we pull the text of the response we got back, run that through the JSON decoder, and
# stuff the whole data structure into a variable.
data = json.loads(r.text)
# The response will have an array of records each of which is a hash array with a bunch of items.
# For this example, we'll cycle through the array, and for each one, get the idnumber and the course name
# and stick them in a dictionary (a Python hashed array)
for course in data:
courselist[course['id']] = course['name']
# Now, if the nexturl is blank, set the keepgoing flag to false so we'll drop out of the loop.
# Otherwise, set url to nexturl and we'll get the next page worth.
if nexturl:
url = nexturl
else:
keepgoing = False
# End of while loop
# Ok, we've got them all now. Sort them in descending order by the key and print them out.
for crsid in sorted(courselist, reverse=True):
print("{} - {}".format(crsid, courselist[crsid]))
# End of sample script.