Skip to content

Commit

Permalink
Bump FastAPI to 0.95.0
Browse files Browse the repository at this point in the history
This release adds support for dependencies and parameters using Annotated and recommends its usage
  • Loading branch information
ChrisLovering committed Mar 21, 2023
1 parent 07ff82c commit e0b413e
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 57 deletions.
5 changes: 5 additions & 0 deletions api/database.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
from typing import Annotated

from fastapi import Depends
from sqlalchemy import BigInteger, Boolean, Column, Enum, ForeignKey, Index, Integer, PrimaryKeyConstraint, Text, text
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker

from api.constants import Config
from api.dependencies import get_db_session

engine = create_async_engine(Config.DATABASE_URL)
Base = declarative_base()

Session = sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)
DBSession = Annotated[AsyncSession, Depends(get_db_session)]


class TeamUser(Base):
Expand Down
14 changes: 6 additions & 8 deletions api/routers/codejams.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, HTTPException
from sqlalchemy import desc, update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select

from api.database import Jam, Team, TeamUser, User
from api.dependencies import get_db_session
from api.database import DBSession, Jam, Team, TeamUser, User
from api.models import CodeJam, CodeJamResponse

router = APIRouter(prefix="/codejams", tags=["codejams"])


@router.get("/")
async def get_codejams(session: AsyncSession = Depends(get_db_session)) -> list[CodeJamResponse]:
async def get_codejams(session: DBSession) -> list[CodeJamResponse]:
"""Get all the codejams stored in the database."""
codejams = await session.execute(select(Jam).order_by(desc(Jam.id)))
codejams.unique()
Expand All @@ -25,7 +23,7 @@ async def get_codejams(session: AsyncSession = Depends(get_db_session)) -> list[
"/{codejam_id}",
responses={404: {"description": "CodeJam could not be found or there is no ongoing code jam."}},
)
async def get_codejam(codejam_id: int, session: AsyncSession = Depends(get_db_session)) -> CodeJamResponse:
async def get_codejam(codejam_id: int, session: DBSession) -> CodeJamResponse:
"""
Get a specific codejam stored in the database by ID.
Expand All @@ -52,9 +50,9 @@ async def get_codejam(codejam_id: int, session: AsyncSession = Depends(get_db_se
@router.patch("/{codejam_id}", responses={404: {"description": "Code Jam with specified ID does not exist."}})
async def modify_codejam(
codejam_id: int,
session: DBSession,
name: Optional[str] = None,
ongoing: Optional[bool] = None,
session: AsyncSession = Depends(get_db_session),
) -> CodeJamResponse:
"""Modify the specified codejam to change its name and/or whether it's the ongoing code jam."""
codejam = await session.execute(select(Jam).where(Jam.id == codejam_id))
Expand All @@ -80,7 +78,7 @@ async def modify_codejam(


@router.post("/")
async def create_codejam(codejam: CodeJam, session: AsyncSession = Depends(get_db_session)) -> CodeJamResponse:
async def create_codejam(codejam: CodeJam, session: DBSession) -> CodeJamResponse:
"""
Create a new codejam and get back the one just created.
Expand Down
11 changes: 5 additions & 6 deletions api/routers/infractions.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import APIRouter, HTTPException
from sqlalchemy.future import select

from api.database import DBSession
from api.database import Infraction as DbInfraction
from api.database import Jam, User
from api.dependencies import get_db_session
from api.models import Infraction, InfractionResponse

router = APIRouter(prefix="/infractions", tags=["infractions"])


@router.get("/")
async def get_infractions(session: AsyncSession = Depends(get_db_session)) -> list[InfractionResponse]:
async def get_infractions(session: DBSession) -> list[InfractionResponse]:
"""Get every infraction stored in the database."""
infractions = await session.execute(select(DbInfraction))
infractions.unique()
Expand All @@ -23,7 +22,7 @@ async def get_infractions(session: AsyncSession = Depends(get_db_session)) -> li
"/{infraction_id}",
responses={404: {"description": "Infraction could not be found."}},
)
async def get_infraction(infraction_id: int, session: AsyncSession = Depends(get_db_session)) -> InfractionResponse:
async def get_infraction(infraction_id: int, session: DBSession) -> InfractionResponse:
"""Get a specific infraction stored in the database by ID."""
infraction_result = await session.execute(select(DbInfraction).where(DbInfraction.id == infraction_id))
infraction_result.unique()
Expand All @@ -40,7 +39,7 @@ async def get_infraction(infraction_id: int, session: AsyncSession = Depends(get
)
async def create_infraction(
infraction: Infraction,
session: AsyncSession = Depends(get_db_session),
session: DBSession,
) -> InfractionResponse:
"""Add an infraction for a user to the database."""
jam_id = (await session.execute(select(Jam.id).where(Jam.id == infraction.jam_id))).scalars().one_or_none()
Expand Down
23 changes: 12 additions & 11 deletions api/routers/teams.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Response
from fastapi import APIRouter, HTTPException, Response
from sqlalchemy import func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select

from api.database import Jam, Team, TeamUser
from api.database import DBSession, Jam, Team, TeamUser
from api.database import User as DbUser
from api.dependencies import get_db_session
from api.models import TeamResponse, User

router = APIRouter(prefix="/teams", tags=["teams"])
Expand Down Expand Up @@ -36,7 +35,7 @@ async def ensure_user_exists(user_id: int, session: AsyncSession) -> DbUser:


@router.get("/")
async def get_teams(current_jam: bool = False, session: AsyncSession = Depends(get_db_session)) -> list[TeamResponse]:
async def get_teams(session: DBSession, current_jam: bool = False) -> list[TeamResponse]:
"""Get every code jam team in the database."""
if not current_jam:
teams = await session.execute(select(Team))
Expand All @@ -49,7 +48,9 @@ async def get_teams(current_jam: bool = False, session: AsyncSession = Depends(g

@router.get("/find", responses={404: {"description": "Team could not be found."}})
async def find_team_by_name(
name: str, jam_id: Optional[int] = None, session: AsyncSession = Depends(get_db_session)
name: str,
session: DBSession,
jam_id: Optional[int] = None,
) -> TeamResponse:
"""Get a specific code jam team by name."""
if jam_id is None:
Expand All @@ -70,13 +71,13 @@ async def find_team_by_name(


@router.get("/{team_id}", responses={404: {"description": "Team could not be found."}})
async def get_team(team_id: int, session: AsyncSession = Depends(get_db_session)) -> TeamResponse:
async def get_team(team_id: int, session: DBSession) -> TeamResponse:
"""Get a specific code jam team in the database by ID."""
return await ensure_team_exists(team_id, session)


@router.get("/{team_id}/users", responses={404: {"description": "Team could not be found."}})
async def get_team_users(team_id: int, session: AsyncSession = Depends(get_db_session)) -> list[User]:
async def get_team_users(team_id: int, session: DBSession) -> list[User]:
"""Get the users of a specific code jam team in the database."""
await ensure_team_exists(team_id, session)

Expand All @@ -95,9 +96,7 @@ async def get_team_users(team_id: int, session: AsyncSession = Depends(get_db_se
400: {"description": "This user is already on the team."},
},
)
async def add_user_to_team(
team_id: int, user_id: int, is_leader: bool = False, session: AsyncSession = Depends(get_db_session)
) -> User:
async def add_user_to_team(team_id: int, user_id: int, session: DBSession, is_leader: bool = False) -> User:
"""Add a user to a specific code jam team in the database."""
await ensure_team_exists(team_id, session)
await ensure_user_exists(user_id, session)
Expand Down Expand Up @@ -128,7 +127,9 @@ async def add_user_to_team(
},
)
async def remove_user_from_team(
team_id: int, user_id: int, session: AsyncSession = Depends(get_db_session)
team_id: int,
user_id: int,
session: DBSession,
) -> Response:
"""Remove a user from a specific code jam team in the database."""
await ensure_team_exists(team_id, session)
Expand Down
13 changes: 6 additions & 7 deletions api/routers/users.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from typing import Any

from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select

from api.database import Jam, TeamUser, User
from api.dependencies import get_db_session
from api.database import DBSession, Jam, TeamUser, User
from api.models import UserResponse, UserTeamResponse

router = APIRouter(prefix="/users", tags=["users"])
Expand Down Expand Up @@ -48,7 +47,7 @@ async def get_user_data(session: AsyncSession, user_id: int) -> dict[str, Any]:


@router.get("/")
async def get_users(session: AsyncSession = Depends(get_db_session)) -> list[UserResponse]:
async def get_users(session: DBSession) -> list[UserResponse]:
"""Get information about all the users stored in the database."""
users = await session.execute(select(User.id))
users.unique()
Expand All @@ -57,7 +56,7 @@ async def get_users(session: AsyncSession = Depends(get_db_session)) -> list[Use


@router.get("/{user_id}", responses={404: {"description": "User could not be found."}})
async def get_user(user_id: int, session: AsyncSession = Depends(get_db_session)) -> UserResponse:
async def get_user(user_id: int, session: DBSession) -> UserResponse:
"""Get a specific user stored in the database by ID."""
user = await session.execute(select(User).where(User.id == user_id))
user.unique()
Expand All @@ -69,7 +68,7 @@ async def get_user(user_id: int, session: AsyncSession = Depends(get_db_session)


@router.post("/{user_id}", responses={400: {"description": "User already exists."}})
async def create_user(user_id: int, session: AsyncSession = Depends(get_db_session)) -> UserResponse:
async def create_user(user_id: int, session: DBSession) -> UserResponse:
"""Create a new user with the specified ID to the database."""
user = await session.execute(select(User).where(User.id == user_id))
user.unique()
Expand All @@ -94,7 +93,7 @@ async def create_user(user_id: int, session: AsyncSession = Depends(get_db_sessi
}
},
)
async def get_current_team(user_id: int, session: AsyncSession = Depends(get_db_session)) -> UserTeamResponse:
async def get_current_team(user_id: int, session: DBSession) -> UserTeamResponse:
"""Get a user's current team information."""
user = await session.execute(select(User).where(User.id == user_id))
user.unique()
Expand Down
12 changes: 4 additions & 8 deletions api/routers/winners.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, HTTPException
from sqlalchemy import func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select

from api.database import Jam, User
from api.database import DBSession, Jam, User
from api.database import Winner as DbWinner
from api.dependencies import get_db_session
from api.models import Winner, WinnerResponse

router = APIRouter(prefix="/winners", tags=["winners"])
Expand All @@ -15,7 +13,7 @@
"/{jam_id}",
responses={404: {"description": "The specified codejam could not be found."}},
)
async def get_winners(jam_id: int, session: AsyncSession = Depends(get_db_session)) -> list[WinnerResponse]:
async def get_winners(jam_id: int, session: DBSession) -> list[WinnerResponse]:
"""Get the top ten winners from the specified codejam."""
jam = await session.execute(select(Jam).where(Jam.id == jam_id))
jam.unique()
Expand All @@ -38,9 +36,7 @@ async def get_winners(jam_id: int, session: AsyncSession = Depends(get_db_sessio
409: {"description": "One or more users are already a winner in the specified codejam."},
},
)
async def create_winners(
jam_id: int, winners: list[Winner], session: AsyncSession = Depends(get_db_session)
) -> list[WinnerResponse]:
async def create_winners(jam_id: int, winners: list[Winner], session: DBSession) -> list[WinnerResponse]:
"""Add the top ten winners to the specified codejam."""
jam = await session.execute(select(Jam).where(Jam.id == jam_id))
jam.unique()
Expand Down
12 changes: 6 additions & 6 deletions main-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ click==8.1.3 ; python_full_version >= "3.11.0" and python_full_version < "3.12.0
colorama==0.4.6 ; python_full_version >= "3.11.0" and python_full_version < "3.12.0" and sys_platform == "win32" or python_full_version >= "3.11.0" and python_full_version < "3.12.0" and platform_system == "Windows" \
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
fastapi==0.89.0 ; python_full_version >= "3.11.0" and python_full_version < "3.12.0" \
--hash=sha256:34990132751324c988db7bd15bf43a86f5c8580e58a4438e14b12d72fb0ae1d1 \
--hash=sha256:d8cafbd223b5a3c010119ba61fb246d5fd3b8f4766cfa93f922a416650797976
fastapi==0.95.0 ; python_full_version >= "3.11.0" and python_full_version < "3.12.0" \
--hash=sha256:99d4fdb10e9dd9a24027ac1d0bd4b56702652056ca17a6c8721eec4ad2f14e18 \
--hash=sha256:daf73bbe844180200be7966f68e8ec9fd8be57079dff1bacb366db32729e6eb5
greenlet==2.0.2 ; python_full_version >= "3.11.0" and platform_machine == "aarch64" and python_full_version < "3.12.0" or python_full_version >= "3.11.0" and platform_machine == "ppc64le" and python_full_version < "3.12.0" or python_full_version >= "3.11.0" and platform_machine == "x86_64" and python_full_version < "3.12.0" or python_full_version >= "3.11.0" and platform_machine == "amd64" and python_full_version < "3.12.0" or python_full_version >= "3.11.0" and platform_machine == "AMD64" and python_full_version < "3.12.0" or python_full_version >= "3.11.0" and platform_machine == "win32" and python_full_version < "3.12.0" or python_full_version >= "3.11.0" and platform_machine == "WIN32" and python_full_version < "3.12.0" \
--hash=sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a \
--hash=sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a \
Expand Down Expand Up @@ -390,9 +390,9 @@ sqlalchemy[asyncio,postgresql-asyncpg]==1.4.45 ; python_full_version >= "3.11.0"
--hash=sha256:f61e54b8c2b389de1a8ad52394729c478c67712dbdcdadb52c2575e41dae94a5 \
--hash=sha256:f7944b04e6fcf8d733964dd9ee36b6a587251a1a4049af3a9b846f6e64eb349a \
--hash=sha256:fd69850860093a3f69fefe0ab56d041edfdfe18510b53d9a2eaecba2f15fa795
starlette==0.22.0 ; python_full_version >= "3.11.0" and python_full_version < "3.12.0" \
--hash=sha256:b092cbc365bea34dd6840b42861bdabb2f507f8671e642e8272d2442e08ea4ff \
--hash=sha256:b5eda991ad5f0ee5d8ce4c4540202a573bb6691ecd0c712262d0bc85cf8f2c50
starlette==0.26.1 ; python_full_version >= "3.11.0" and python_full_version < "3.12.0" \
--hash=sha256:41da799057ea8620e4667a3e69a5b1923ebd32b1819c8fa75634bbe8d8bea9bd \
--hash=sha256:e87fce5d7cbdde34b76f0ac69013fd9d190d581d80681493016666e6f96c6d5e
typing-extensions==4.5.0 ; python_full_version >= "3.11.0" and python_full_version < "3.12.0" \
--hash=sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb \
--hash=sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4
Expand Down
20 changes: 10 additions & 10 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license = "MIT"
python = "3.11.*"

alembic = {version = "1.10.2", extras = ["tz"]}
fastapi = "0.89.0"
fastapi = "0.95.0"
python-decouple = "3.8"
SQLAlchemy = {version = "1.4.45", extras = ["asyncio", "postgresql_asyncpg"]}
uvicorn = {version = "0.21.1", extras = ["standard"]}
Expand Down

0 comments on commit e0b413e

Please sign in to comment.