Skip to content

Conversation

@AssassinMagic
Copy link
Collaborator

Using asyncio with python 3.14 lets python run multi threaded instead of single threaded.

  • CourseInfo in enhanced was updated to take advantage of this

@AssassinMagic AssassinMagic self-assigned this Nov 3, 2025
@AssassinMagic AssassinMagic added the backend Backend label Nov 3, 2025
@vercel
Copy link

vercel bot commented Nov 3, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
gophergrades Ready Ready Preview Nov 3, 2025 6:53pm

from .abstract import EnhanceBase
from db.Models import DepartmentDistribution, ClassDistribution, Libed, Session, and_
import requests
import httpx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not imported in pipenv

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we use aiohttp for RMP already. I would encourage using that so we keep our surface area low with libraries. Check the RMP folder for how that looks like.

finally:
session.close()

async def enhance_helper(self, dept_dist: DepartmentDistribution, semaphore: asyncio.Semaphore) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not fit abstract class structure.

with Pool() as pool:
pool.map(self.enhance_helper, dept_dists)

semaphore = asyncio.Semaphore(9) # Limit concurrent tasks to something under 5 due to rate limiting
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment conflicts with implementation

campus_str = str(campus)
def _process_course_data(self, courses: list[dict], dept: str, campus: str) -> None:
session = Session()
try:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If even one course fails the entire batch will be considered faulty.

response.raise_for_status()
req = response.json()
courses = req.get("courses", [])
except httpx.HTTPStatusError as e:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to know if this is a prohibited error 4xx or a server error 5xx in our logs.

campus = dept_dist.campus
campus_str = str(campus)
def _process_course_data(self, courses: list[dict], dept: str, campus: str) -> None:
session = Session()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sessions should be made for every granular change. You're batching a massive amount of data in one commit.

# Only process UMNTC and UMNRO campuses
if campus_str not in ["UMNTC", "UMNRO"]:
return
courses = []
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this is necessary? Courses will either be assigned a value if the try succeeds. If it fails it should return with no-ops./

courses = req.get("courses", [])
except ValueError:
print("Json malformed, icky!")
await asyncio.to_thread(self._process_course_data, courses, dept, campus)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spawns a seperate thread to run a synchronous function. Can you make _process_course_data async and just await it instead? Would reduce thread overhead.


def enhance(self, dept_dists: list[DepartmentDistribution]) -> None:
async def enhance(self, dept_dists: list[DepartmentDistribution]) -> None:
"""Enhance the data for a list of department distributions in a multiprocessing pool."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update comment.

@Kanishk-K
Copy link
Collaborator

In addition, you want to change the signature and logic of CourseDogEnhance. Even though we no longer use it, I would like to have backwards compatibility.

@Kanishk-K
Copy link
Collaborator

Kanishk-K commented Nov 28, 2025

Once you merge in changes from #148 can you also add the following to the pipenv so we force Python 3.14t usage?

[requires]
python_full_version = "3.14t"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants