Skip to content
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
2 changes: 1 addition & 1 deletion calendar_backend/routes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -

app.add_middleware(
DBSessionMiddleware,
db_url=settings.DB_DSN,
db_url=str(settings.DB_DSN),
engine_args={"pool_pre_ping": True, "isolation_level": "AUTOCOMMIT"},
)
app.add_middleware(
Expand Down
10 changes: 5 additions & 5 deletions calendar_backend/routes/event/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
async def comment_event(event_id: int, comment: EventCommentPost) -> CommentEventGet:
approve_status = ApproveStatuses.APPROVED if not settings.REQUIRE_REVIEW_EVENT_COMMENT else ApproveStatuses.PENDING
comment_event = DbCommentEvent.create(
event_id=event_id, session=db.session, **comment.dict(), approve_status=approve_status
event_id=event_id, session=db.session, **comment.model_dump(), approve_status=approve_status
)
db.session.commit()
return CommentEventGet.from_orm(comment_event)
return CommentEventGet.model_validate(comment_event)


@router.patch("/{id}", response_model=CommentEventGet)
Expand All @@ -30,17 +30,17 @@ async def update_comment(id: int, event_id: int, comment_inp: EventCommentPatch)
raise ObjectNotFound(DbCommentEvent, id)
if comment.approve_status is not ApproveStatuses.PENDING:
raise ForbiddenAction(DbCommentEvent, id)
comment_event = DbCommentEvent.update(id, session=db.session, **comment_inp.dict(exclude_unset=True))
comment_event = DbCommentEvent.update(id, session=db.session, **comment_inp.model_dump(exclude_unset=True))
db.session.commit()
return CommentEventGet.from_orm(comment_event)
return CommentEventGet.model_validate(comment_event)


@router.get("/{id}", response_model=CommentEventGet)
async def get_comment(id: int, event_id: int) -> CommentEventGet:
comment = DbCommentEvent.get(id, session=db.session)
if not comment.event_id == event_id or comment.approve_status != ApproveStatuses.APPROVED:
raise ObjectNotFound(DbCommentEvent, id)
return CommentEventGet.from_orm(comment)
return CommentEventGet.model_validate(comment)


@router.delete("/{id}", response_model=None)
Expand Down
7 changes: 4 additions & 3 deletions calendar_backend/routes/event/comment_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from auth_lib.fastapi import UnionAuth
from fastapi import APIRouter, Depends
from fastapi_sqlalchemy import db
from pydantic import parse_obj_as
from pydantic import TypeAdapter

from calendar_backend.exceptions import ObjectNotFound
from calendar_backend.models import ApproveStatuses
Expand All @@ -25,7 +25,8 @@ async def get_unreviewed_comments(
.filter(DbCommentEvent.event_id == event_id, DbCommentEvent.approve_status == ApproveStatuses.PENDING)
.all()
)
return parse_obj_as(list[CommentEventGet], comments)
adapter = TypeAdapter(list[CommentEventGet])
return adapter.validate_python(comments)


@router.post("/{id}/review/", response_model=CommentEventGet)
Expand All @@ -42,4 +43,4 @@ async def review_comment(
if action == ApproveStatuses.DECLINED:
DbCommentEvent.delete(comment.id, session=db.session)
db.session.commit()
return CommentEventGet.from_orm(comment)
return CommentEventGet.model_validate(comment)
19 changes: 10 additions & 9 deletions calendar_backend/routes/event/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from fastapi import APIRouter, Depends, Query
from fastapi.responses import FileResponse
from fastapi_sqlalchemy import db
from pydantic import parse_obj_as
from pydantic import TypeAdapter

from calendar_backend.exceptions import NotEnoughCriteria
from calendar_backend.methods import list_calendar
Expand All @@ -23,7 +23,7 @@

@router.get("/{id}", response_model=EventGet)
async def get_event_by_id(id: int) -> EventGet:
return EventGet.from_orm(Event.get(id, session=db.session))
return EventGet.model_validate(Event.get(id, session=db.session))


async def _get_timetable(start: date, end: date, group_id, lecturer_id, room_id, detail, limit, offset):
Expand Down Expand Up @@ -60,7 +60,7 @@ async def _get_timetable(start: date, end: date, group_id, lecturer_id, room_id,
}
]

return GetListEvent(items=events, limit=limit, offset=offset, total=cnt).dict(exclude=fmt)
return GetListEvent(items=events, limit=limit, offset=offset, total=cnt).model_dump(exclude=fmt)


@router.get("/", response_model=GetListEvent | None)
Expand All @@ -86,7 +86,7 @@ async def get_events(

@router.post("/", response_model=EventGet)
async def create_event(event: EventPost, _=Depends(UnionAuth(scopes=["timetable.event.create"]))) -> EventGet:
event_dict = event.dict()
event_dict = event.model_dump()
rooms = [Room.get(room_id, session=db.session) for room_id in event_dict.pop("room_id", [])]
lecturers = [Lecturer.get(lecturer_id, session=db.session) for lecturer_id in event_dict.pop("lecturer_id", [])]
groups = [Group.get(group_id, session=db.session) for group_id in event_dict.pop("group_id", [])]
Expand All @@ -98,7 +98,7 @@ async def create_event(event: EventPost, _=Depends(UnionAuth(scopes=["timetable.
session=db.session,
)
db.session.commit()
return EventGet.from_orm(event_get)
return EventGet.model_validate(event_get)


@router.post("/bulk", response_model=list[EventGet])
Expand All @@ -107,7 +107,7 @@ async def create_events(
) -> list[EventGet]:
result = []
for event in events:
event_dict = event.dict()
event_dict = event.model_dump()
rooms = [Room.get(room_id, session=db.session) for room_id in event_dict.pop("room_id", [])]
lecturers = [Lecturer.get(lecturer_id, session=db.session) for lecturer_id in event_dict.pop("lecturer_id", [])]
groups = [Group.get(group_id, session=db.session) for group_id in event_dict.pop("group_id", [])]
Expand All @@ -121,16 +121,17 @@ async def create_events(
)
)
db.session.commit()
return parse_obj_as(list[EventGet], result)
adapter = TypeAdapter(list[EventGet])
return adapter.validate_python(result)


@router.patch("/{id}", response_model=EventGet)
async def patch_event(
id: int, event_inp: EventPatch, _=Depends(UnionAuth(scopes=["timetable.event.update"]))
) -> EventGet:
patched = Event.update(id, session=db.session, **event_inp.dict(exclude_unset=True))
patched = Event.update(id, session=db.session, **event_inp.model_dump(exclude_unset=True))
db.session.commit()
return EventGet.from_orm(patched)
return EventGet.model_validate(patched)


@router.delete("/bulk", response_model=None)
Expand Down
10 changes: 5 additions & 5 deletions calendar_backend/routes/group/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

@router.get("/{id}", response_model=GroupGet)
async def get_group_by_id(id: int) -> GroupGet:
return GroupGet.from_orm(Group.get(id, session=db.session))
return GroupGet.model_validate(Group.get(id, session=db.session))


@router.get("/", response_model=GetListGroup)
Expand All @@ -40,9 +40,9 @@ async def get_groups(query: str = "", limit: int = 10, offset: int = 0) -> GetLi
async def create_group(group: GroupPost, _=Depends(UnionAuth(scopes=["timetable.group.create"]))) -> GroupGet:
if db.session.query(Group).filter(Group.number == group.number).one_or_none():
raise HTTPException(status_code=423, detail="Already exists")
group = Group.create(**group.dict(), session=db.session)
group = Group.create(**group.model_dump(), session=db.session)
db.session.commit()
return GroupGet.from_orm(group)
return GroupGet.model_validate(group)


@router.patch("/{id}", response_model=GroupGet)
Expand All @@ -56,9 +56,9 @@ async def patch_group(
and query.id != id
):
raise HTTPException(status_code=423, detail="Already exists")
patched = Group.update(id, **group_inp.dict(exclude_unset=True), session=db.session)
patched = Group.update(id, **group_inp.model_dump(exclude_unset=True), session=db.session)
db.session.commit()
return GroupGet.from_orm(patched)
return GroupGet.model_validate(patched)


@router.delete("/{id}", response_model=None)
Expand Down
10 changes: 5 additions & 5 deletions calendar_backend/routes/lecturer/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ async def comment_lecturer(lecturer_id: int, comment: LecturerCommentPost) -> Co
db_comment_lecturer = DbCommentLecturer.create(
lecturer_id=lecturer_id,
session=db.session,
**comment.dict(),
**comment.model_dump(),
approve_status=approve_status,
)
db.session.commit()
return CommentLecturer.from_orm(db_comment_lecturer)
return CommentLecturer.model_validate(db_comment_lecturer)


@router.patch("/comment/{id}", response_model=CommentLecturer)
Expand All @@ -35,9 +35,9 @@ async def update_comment_lecturer(id: int, lecturer_id: int, comment_inp: Lectur
raise ObjectNotFound(DbCommentLecturer, id)
if comment.approve_status is not ApproveStatuses.PENDING:
raise ForbiddenAction(DbCommentLecturer, id)
patched = DbCommentLecturer.update(id, session=db.session, **comment_inp.dict(exclude_unset=True))
patched = DbCommentLecturer.update(id, session=db.session, **comment_inp.model_dump(exclude_unset=True))
db.session.commit()
return CommentLecturer.from_orm(patched)
return CommentLecturer.model_validate(patched)


@router.delete("/comment/{id}", response_model=None)
Expand All @@ -58,7 +58,7 @@ async def get_comment(id: int, lecturer_id: int) -> CommentLecturer:
raise ObjectNotFound(DbCommentLecturer, id)
if comment.approve_status is not None:
raise ForbiddenAction(DbCommentLecturer, id)
return CommentLecturer.from_orm(comment)
return CommentLecturer.model_validate(comment)


@router.get("/comment/", response_model=LecturerComments)
Expand Down
7 changes: 4 additions & 3 deletions calendar_backend/routes/lecturer/comment_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from auth_lib.fastapi import UnionAuth
from fastapi import APIRouter, Depends
from fastapi_sqlalchemy import db
from pydantic import parse_obj_as
from pydantic import TypeAdapter

from calendar_backend.exceptions import ObjectNotFound
from calendar_backend.models.db import ApproveStatuses
Expand All @@ -25,7 +25,8 @@ async def get_unreviewed_comments(
)
.all()
)
return parse_obj_as(list[CommentLecturer], comments)
adapter = TypeAdapter(list[CommentLecturer])
return adapter.validate_python(comments)


@router.post("/{id}/review/", response_model=CommentLecturer)
Expand All @@ -42,4 +43,4 @@ async def review_comment(
if action == ApproveStatuses.DECLINED:
DbCommentLecturer.delete(comment.id, session=db.session)
db.session.commit()
return CommentLecturer.from_orm(comment)
return CommentLecturer.model_validate(comment)
17 changes: 10 additions & 7 deletions calendar_backend/routes/lecturer/lecturer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
@router.get("/{id}", response_model=LecturerGet)
async def get_lecturer_by_id(id: int) -> LecturerGet:
lecturer = Lecturer.get(id, session=db.session)
result = LecturerGet.from_orm(Lecturer.get(id, session=db.session))
result = LecturerGet.model_validate(Lecturer.get(id, session=db.session))
if lecturer.avatar_id:
result.avatar_link = get_photo_webpath(lecturer.avatar.link)
return result
Expand All @@ -49,7 +49,7 @@ async def get_lecturers(

result = []
for row in query:
row_get = LecturerGet.from_orm(row)
row_get = LecturerGet.model_validate(row)
if row.avatar:
row_get.avatar_link = get_photo_webpath(row.avatar.link)
result.append(row_get)
Expand All @@ -65,9 +65,9 @@ async def get_lecturers(
async def create_lecturer(
lecturer: LecturerPost, _=Depends(UnionAuth(scopes=["timetable.lecturer.create"]))
) -> LecturerGet:
dblecturer = Lecturer.create(session=db.session, **lecturer.dict())
dblecturer = Lecturer.create(session=db.session, **lecturer.model_dump())
db.session.commit()
return LecturerGet.from_orm(dblecturer)
return LecturerGet.model_validate(dblecturer)


@router.patch("/{id}", response_model=LecturerGet)
Expand All @@ -79,12 +79,15 @@ async def patch_lecturer(
if photo.lecturer_id != id or photo.approve_status != ApproveStatuses.APPROVED:
raise ObjectNotFound(DbPhoto, lecturer_inp.avatar_id)
lecturer_upd = Lecturer.update(
id, session=db.session, **lecturer_inp.dict(exclude_unset=True), avatar_link=get_photo_webpath(photo.link)
id,
session=db.session,
**lecturer_inp.model_dump(exclude_unset=True),
avatar_link=get_photo_webpath(photo.link),
)
else:
lecturer_upd = Lecturer.update(id, session=db.session, **lecturer_inp.dict(exclude_unset=True))
lecturer_upd = Lecturer.update(id, session=db.session, **lecturer_inp.model_dump(exclude_unset=True))
db.session.commit()
return LecturerGet.from_orm(lecturer_upd)
return LecturerGet.model_validate(lecturer_upd)


@router.delete("/{id}", response_model=None)
Expand Down
4 changes: 2 additions & 2 deletions calendar_backend/routes/lecturer/photo.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async def upload_photo(lecturer_id: int, photo: UploadFile = File(...)) -> Photo
"""
photo = await upload_lecturer_photo(lecturer_id, db.session, file=photo)
db.session.commit()
return Photo.from_orm(photo)
return Photo.model_validate(photo)


@router.get("/photo", response_model=LecturerPhotos)
Expand Down Expand Up @@ -68,4 +68,4 @@ async def get_photo(id: int, lecturer_id: int) -> Photo:
photo = DbPhoto.get(id, session=db.session)
if photo.lecturer_id != lecturer_id or photo.approve_status != ApproveStatuses.APPROVED:
raise ObjectNotFound(DbPhoto, id)
return Photo.from_orm(photo)
return Photo.model_validate(photo)
4 changes: 2 additions & 2 deletions calendar_backend/routes/lecturer/photo_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async def get_unreviewed_photos(

result = []
for row in query:
get_row = Photo.from_orm(row)
get_row = Photo.model_validate(row)
get_row.link = get_photo_webpath(row.link)
result.append(get_row)

Expand All @@ -78,4 +78,4 @@ async def review_photo(
if not photo.lecturer.avatar:
photo.lecturer.avatar_id = photo.id
db.session.flush()
return Photo.from_orm(photo)
return Photo.model_validate(photo)
21 changes: 10 additions & 11 deletions calendar_backend/routes/models/base.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import datetime

from pydantic import BaseModel, validator
from pydantic import BaseModel, ConfigDict, field_validator


class Base(BaseModel):
class Config:
orm_mode = True
model_config = ConfigDict(from_attributes=True)


class CommentLecturer(Base):
Expand All @@ -28,11 +27,11 @@ class CommentEventGet(Base):

class GroupGet(Base):
id: int
name: str | None
name: str | None = None
number: str

@classmethod
@validator("number")
@field_validator("number")
def number_validate(cls, v: str):
if len(v) not in [3, 4]:
raise ValueError("Group number must contain 3 or 4 characters")
Expand All @@ -49,9 +48,9 @@ class LecturerGet(Base):
first_name: str
middle_name: str
last_name: str
avatar_id: int | None
avatar_link: str | None
description: str | None
avatar_id: int | None = None
avatar_link: str | None = None
description: str | None = None

def __repr__(self):
return f"Lecturer(id={self.id}, first_name={self.first_name}, middle_name={self.middle_name}, last_name={self.last_name})"
Expand All @@ -60,9 +59,9 @@ def __repr__(self):
class RoomGet(Base):
id: int
name: str
building: str | None
building_url: str | None
direction: str | None
building: str | None = None
building_url: str | None = None
direction: str | None = None

def __repr__(self):
return f"Room(id={self.id}, name={self.name}, direction={self.direction}, building={self.building})"
Expand Down
16 changes: 8 additions & 8 deletions calendar_backend/routes/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@


class EventPatch(Base):
name: str | None
room_id: list[int] | None
group_id: list[int] | None
lecturer_id: list[int] | None
start_ts: datetime.datetime | None
end_ts: datetime.datetime | None
name: str | None = None
room_id: list[int] | None = None
group_id: list[int] | None = None
lecturer_id: list[int] | None = None
start_ts: datetime.datetime | None = None
end_ts: datetime.datetime | None = None

def __repr__(self):
return (
Expand Down Expand Up @@ -58,8 +58,8 @@ class EventCommentPost(Base):


class EventCommentPatch(Base):
text: str | None
author_name: str | None
text: str | None = None
author_name: str | None = None


class EventComments(Base):
Expand Down
Loading