Using the dashboard information via the API in programs

maguire
Community Champion
1
1385

In most of my programs that use the Canvas API, I take in the course_id from the command line in numeric form (i.e., the string: 11). One of my colleagues said that he does not like to remember the course numbers but would rather use the course code or a nickname. So this motivated me to see if one could use the dashboard information for this.

The first thing I discovered was that it seems the dashboard API is not documented - or perhaps I just could not find it. So I watched a Canvas session in the browser and found the API is:

GET /api/v1/dashboard/dashboard_cards

So I made a test program to get all of my cards and make a spreadsheet of them, see my-dashboard.py at GitHub - gqmaguirejr/Canvas-tools: Some tools for use with the Canvas LMS. 

After looking at the cards and their information it was really easy to see how to use this information to make it so that you can convert the "course_id" that is actually a nickname, short name, or original name (or a prefix or substring of it).

def course_id_from_assetString(card):
global Verbose_Flag

course_id=card['assetString']
if len(course_id) > 7:
if course_id.startswith('course_'):
course_id=course_id.replace('course_', "", 1)
if Verbose_Flag:
print("course_id_from_assetString:: course_id={}".format(course_id))
return course_id
else:
print("Error missing assetString for card {}".format(card))
return None

# check if the course_id is all digits, matches course code, or matches a short_name
def process_course_id_from_commandLine(course_id):
if not course_id.isdigit():
cards=list_dashboard_cards()
for c in cards:
# look to see if the string is a course_code
if course_id == c['courseCode']:
course_id=course_id_from_assetString(c)
break
# check for matched against shortName
if course_id == c['shortName']:
course_id=course_id_from_assetString(c)
break
# look for the string at start of the shortName
if c['shortName'].startswith(course_id) > 0:
course_id=course_id_from_assetString(c)
print("picked the course {} based on the starting match".format(c['shortName']))
break
# look for the substring in the shortName
if c['shortName'].find(course_id) > 0:
course_id=course_id_from_assetString(c)
print("picked the course {} based on partial match".format(c['shortName']))
break

# check for matched against originalName
if course_id == c['originalName']:
course_id=course_id_from_assetString(c)
break
# look for the string at start of the shortName
if c['originalName'].startswith(course_id) > 0:
course_id=course_id_from_assetString(c)
print("picked the course {} based on the starting match".format(c['shortName']))
break
# look for the substring in the shortName
if c['originalName'].find(course_id) > 0:
course_id=course_id_from_assetString(c)
print("picked the course {} based on partial match".format(c['shortName']))
break

print("processing course: {0} with course_id={1}".format(c['originalName'], course_id))
return course_id

Now, hopefully, there will be a happy user as in the main program to process the first argument of the command line as a course_id you simply say:

    course_id=process_course_id_from_commandLine(remainder[0])
if not course_id:
print("Unable to recognize a course_id, course code, or short name for a course in {}".format(remainder[0]))
return

Of course, there are probably some gotchas - but it should work better than having to look up the numeric values.

1 Comment