Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mypy #322

Merged
merged 16 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,34 @@ repos:
rev: v1.1-mobile-backend
hooks:
- id: black
args: [-l100]
args: [-l100, --config, backend/pyproject.toml]
- id: isort
args: []
- id: flake8
args: [--config, backend/setup.cfg]
- id: detect-private-key

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
additional_dependencies:
- types-requests
- types-python-dateutil
- django-stubs
- djangorestframework-stubs
- types-PyYAML
- types-redis
- types-pytz
files: ^backend/
exclude: ^backend/.*/migrations/.*$
args: [
--ignore-missing-imports,
--disallow-untyped-defs,
--check-untyped-defs,
--warn-redundant-casts,
--no-implicit-optional,
--strict-optional,
--warn-unused-ignores,
--disallow-incomplete-defs,
]
2 changes: 2 additions & 0 deletions backend/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ webdriver-manager = "*"
pre-commit = "*"
alt-profanity-check = "*"
inflection = "*"
types-redis = "*"
types-pytz = "*"

[requires]
python_version = "3.11"
397 changes: 214 additions & 183 deletions backend/Pipfile.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions backend/dining/api_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def get_venues(self) -> list[dict[str, Any]]:
for key, value in venues.items():
# Cleaning up json response
venue = Venue.objects.filter(venue_id=key).first()
if venue is None:
continue
value["name"] = venue.name
value["image"] = venue.image_url if venue else None

Expand Down
4 changes: 1 addition & 3 deletions backend/dining/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ class Migration(migrations.Migration):

initial = True

dependencies = [
("user", "0002_profile_laundry_preferences"),
]
dependencies = [("user", "0002_profile_laundry_preferences")]

operations = [
migrations.CreateModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

class Migration(migrations.Migration):

dependencies = [
("dining", "0001_initial"),
]
dependencies = [("dining", "0001_initial")]

operations = [
migrations.CreateModel(
Expand Down
10 changes: 3 additions & 7 deletions backend/dining/migrations/0003_venue_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@

class Migration(migrations.Migration):

dependencies = [
("dining", "0002_diningitem_diningstation_diningmenu"),
]
dependencies = [("dining", "0002_diningitem_diningstation_diningmenu")]

operations = [
migrations.AddField(
model_name="venue",
name="name",
field=models.CharField(max_length=255, null=True),
),
model_name="venue", name="name", field=models.CharField(max_length=255, null=True)
)
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,16 @@

class Migration(migrations.Migration):

dependencies = [
("dining", "0003_venue_name"),
]
dependencies = [("dining", "0003_venue_name")]

operations = [
migrations.RemoveField(
model_name="diningtransaction",
name="profile",
),
migrations.RemoveField(model_name="diningtransaction", name="profile"),
migrations.AlterField(
model_name="diningitem",
name="description",
field=models.CharField(max_length=1000),
model_name="diningitem", name="description", field=models.CharField(max_length=1000)
),
migrations.AlterField(
model_name="diningitem",
name="ingredients",
field=models.CharField(max_length=1000),
),
migrations.DeleteModel(
name="DiningBalance",
),
migrations.DeleteModel(
name="DiningTransaction",
model_name="diningitem", name="ingredients", field=models.CharField(max_length=1000)
),
migrations.DeleteModel(name="DiningBalance"),
migrations.DeleteModel(name="DiningTransaction"),
]
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@

class Migration(migrations.Migration):

dependencies = [
("dining", "0004_remove_diningtransaction_profile_and_more"),
]
dependencies = [("dining", "0004_remove_diningtransaction_profile_and_more")]

operations = [
migrations.AddField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,10 @@

class Migration(migrations.Migration):

dependencies = [
("dining", "0005_diningitem_allergens_diningitem_nutrition_info_and_more"),
]
dependencies = [("dining", "0005_diningitem_allergens_diningitem_nutrition_info_and_more")]

operations = [
migrations.RemoveField(
model_name="diningmenu",
name="stations",
),
migrations.RemoveField(model_name="diningmenu", name="stations"),
migrations.AlterField(
model_name="diningitem",
name="allergens",
Expand Down
44 changes: 25 additions & 19 deletions backend/dining/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,43 @@


class Venue(models.Model):
venue_id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255, null=True)
image_url = models.URLField()
venue_id: models.IntegerField = models.IntegerField(primary_key=True)
name: models.CharField = models.CharField(max_length=255, null=True)
image_url: models.URLField = models.URLField()

def __str__(self):
def __str__(self) -> str:
return f"{self.name}-{str(self.venue_id)}"


class DiningItem(models.Model):
item_id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255)
description = models.CharField(max_length=1000, blank=True)
ingredients = models.CharField(max_length=1000, blank=True) # comma separated list
allergens = models.CharField(max_length=1000, blank=True) # comma separated list
nutrition_info = models.CharField(max_length=1000, blank=True) # json string.
item_id: models.IntegerField = models.IntegerField(primary_key=True)
name: models.CharField = models.CharField(max_length=255)
description: models.CharField = models.CharField(max_length=1000, blank=True)
ingredients: models.CharField = models.CharField(
max_length=1000, blank=True
) # comma separated list
allergens: models.CharField = models.CharField(
max_length=1000, blank=True
) # comma separated list
nutrition_info: models.CharField = models.CharField(max_length=1000, blank=True) # json string.
# Technically, postgres supports json fields but that involves local postgres
# instead of sqlite AND we don't need to query on this field

def __str__(self):
def __str__(self) -> str:
return f"{self.name}"


class DiningStation(models.Model):
name = models.CharField(max_length=255)
items = models.ManyToManyField(DiningItem)
menu = models.ForeignKey("DiningMenu", on_delete=models.CASCADE, related_name="stations")
name: models.CharField = models.CharField(max_length=255)
items: models.ManyToManyField = models.ManyToManyField(DiningItem)
menu: models.ForeignKey = models.ForeignKey(
"DiningMenu", on_delete=models.CASCADE, related_name="stations"
)


class DiningMenu(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE)
date = models.DateField(default=timezone.now)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
service = models.CharField(max_length=255)
venue: models.ForeignKey = models.ForeignKey(Venue, on_delete=models.CASCADE)
date: models.DateField = models.DateField(default=timezone.now)
start_time: models.DateTimeField = models.DateTimeField()
end_time: models.DateTimeField = models.DateTimeField()
service: models.CharField = models.CharField(max_length=255)
14 changes: 8 additions & 6 deletions backend/dining/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime

from django.core.cache import cache
from django.db.models import Count, QuerySet
from django.db.models import Count, Manager, QuerySet
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.timezone import make_aware
Expand All @@ -15,6 +15,7 @@
from dining.models import DiningMenu, Venue
from dining.serializers import DiningMenuSerializer
from utils.cache import Cache
from utils.types import get_user


d = DiningAPIWrapper()
Expand All @@ -40,7 +41,7 @@ class Menus(generics.ListAPIView):

serializer_class = DiningMenuSerializer

def get_queryset(self) -> QuerySet[DiningMenu]:
def get_queryset(self) -> QuerySet[DiningMenu, Manager[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 @@ -63,18 +64,19 @@ class Preferences(APIView):
key = "dining_preferences:{user_id}"

def get(self, request: Request) -> Response:
key = self.key.format(user_id=request.user.id)
key = self.key.format(user_id=get_user(request).id)
cached_preferences = cache.get(key)
if cached_preferences is None:
preferences = request.user.profile.dining_preferences
preferences = get_user(request).profile.dining_preferences
# aggregates venues and puts it in form {"venue_id": x, "count": x}
cached_preferences = preferences.values("venue_id").annotate(count=Count("venue_id"))
cache.set(key, cached_preferences, Cache.MONTH)
return Response({"preferences": cached_preferences})

def post(self, request: Request) -> Response:
key = self.key.format(user_id=request.user.id)
profile = request.user.profile
user = get_user(request)
key = self.key.format(user_id=user.id)
profile = user.profile
preferences = profile.dining_preferences

venue_ids = set(request.data["venues"])
Expand Down
16 changes: 10 additions & 6 deletions backend/gsr_booking/admin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from typing import Any, cast

from django.contrib import admin
from django.db.models import QuerySet
from rest_framework.request import Request
from django.db.models import Manager, QuerySet
from django.http import HttpRequest

from gsr_booking.models import GSR, Group, GroupMembership, GSRBooking, Reservation
from utils.types import UserType


class GroupMembershipInline(admin.TabularInline):
Expand All @@ -12,12 +15,13 @@ class GroupMembershipInline(admin.TabularInline):
readonly_fields = ["name"]

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

def get_fields(self, request, obj=None) -> list[str]:
def get_fields(self, request: HttpRequest, obj: Any = 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]
return ["name"] + [str(f) for f in fields if f not in to_remove]


class GroupAdmin(admin.ModelAdmin):
Expand All @@ -33,7 +37,7 @@ class GroupMembershipAdmin(admin.ModelAdmin):


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

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