Skip to content

Instantly share code, notes, and snippets.

@bennettscience
Last active May 18, 2020 12:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennettscience/94cfb6c86e4cdbbdfe0efbad66a649f1 to your computer and use it in GitHub Desktop.
Save bennettscience/94cfb6c86e4cdbbdfe0efbad66a649f1 to your computer and use it in GitHub Desktop.
Generate a report of missing assignments for all students in a Canvas course. Returns a CSV.
from canvasapi import Canvas # pip install canvasapi
import csv
import concurrent.futures
from functools import partial
KEY = '' # Your Canvas API key
URL = '' # Your Canvas API URL
COURSE = '' # Your course ID
canvas = Canvas(URL, KEY)
course = canvas.get_course(COURSE)
assignments = len(list(course.get_assignments()))
writer = csv.writer(open('report.csv', 'w'))
def main():
sections = course.get_sections()
writer.writerow(['Name', 'Building', 'Last Activity', 'Complete', 'Missing'])
for section in sections:
enrollments = section.get_enrollments(state="active", type="StudentEnrollment")
# Play with the number of workers.
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
data = []
job = partial(process_user, section=section)
results = [executor.submit(job, enrollment) for enrollment in enrollments]
for f in concurrent.futures.as_completed(results):
data.append(f.result())
print(f'Processed {len(data)} in {len(list(enrollments))} at {section}')
writer.writerows(data)
def process_user(enrollment, section):
missing = get_user_missing(section, enrollment.user['id'])
return [
enrollment.user['sortable_name'],
section.name,
enrollment.last_activity_at,
len(missing), ', '.join(missing)
]
def get_user_missing(section, user_id):
submissions = section.get_multiple_submissions(student_ids=[user_id],
include=["assignment", "submission_history"],
workflow_state="unsubmitted")
missing_list = [item.assignment['name'] for item in submissions \
if item.workflow_state == "unsubmitted" and item.excused is not True]
return missing_list
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment