From 88eec976623b7db34bd54123a2a9f6ba2669bc79 Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 20 Dec 2024 21:50:34 +0100 Subject: [PATCH] Migrate class-based config to ConfigDict (#807) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔨 Migrate class-based config to ConfigDict * 🔨 Use json_schema_extra * 🔨 Fix json key * 🔨 Replace model dict by model_dump --- .../appointment/database/repo/appointment.py | 2 +- .../src/appointment/database/repo/calendar.py | 2 +- .../database/repo/external_connection.py | 2 +- .../src/appointment/database/repo/schedule.py | 2 +- backend/src/appointment/database/repo/slot.py | 6 +- backend/src/appointment/database/schemas.py | 56 ++++++++----------- backend/src/appointment/routes/schedule.py | 2 +- 7 files changed, 30 insertions(+), 42 deletions(-) diff --git a/backend/src/appointment/database/repo/appointment.py b/backend/src/appointment/database/repo/appointment.py index 32c191944..077b4cbba 100644 --- a/backend/src/appointment/database/repo/appointment.py +++ b/backend/src/appointment/database/repo/appointment.py @@ -9,7 +9,7 @@ def create(db: Session, appointment: schemas.AppointmentFull, slots: list[schemas.SlotBase] = []): """create new appointment with slots for calendar""" - db_appointment = models.Appointment(**appointment.dict()) + db_appointment = models.Appointment(**appointment.model_dump()) db.add(db_appointment) db.commit() db.refresh(db_appointment) diff --git a/backend/src/appointment/database/repo/calendar.py b/backend/src/appointment/database/repo/calendar.py index 558fe57e5..669081494 100644 --- a/backend/src/appointment/database/repo/calendar.py +++ b/backend/src/appointment/database/repo/calendar.py @@ -53,7 +53,7 @@ def get_by_subscriber(db: Session, subscriber_id: int, include_unconnected: bool def create(db: Session, calendar: schemas.CalendarConnection, subscriber_id: int): """create new calendar for owner, if not already existing""" - db_calendar = models.Calendar(**calendar.dict(), owner_id=subscriber_id) + db_calendar = models.Calendar(**calendar.model_dump(), owner_id=subscriber_id) subscriber_calendars = get_by_subscriber(db, subscriber_id) subscriber_calendar_urls = [c.url for c in subscriber_calendars] # check if subscriber already holds this calendar by url diff --git a/backend/src/appointment/database/repo/external_connection.py b/backend/src/appointment/database/repo/external_connection.py index 6eda6a5e7..fbbe40e5c 100644 --- a/backend/src/appointment/database/repo/external_connection.py +++ b/backend/src/appointment/database/repo/external_connection.py @@ -13,7 +13,7 @@ def create(db: Session, external_connection: ExternalConnection): - db_external_connection = models.ExternalConnections(**external_connection.dict()) + db_external_connection = models.ExternalConnections(**external_connection.model_dump()) db.add(db_external_connection) db.commit() db.refresh(db_external_connection) diff --git a/backend/src/appointment/database/repo/schedule.py b/backend/src/appointment/database/repo/schedule.py index e08054f65..3d803bddc 100644 --- a/backend/src/appointment/database/repo/schedule.py +++ b/backend/src/appointment/database/repo/schedule.py @@ -11,7 +11,7 @@ def create(db: Session, schedule: schemas.ScheduleBase): """create a new schedule with slots for calendar""" - db_schedule = models.Schedule(**schedule.dict()) + db_schedule = models.Schedule(**schedule.model_dump()) db.add(db_schedule) db.commit() db.refresh(db_schedule) diff --git a/backend/src/appointment/database/repo/slot.py b/backend/src/appointment/database/repo/slot.py index f03925fca..3223bcd7f 100644 --- a/backend/src/appointment/database/repo/slot.py +++ b/backend/src/appointment/database/repo/slot.py @@ -37,7 +37,7 @@ def add_for_appointment(db: Session, slots: list[schemas.SlotBase], appointment_ """create new slots for appointment of given id""" return_slots = [] for slot in slots: - db_slot = models.Slot(**slot.dict()) + db_slot = models.Slot(**slot.model_dump()) db_slot.appointment_id = appointment_id db.add(db_slot) return_slots.append(db_slot) @@ -47,7 +47,7 @@ def add_for_appointment(db: Session, slots: list[schemas.SlotBase], appointment_ def add_for_schedule(db: Session, slot: schemas.SlotBase, schedule_id: int): """create new slot for schedule of given id""" - db_slot = models.Slot(**slot.dict()) + db_slot = models.Slot(**slot.model_dump()) db_slot.schedule_id = schedule_id db.add(db_slot) db.commit() @@ -96,7 +96,7 @@ def delete_all_for_subscriber(db: Session, subscriber_id: int): def update(db: Session, slot_id: int, attendee: schemas.Attendee): """update existing slot by id and create corresponding attendee""" # create attendee - db_attendee = models.Attendee(**attendee.dict()) + db_attendee = models.Attendee(**attendee.model_dump()) db.add(db_attendee) db.commit() db.refresh(db_attendee) diff --git a/backend/src/appointment/database/schemas.py b/backend/src/appointment/database/schemas.py index 2d4a3a40d..dca8b4178 100644 --- a/backend/src/appointment/database/schemas.py +++ b/backend/src/appointment/database/schemas.py @@ -9,7 +9,7 @@ from datetime import datetime, date, time, timezone, timedelta from typing import Annotated, Optional, Self -from pydantic import BaseModel, Field, EmailStr, model_validator +from pydantic import BaseModel, ConfigDict, Field, EmailStr, model_validator from pydantic_core import PydanticCustomError from ..defines import DEFAULT_CALENDAR_COLOUR, FALLBACK_LOCALE @@ -41,10 +41,9 @@ class AttendeeBase(BaseModel): class Attendee(AttendeeBase): - id: int + model_config = ConfigDict(from_attributes=True) - class Config: - from_attributes = True + id: int """ SLOT model schemas @@ -63,15 +62,14 @@ class SlotBase(BaseModel): class Slot(SlotBase): + model_config = ConfigDict(from_attributes=True) + id: int appointment_id: int subscriber_id: int | None = None time_updated: datetime | None = None attendee: Attendee | None = None - class Config: - from_attributes = True - class SlotOut(SlotBase): id: int | None = None @@ -113,15 +111,14 @@ class AppointmentFull(AppointmentBase): class Appointment(AppointmentFull): + model_config = ConfigDict(from_attributes=True) + id: int uuid: UUID time_created: datetime | None = None time_updated: datetime | None = None slots: list[Slot] = [] - class Config: - from_attributes = True - class AppointmentWithCalendarOut(Appointment): """For /me/appointments""" @@ -152,15 +149,16 @@ class AvailabilityBase(BaseModel): class Availability(AvailabilityBase): + model_config = ConfigDict(from_attributes=True) + id: int time_created: datetime | None = None time_updated: datetime | None = None - class Config: - from_attributes = True - class ScheduleBase(BaseModel): + model_config = ConfigDict(json_encoders = { time: lambda t: t.strftime('%H:%M') }) + active: bool | None = True name: str = Field(min_length=1, max_length=128) slug: Optional[str] = None @@ -180,22 +178,16 @@ class ScheduleBase(BaseModel): booking_confirmation: bool = True timezone: Optional[str] = None - class Config: - json_encoders = { - time: lambda t: t.strftime('%H:%M'), - } - class Schedule(ScheduleBase): + model_config = ConfigDict(from_attributes=True) + id: int time_created: datetime | None = None time_updated: datetime | None = None availabilities: list[Availability] = [] calendar: 'CalendarBase' - class Config: - from_attributes = True - class ScheduleValidationIn(ScheduleBase): """ScheduleBase but with specific fields overridden to add validation.""" @@ -266,14 +258,13 @@ class CalendarConnectionIn(CalendarConnection): class Calendar(CalendarConnection): + model_config = ConfigDict(from_attributes=True) + id: int owner_id: int appointments: list[Appointment] = [] schedules: list[Schedule] = [] - class Config: - from_attributes = True - class CalendarOut(CalendarBase): id: int @@ -322,13 +313,12 @@ class SubscriberAuth(SubscriberBase): class Subscriber(SubscriberAuth): + model_config = ConfigDict(from_attributes=True) + id: int calendars: list[Calendar] = [] slots: list[Slot] = [] - ftue_level: Optional[int] = Field(gte=0) - - class Config: - from_attributes = True + ftue_level: Optional[int] = Field(json_schema_extra={'gte': 0}) class SubscriberMeOut(SubscriberBase): @@ -337,13 +327,12 @@ class SubscriberMeOut(SubscriberBase): class SubscriberAdminOut(Subscriber): + model_config = ConfigDict(from_attributes=True) + invite: Invite | None = None time_created: datetime time_deleted: datetime | None - class Config: - from_attributes = True - """ other schemas used for requests or data migration """ @@ -470,6 +459,8 @@ class WaitingListInviteAdminOut(BaseModel): class WaitingListAdminOut(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: int email: str email_verified: bool @@ -479,9 +470,6 @@ class WaitingListAdminOut(BaseModel): invite: Invite | None = None - class Config: - from_attributes = True - class PageLoadIn(BaseModel): browser: Optional[str] = None diff --git a/backend/src/appointment/routes/schedule.py b/backend/src/appointment/routes/schedule.py index f479bb8ac..908e18e19 100644 --- a/backend/src/appointment/routes/schedule.py +++ b/backend/src/appointment/routes/schedule.py @@ -287,7 +287,7 @@ def request_schedule_availability_slot( raise validation.SlotNotFoundException() # check if slot still available, might already be taken at this time - slot = schemas.SlotBase(**s_a.slot.dict()) + slot = schemas.SlotBase(**s_a.slot.model_dump()) if repo.slot.exists_on_schedule(db, slot, schedule.id): raise validation.SlotAlreadyTakenException()