We found that Canvas sometimes doesn't provide the "last" element in its responses, leading to dispatch's canvas request loop breaking. An example of the fixed code follows. We should eventually replace the general loop in rudaux with a similarly generalized version of the below.
def get_enrollment_dates(course):
'''Takes a course object and returns student dates of enrollment.
Useful for handling late registrations and modified deadlines.
Example:
course.get_enrollment_date()'''
url_path = posixpath.join("api", "v1", "courses", course['course_id'], "enrollments")
api_url = urllib.parse.urljoin(course['hostname'], url_path)
token = course['token']
resp = None
students = []
max_iters = 100
iter = 0
while iter < max_iters and (resp is None or "last" not in resp.links.keys() or resp.links["current"]["url"] != resp.links["last"]["url"]):
iter += 1
resp = requests.get(
url = api_url if resp is None else resp.links['next']['url'],
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/json+canvas-string-ids"
},
json={
"type": ["StudentEnrollment"],
"per_page":"100"
}
)
students.extend(resp.json())
enrollment_dates = {}
for st in students:
enrollment_dates[str(st['user_id'])] = str(st['created_at']).strip('Z').replace('T','-').replace(':','-')[:16]
return enrollment_dates
We found that Canvas sometimes doesn't provide the "last" element in its responses, leading to dispatch's canvas request loop breaking. An example of the fixed code follows. We should eventually replace the general loop in rudaux with a similarly generalized version of the below.