Skip to content

Commit

Permalink
💥 add type safety and type checking everywehre
Browse files Browse the repository at this point in the history
  • Loading branch information
ashleyzhang01 committed Nov 5, 2024
1 parent 2264a3b commit 676b65a
Show file tree
Hide file tree
Showing 33 changed files with 223 additions and 133 deletions.
17 changes: 10 additions & 7 deletions backend/dining/api_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime
import json
from typing import Any

import requests
from django.conf import settings
Expand All @@ -16,14 +17,14 @@


class DiningAPIWrapper:
def __init__(self):
def __init__(self) -> None:
self.token = None
self.expiration = timezone.localtime()
self.openid_endpoint = (
"https://sso.apps.k8s.upenn.edu/auth/realms/master/protocol/openid-connect/token"
)

def update_token(self):
def update_token(self) -> None:
if self.expiration > timezone.localtime():
return
body = {
Expand All @@ -37,7 +38,7 @@ def update_token(self):
self.expiration = timezone.localtime() + datetime.timedelta(seconds=response["expires_in"])
self.token = response["access_token"]

def request(self, *args, **kwargs):
def request(self, *args, **kwargs) -> requests.Response:
"""Make a signed request to the dining API."""
self.update_token()

Expand All @@ -54,7 +55,7 @@ def request(self, *args, **kwargs):
except (ConnectTimeout, ReadTimeout, ConnectionError):
raise APIError("Dining: Connection timeout")

def get_venues(self):
def get_venues(self) -> list[dict[str, Any]]:
results = []
venues_route = OPEN_DATA_ENDPOINTS["VENUES"]
response = self.request("GET", venues_route)
Expand Down Expand Up @@ -107,7 +108,7 @@ def get_venues(self):
results.append(value)
return results

def load_menu(self, date=timezone.now().date()):
def load_menu(self, date: datetime.date = timezone.now().date()) -> None:
"""
Loads the weeks menu starting from today
NOTE: This method should only be used in load_next_menu.py, which is
Expand Down Expand Up @@ -147,7 +148,9 @@ def load_menu(self, date=timezone.now().date()):
# Append stations to dining menu
self.load_stations(daypart["stations"], dining_menu)

def load_stations(self, station_response, dining_menu):
def load_stations(
self, station_response: list[dict[str, Any]], dining_menu: DiningMenu
) -> None:
for station_data in station_response:
# TODO: This is inefficient for venues such as Houston Market
station = DiningStation.objects.create(name=station_data["label"], menu=dining_menu)
Expand All @@ -158,7 +161,7 @@ def load_stations(self, station_response, dining_menu):
station.items.add(*items)
station.save()

def load_items(self, item_response):
def load_items(self, item_response: dict[str, Any]) -> None:
item_list = [
DiningItem(
item_id=key,
Expand Down
2 changes: 1 addition & 1 deletion backend/dining/management/commands/load_next_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Command(BaseCommand):
the next 7 days, including the original date.
"""

def handle(self, *args, **kwargs):
def handle(self, *args, **kwargs) -> None:
d = DiningAPIWrapper()
d.load_menu(timezone.now().date() + datetime.timedelta(days=6))
self.stdout.write("Loaded new Dining Menu!")
2 changes: 1 addition & 1 deletion backend/dining/management/commands/load_venues.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Command(BaseCommand):
Loads Venues based on CSV
"""

def handle(self, *args, **kwargs):
def handle(self, *args, **kwargs) -> None:

with open("dining/data/dining_venues.csv") as data:
reader = csv.reader(data)
Expand Down
3 changes: 2 additions & 1 deletion backend/dining/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from typing import Any

from rest_framework import serializers

Expand All @@ -18,7 +19,7 @@ class Meta:
model = DiningItem
fields = "__all__"

def get_nutrition_info(self, obj):
def get_nutrition_info(self, obj: DiningItem) -> dict[str, Any]:
try:
return json.loads(obj.nutrition_info)
except json.JSONDecodeError:
Expand Down
11 changes: 6 additions & 5 deletions backend/dining/views.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import datetime

from django.core.cache import cache
from django.db.models import Count
from django.db.models import Count, QuerySet
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.timezone import make_aware
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView

Expand All @@ -24,7 +25,7 @@ class Venues(APIView):
GET: returns list of venue data provided by Penn API, as well as an image of the venue
"""

def get(self, request):
def get(self, request: Request) -> Response:
try:
return Response(d.get_venues())
except APIError as e:
Expand All @@ -39,7 +40,7 @@ class Menus(generics.ListAPIView):

serializer_class = DiningMenuSerializer

def get_queryset(self):
def get_queryset(self) -> QuerySet[DiningMenu]:
# TODO: We only have data for the next week, so we should 404
# if date_param is out of bounds
if date_param := self.kwargs.get("date"):
Expand All @@ -61,7 +62,7 @@ class Preferences(APIView):
permission_classes = [IsAuthenticated]
key = "dining_preferences:{user_id}"

def get(self, request):
def get(self, request: Request) -> Response:
key = self.key.format(user_id=request.user.id)
cached_preferences = cache.get(key)
if cached_preferences is None:
Expand All @@ -71,7 +72,7 @@ def get(self, request):
cache.set(key, cached_preferences, Cache.MONTH)
return Response({"preferences": cached_preferences})

def post(self, request):
def post(self, request: Request) -> Response:
key = self.key.format(user_id=request.user.id)
profile = request.user.profile
preferences = profile.dining_preferences
Expand Down
8 changes: 5 additions & 3 deletions backend/gsr_booking/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.contrib import admin
from django.db.models import QuerySet
from rest_framework.request import Request

from gsr_booking.models import GSR, Group, GroupMembership, GSRBooking, Reservation

Expand All @@ -9,10 +11,10 @@ class GroupMembershipInline(admin.TabularInline):

readonly_fields = ["name"]

def name(self, obj):
def name(self, obj: GroupMembership) -> str:
return obj.user.get_full_name()

def get_fields(self, request, obj=None):
def get_fields(self, request, obj=None) -> list[str]:
fields = super().get_fields(request, obj)
to_remove = ["user", "name"]
return ["name"] + [f for f in fields if f not in to_remove]
Expand All @@ -31,7 +33,7 @@ class GroupMembershipAdmin(admin.ModelAdmin):


class GSRAdmin(admin.ModelAdmin):
def get_queryset(self, request):
def get_queryset(self, request: Request) -> QuerySet[GSR]:
return GSR.all_objects.all()

list_display = ["name", "kind", "lid", "gid", "in_use"]
Expand Down
Loading

0 comments on commit 676b65a

Please sign in to comment.