mirror of
https://github.com/ae-utbm/sith.git
synced 2025-01-22 15:01:11 +00:00
Custom client for UTBM UV API calls
This commit is contained in:
parent
cddc67f097
commit
27e3781653
@ -10,13 +10,13 @@ from ninja_extra.pagination import PageNumberPaginationExtra, PaginatedResponseS
|
|||||||
from core.auth.api_permissions import HasPerm
|
from core.auth.api_permissions import HasPerm
|
||||||
from pedagogy.models import UV
|
from pedagogy.models import UV
|
||||||
from pedagogy.schemas import SimpleUvSchema, UvFilterSchema, UvSchema
|
from pedagogy.schemas import SimpleUvSchema, UvFilterSchema, UvSchema
|
||||||
from pedagogy.utbm_api import find_uv
|
from pedagogy.utbm_api import UtbmApiClient
|
||||||
|
|
||||||
|
|
||||||
@api_controller("/uv")
|
@api_controller("/uv")
|
||||||
class UvController(ControllerBase):
|
class UvController(ControllerBase):
|
||||||
@route.get(
|
@route.get(
|
||||||
"/{year}/{code}",
|
"/{code}",
|
||||||
permissions=[
|
permissions=[
|
||||||
# this route will almost always be called in the context
|
# this route will almost always be called in the context
|
||||||
# of a UV creation/edition
|
# of a UV creation/edition
|
||||||
@ -26,10 +26,14 @@ class UvController(ControllerBase):
|
|||||||
response=UvSchema,
|
response=UvSchema,
|
||||||
)
|
)
|
||||||
def fetch_from_utbm_api(
|
def fetch_from_utbm_api(
|
||||||
self, year: Annotated[int, Ge(2010)], code: str, lang: Query[str] = "fr"
|
self,
|
||||||
|
code: str,
|
||||||
|
lang: Query[str] = "fr",
|
||||||
|
year: Query[Annotated[int, Ge(2010)] | None] = None,
|
||||||
):
|
):
|
||||||
"""Fetch UV data from the UTBM API and returns it after some parsing."""
|
"""Fetch UV data from the UTBM API and returns it after some parsing."""
|
||||||
res = find_uv(lang, year, code)
|
with UtbmApiClient() as client:
|
||||||
|
res = client.find_uv(lang, code, year)
|
||||||
if res is None:
|
if res is None:
|
||||||
raise NotFound
|
raise NotFound
|
||||||
return res
|
return res
|
||||||
|
@ -46,12 +46,7 @@
|
|||||||
const codeInput = document.querySelector('input[name="code"]')
|
const codeInput = document.querySelector('input[name="code"]')
|
||||||
|
|
||||||
autofillBtn.addEventListener('click', () => {
|
autofillBtn.addEventListener('click', () => {
|
||||||
const today = new Date()
|
const url = `/api/uv/${codeInput.value}`;
|
||||||
let year = today.getFullYear()
|
|
||||||
if (today.getMonth() < 7) { // student year starts in september
|
|
||||||
year--
|
|
||||||
}
|
|
||||||
const url = `/api/uv/${year}/${codeInput.value}`;
|
|
||||||
deleteQuickNotifs()
|
deleteQuickNotifs()
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -2,24 +2,56 @@
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
from pedagogy.schemas import ShortUvList, UtbmFullUvSchema, UtbmShortUvSchema, UvSchema
|
from pedagogy.schemas import ShortUvList, UtbmFullUvSchema, UtbmShortUvSchema, UvSchema
|
||||||
|
|
||||||
|
|
||||||
def find_uv(lang, year, code) -> UvSchema | None:
|
class UtbmApiClient(requests.Session):
|
||||||
|
"""A wrapper around `requests.Session` to perform requests to the UTBM UV API."""
|
||||||
|
|
||||||
|
BASE_URL = settings.SITH_PEDAGOGY_UTBM_API
|
||||||
|
_cache = {}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def current_year(self) -> int:
|
||||||
|
"""Fetch from the API the latest existing year"""
|
||||||
|
url = f"{self.BASE_URL}/guides/fr"
|
||||||
|
response = self.get(url)
|
||||||
|
return response.json()[-1]["annee"]
|
||||||
|
|
||||||
|
def fetch_short_uvs(
|
||||||
|
self, lang: str = "fr", year: int | None = None
|
||||||
|
) -> list[UtbmShortUvSchema]:
|
||||||
|
"""Get the list of UVs in their short format from the UTBM API"""
|
||||||
|
if year is None:
|
||||||
|
year = self.current_year
|
||||||
|
if "short_uvs" not in self._cache:
|
||||||
|
self._cache["short_uvs"] = {}
|
||||||
|
if lang not in self._cache["short_uvs"]:
|
||||||
|
self._cache["short_uvs"][lang] = {}
|
||||||
|
if year not in self._cache["short_uvs"][lang]:
|
||||||
|
url = f"{self.BASE_URL}/uvs/{lang}/{year}"
|
||||||
|
response = self.get(url)
|
||||||
|
uvs = ShortUvList.validate_json(response.content)
|
||||||
|
self._cache["short_uvs"][lang][year] = uvs
|
||||||
|
return self._cache["short_uvs"][lang][year]
|
||||||
|
|
||||||
|
def find_uv(self, lang: str, code: str, year: int | None = None) -> UvSchema | None:
|
||||||
"""Find an UV from the UTBM API."""
|
"""Find an UV from the UTBM API."""
|
||||||
# query the UV list
|
# query the UV list
|
||||||
base_url = settings.SITH_PEDAGOGY_UTBM_API
|
if not year:
|
||||||
uvs_url = f"{base_url}/uvs/{lang}/{year}"
|
year = self.current_year
|
||||||
response = requests.get(uvs_url)
|
# the UTBM API has no way to fetch a single short uv,
|
||||||
uvs: list[UtbmShortUvSchema] = ShortUvList.validate_json(response.content)
|
# and short uvs contain infos that we need and are not
|
||||||
|
# in the full uv schema, so we must fetch everything.
|
||||||
short_uv = next((uv for uv in uvs if uv.code == code), None)
|
short_uvs = self.fetch_short_uvs(lang, year)
|
||||||
|
short_uv = next((uv for uv in short_uvs if uv.code == code), None)
|
||||||
if short_uv is None:
|
if short_uv is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# get detailed information about the UV
|
# get detailed information about the UV
|
||||||
uv_url = f"{base_url}/uv/{lang}/{year}/{code}/{short_uv.code_formation}"
|
uv_url = f"{self.BASE_URL}/uv/{lang}/{year}/{code}/{short_uv.code_formation}"
|
||||||
response = requests.get(uv_url)
|
response = requests.get(uv_url)
|
||||||
full_uv = UtbmFullUvSchema.model_validate_json(response.content)
|
full_uv = UtbmFullUvSchema.model_validate_json(response.content)
|
||||||
return make_clean_uv(short_uv, full_uv)
|
return make_clean_uv(short_uv, full_uv)
|
||||||
|
Loading…
Reference in New Issue
Block a user