Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
Hi,
I'd love to get feedback on some code that ChatGPT 4 came up with to do the following:
Find all published courses for the current term for each teacher and 'favorite' any courses which have NOT been favorited. Purpose of code will be to keep current term published courses in the dashboard.
I am not a programmer but wanted to find out how helpful AI might be in giving a 'head start' in creating scripts for accomplishing tasks in Canvas. I assume the section on un-favorited courses is probably not needed since my question was specific to 'favoriting'. I'd appreciate any and all comments positive and negative--especially what parts of the needed code is ChatGPT completely missing. This was using the paid subscription for ChatGPT 4.
Some basic configuration info:
# Configuration
canvas_domain = 'YOUR_CANVAS_DOMAIN' # Example: 'canvas.instructure.com'
access_token = 'YOUR_ACCESS_TOKEN' # API token with admin privileges
headers = {'Authorization': f'Bearer {access_token}'}
def get_json(url):
"""Make a GET request to the specified URL."""
response = requests.get(url, headers=headers)
response.raise_for_status() # Raise an error for bad status codes
return response.json()
def post(url):
"""Make a POST request to the specified URL."""
response = requests.post(url, headers=headers)
response.raise_for_status()
return response.json()
def get_current_term_id():
"""Retrieve the current term's ID."""
terms = get_json(f'https://{canvas_domain}/api/v1/accounts/1/terms')
current_term = max(terms['enrollment_terms'], key=lambda x: x['start_at'])
return current_term['id']
def get_courses(term_id):
"""Retrieve courses for a specific term, filtering for published ones."""
courses = []
page = 1
while True:
response = get_json(f'https://{canvas_domain}/api/v1/courses?enrollment_term_id={term_id}&page={page}&per_page=100')
courses.extend(response)
if 'next' not in response.links:
break
page += 1
return [course for course in courses if course['workflow_state'] == 'available']
def get_favorite_courses(user_id):
"""Retrieve the user's favorited courses."""
return get_json(f'https://{canvas_domain}/api/v1/users/{user_id}/favorites/courses')
def favorite_course(user_id, course_id):
"""Add a course to the user's favorites."""
post(f'https://{canvas_domain}/api/v1/users/{user_id}/favorites/courses/{course_id}')
def get_teachers():
"""Retrieve all users with the role of Teacher."""
teachers = []
page = 1
while True:
response = get_json(f'https://{canvas_domain}/api/v1/accounts/1/users?per_page=100&page={page}&enrollment_type=teacher')
teachers.extend(response)
if 'next' not in response.links:
break
page += 1
return teachers
def process_teacher(teacher):
"""Process each teacher to favorite their unfavorite published courses."""
try:
unfavorited_courses = find_unfavorited_courses(teacher['id'])
for course in unfavorited_courses:
favorite_course(teacher['id'], course['id'])
print(f"Teacher {teacher['id']} - Added to Favorites: {course['name']} (ID: {course['id']})")
except requests.HTTPError as e:
print(f"An HTTP error occurred for teacher {teacher['id']}: {e}")
def find_unfavorited_courses(user_id):
"""Find published courses that are not favorited by the specified user."""
term_id = get_current_term_id()
published_courses = get_courses(term_id)
favorite_courses = get_favorite_courses(user_id)
favorite_course_ids = {course['id'] for course in favorite_courses}
unfavorited_courses = [course for course in published_courses if course['id'] not in favorite_course_ids]
return unfavorited_courses
def main():
teachers = get_teachers()
for teacher in teachers:
process_teacher(teacher)
if __name__ == "__main__":
main()
Thanks!
I applaud the use of ChatGPT to get some starter code going and your willingness to explore Python and the Canvas API!
Just some comments:
1) The API call to get favorites actually doesn't work as written! Here's the documentation for favorites in Canvas.
You cannot specify a User ID like in other API endpoints to get that particular user's favorites. You can only use the self endpoint, which will pull your favorites.
So to get around this you can use API Masquerading.
This allows you to specify which Canvas user ID you want to act as, assuming you have the permissions to do so. What will then happen is that you'll basically act as them during the calls. This is equivalent to "Act as User"/masquerade in the UI.
2) get_current_term_id may work if your terms are unique for each school year/semester, but not so much if you use a SIS integration and your term page is insanely large. For example, at my K-12 district, I have distinct terms associated for each school, so instead of Q1, Q2, Q3, Q4, S1, S2, 23-24 terms that apply to all schools, I have terms like XYZ School - 23-24/YR...multiply this with 180+ schools and it gets to be a bit much.
In my case, I would pull the Terms CSV report from Canvas and just use Python to go through that CSV to find the "current terms" (all of them) and then do the favoriting code.
Hope this helps!
Thanks a lot for the quick reply. This is very helpful. I had heard that about masquerading to get it to work. Thanks for the reference to the API for masquerading. Again, thanks for the speedy reply!
You're welcome!
This is a really good example of having a human review any code or code snippets generated by AI as while it looks correct it isn't 🤣
Lastly, if you're planning to run the code on your instance of Canvas, use your beta instance (usually XXX.beta.instructure.com) before putting the code into production/live, as unexpected results may happen.
Thanks, yes, definitely. We are looking at testing in a sandbox environment before even going to test.
To participate in the Instructure Community, you need to sign up or log in:
Sign In