UBC-DSCI / rudaux

LMS + External Tool Workflow Orchestration
https://ubc-dsci.github.io/rudaux
MIT License
7 stars 5 forks source link

Incorporate fixed canvas request loop #54

Closed trevorcampbell closed 4 years ago

trevorcampbell commented 4 years ago

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
trevorcampbell commented 4 years ago

canvas.py does this properly now