`bucket` parameter in Assignments endpoint

Jump to solution
bbennett2
Community Champion

I'm working on creating a custom report which pulls users from a course and lists the number of missing assignments along with the total assignments in the course. The `bucket` param in the API docs lists 'unsbumitted' as an acceptable parameter, but when request that list, I get an empty response.

When looking at my test account, the test student has unsubmitted assingments, so I'm wondering if A) anyone else can confirm this issue, and B) is there a better way to pull this report together?

Here's a sample script using the Python `canvasapi` library.

from canvasapi import Canvas

canvas = Canvas(PROD_URL, PROD_KEY)

course = canvas.get_course(12345)

# Just need the total number of assignments, details don't matter
assignments = len(list(siop.get_assignments()))

user = canvas.get_user(98765)
missing = user.get_assignments(course.id, bucket="future") # returns empty

# Calling without the bucket returns all assignments, so it works
# missing = user.get_assignments(course.id)

for item in missing:
print(item.name)

Would it be better to call the assignments list and include `submissions` and then compare with a student list? That should work, but given that this endpoint is available, it would save some trouble with nested loops.

Labels (1)
0 Likes
1 Solution
bbennett2
Community Champion
Author

After some more playing, I was able to get a workaround using the submissions API. This script compiles a CSV of users in a course. Each row has the user name, section, enrollment type, last logged in activity, missing and completed assignment totals. The full working (although slow) script is below in case you're trying to do the same.

from config import PROD_URL, PROD_KEY
from canvasapi import Canvas
import csv

writer = csv.writer(open('course_report.csv', 'w'))

# This could benefit from some kind of multiprocessing queue
def get_missing(section_id, user_id):
missing = section.get_multiple_submissions(student_ids=[user_id], workflow_state='unsubmitted')
print(f"User id: {user_id} is missing {len(list(missing))}")
return len(list(missing))

def get_user_details(student, section_id, assignments):
for student in students:
if student['enrollments'][0]['enrollment_state'] == 'active':
missing = get_missing(section.id, student['id'])
user_complete = assignments - missing

writer.writerow([student['name'], section.name, student['enrollments'][0]['role'], student['enrollments'][0]['last_activity_at'], missing, user_complete])


def main():
canvas = Canvas(PROD_URL, PROD_KEY)
course = canvas.get_course(12345)

# This is a hacky way to get the number of assignments in the course. A
# better alternative would be to follow this process (potentially):
# https://github.com/ucfopen/canvasapi/pull/237#pullrequestreview-227354435
assignments = len(list(course.get_assignments()))

# This is the longest part of the call because it compiles several different
# endpoints into one large dict.
sections = course.get_sections(include=["students","enrollments"])

for section in sections:
for user in section.students:
print(f"Processing {user['name']}: {section.name}")

# Passing the User object here includes the `enrollments` dict
# which saves an API call later.
get_user_details(user, section.id, assignments)

if __name__ == "__main__":
main()
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post