1+ """
2+ Module for fetching and updating section enrollment data asynchronously.
3+ """
4+
15import asyncio
2- import requests
36import time
47from concurrent .futures import ThreadPoolExecutor
8+
9+ import requests
510from django .utils import timezone
611from asgiref .sync import sync_to_async
12+ from django .http import HttpResponseNotFound
713
814from tcf_website .models import Section , SectionEnrollment , Semester , Course
915
1016TIMEOUT = 10
1117MAX_WORKERS = 5
1218
19+
1320def fetch_section_data (section ):
1421 """Fetch enrollment data for a given section from the UVA SIS API."""
1522 url = (
@@ -34,20 +41,24 @@ def fetch_section_data(section):
3441 }
3542 except requests .exceptions .RequestException as e :
3643 print (f"Network error while fetching section { section .sis_section_number } : { e } " )
37- except Exception as e :
38- print (f"Unexpected error while fetching section { section .sis_section_number } : { e } " )
39-
44+ except ValueError as e :
45+ print (f"JSON decoding error for section { section .sis_section_number } : { e } " )
46+
4047 return {}
4148
4249
4350async def update_enrollment_data (course_id ):
4451 """Asynchronous function to update enrollment data using ThreadPoolExecutor."""
4552 start_time = time .monotonic ()
46-
53+
54+ if not await sync_to_async (Course .objects .filter (id = course_id ).exists )():
55+ return HttpResponseNotFound ("Course not found." )
4756 course = await sync_to_async (Course .objects .get )(id = course_id )
4857 latest_semester = await sync_to_async (Semester .latest )()
49- sections = await sync_to_async (list )(Section .objects .filter (course = course , semester = latest_semester ))
50-
58+ sections = await sync_to_async (list )(
59+ Section .objects .filter (course = course , semester = latest_semester )
60+ )
61+
5162 if not sections :
5263 print (f"No sections found for course { course .code ()} in semester { latest_semester } ." )
5364 return
@@ -68,20 +79,23 @@ async def process_section(section):
6879 await asyncio .gather (* (process_section (section ) for section in sections ))
6980
7081 elapsed_time = time .monotonic () - start_time
71- print (f"Enrollment update completed at { timezone .now ()} (Total time: { elapsed_time :.2f} seconds)" )
82+ print (f"Enrollment update completed at { timezone .now ()} "
83+ f"(Total time: { elapsed_time :.2f} seconds)" )
7284
7385
7486def update_section_enrollment (section , data ):
7587 """Update SectionEnrollment safely within an async function."""
7688 section_enrollment , _ = SectionEnrollment .objects .get_or_create (section = section )
77- section_enrollment .enrollment_taken = data .get (' enrollment_taken' , 0 )
78- section_enrollment .enrollment_limit = data .get (' enrollment_limit' , 0 )
79- section_enrollment .waitlist_taken = data .get (' waitlist_taken' , 0 )
80- section_enrollment .waitlist_limit = data .get (' waitlist_limit' , 0 )
89+ section_enrollment .enrollment_taken = data .get (" enrollment_taken" , 0 )
90+ section_enrollment .enrollment_limit = data .get (" enrollment_limit" , 0 )
91+ section_enrollment .waitlist_taken = data .get (" waitlist_taken" , 0 )
92+ section_enrollment .waitlist_limit = data .get (" waitlist_limit" , 0 )
8193 section_enrollment .save ()
82-
94+
8395 print (
8496 f"Updated section { section .sis_section_number } | "
85- f"Enrollment: { section_enrollment .enrollment_taken } /{ section_enrollment .enrollment_limit } | "
86- f"Waitlist: { section_enrollment .waitlist_taken } /{ section_enrollment .waitlist_limit } "
97+ f"Enrollment: { section_enrollment .enrollment_taken } /"
98+ f"{ section_enrollment .enrollment_limit } | "
99+ f"Waitlist: { section_enrollment .waitlist_taken } /"
100+ f"{ section_enrollment .waitlist_limit } "
87101 )
0 commit comments