Convert to SQLModel + adding matchday
This commit is contained in:
parent
bf3bd68e52
commit
3b6ba0a2a4
|
|
@ -4,9 +4,13 @@ from app.api.api_v1.endpoints import users
|
|||
from app.api.api_v1.endpoints import login
|
||||
from app.api.api_v1.endpoints import player
|
||||
from app.api.api_v1.endpoints import team
|
||||
from app.api.api_v1.endpoints import match
|
||||
from app.api.api_v1.endpoints import matchday
|
||||
|
||||
api_router = APIRouter()
|
||||
api_router.include_router(login.router, tags=["login"])
|
||||
api_router.include_router(users.router, prefix="/users", tags=["users"])
|
||||
api_router.include_router(player.router, prefix="/player", tags=["player"])
|
||||
api_router.include_router(team.router, prefix="/team", tags=["team"])
|
||||
api_router.include_router(matchday.router, prefix="/matchday", tags=["matchday"])
|
||||
#api_router.include_router(match.router, prefix="/match", tags=["match"])
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@ from fastapi import APIRouter, Body, Depends, HTTPException
|
|||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud, models, schemas
|
||||
from app import crud
|
||||
from app.api import deps
|
||||
from app.core import security
|
||||
from app.core.config import settings
|
||||
from app.core.security import get_password_hash
|
||||
from app.models.msg import Msg
|
||||
from app.models.token import Token
|
||||
from app.models.user import User
|
||||
from app.utils import (
|
||||
generate_password_reset_token,
|
||||
send_reset_password_email,
|
||||
|
|
@ -19,7 +22,7 @@ from app.utils import (
|
|||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/login/access-token", response_model=schemas.Token)
|
||||
@router.post("/login/access-token", response_model=Token)
|
||||
def login_access_token(
|
||||
db: Session = Depends(deps.get_db),
|
||||
form_data: OAuth2PasswordRequestForm = Depends(),
|
||||
|
|
@ -47,9 +50,9 @@ def login_access_token(
|
|||
}
|
||||
|
||||
|
||||
@router.post("/login/test-token", response_model=schemas.User)
|
||||
@router.post("/login/test-token", response_model=User)
|
||||
def test_token(
|
||||
current_user: models.User = Depends(deps.get_current_user),
|
||||
current_user: User = Depends(deps.get_current_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Test access token
|
||||
|
|
@ -57,7 +60,7 @@ def test_token(
|
|||
return current_user
|
||||
|
||||
|
||||
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
|
||||
@router.post("/password-recovery/{email}", response_model=Msg)
|
||||
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
|
||||
"""
|
||||
Password Recovery
|
||||
|
|
@ -76,7 +79,7 @@ def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
|
|||
return {"msg": "Password recovery email sent"}
|
||||
|
||||
|
||||
@router.post("/reset-password/", response_model=schemas.Msg)
|
||||
@router.post("/reset-password/", response_model=Msg)
|
||||
def reset_password(
|
||||
token: str = Body(...),
|
||||
new_password: str = Body(...),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
from typing import Any, List
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from pydantic.networks import EmailStr
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud
|
||||
from app.api import deps
|
||||
|
||||
from app.models.player import Player, PlayerCreate, PlayerUpdate
|
||||
from app.models.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/{id}", response_model=Player)
|
||||
def read_player(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
firstname: str,
|
||||
lastname: str,
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Get player by firstname and lastname.
|
||||
"""
|
||||
player = crud.player.get_player_by_name(
|
||||
db=db, firstname=firstname, lastname=lastname
|
||||
)
|
||||
if not player:
|
||||
raise HTTPException(status_code=404, detail="player not found")
|
||||
if not crud.user.is_superuser(current_user):
|
||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
||||
return player
|
||||
|
||||
|
||||
@router.post("/", response_model=List[Player])
|
||||
def create_player(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
players_in: list[PlayerCreate],
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Create new user.
|
||||
"""
|
||||
player_out = []
|
||||
for player_in in players_in:
|
||||
player = crud.player.get_player_by_name(
|
||||
db, firstname=player_in.firstname, lastname=player_in.lastname
|
||||
)
|
||||
if player:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"The user with this username already exists in the "
|
||||
f"system. Player is {player}",
|
||||
)
|
||||
player = crud.player.create(db, obj_in=player_in)
|
||||
player_out.append(player)
|
||||
|
||||
return player_out
|
||||
|
||||
|
||||
@router.get("/", response_model=List[Player])
|
||||
def get_players(
|
||||
db: Session = Depends(deps.get_db),
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Retrieve all players.
|
||||
"""
|
||||
player = crud.player.get_multi(db, skip=skip, limit=limit)
|
||||
return player
|
||||
|
||||
|
||||
@router.post("/{id}", response_model=Player)
|
||||
def update_player(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
id: int,
|
||||
player_in: PlayerUpdate,
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Update player.
|
||||
"""
|
||||
|
||||
player = crud.player.get(db=db, id=id)
|
||||
if not player:
|
||||
raise HTTPException(status_code=404, detail="Player not found")
|
||||
|
||||
player = crud.player.update(db=db, db_obj=player, obj_in=player_in)
|
||||
return player
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
from typing import Any, List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud
|
||||
from app.api import deps
|
||||
|
||||
from app.models.matchday import Matchday, MatchdayCreate, MatchdayUpdate, \
|
||||
MatchdayWithPlayers
|
||||
from app.models.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/{matchday_id}", response_model=MatchdayWithPlayers)
|
||||
def read_matchday(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
matchday_id: int,
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Get matchday by firstname and lastname.
|
||||
"""
|
||||
matchday = crud.matchday.get(
|
||||
db=db, id=matchday_id
|
||||
)
|
||||
if not matchday:
|
||||
raise HTTPException(status_code=404, detail="matchday not found")
|
||||
if not crud.user.is_superuser(current_user):
|
||||
raise HTTPException(status_code=400, detail="Not enough permissions")
|
||||
return matchday
|
||||
|
||||
|
||||
@router.post("/", response_model=Matchday)
|
||||
def create_matchday(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
matchday_in: MatchdayCreate,
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Create new user.
|
||||
"""
|
||||
matchday = crud.matchday.get_unique_day(db, obj_in=matchday_in)
|
||||
if matchday:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"The matchday with this day already exists in the "
|
||||
f"system. Matchday is {matchday}",
|
||||
)
|
||||
matchday = crud.matchday.create(db, obj_in=matchday_in)
|
||||
|
||||
return matchday
|
||||
|
||||
|
||||
@router.get("/", response_model=List[MatchdayWithPlayers])
|
||||
def get_matchdays(
|
||||
db: Session = Depends(deps.get_db),
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Retrieve all matchdays.
|
||||
"""
|
||||
matchday = crud.matchday.get_multi(db, skip=skip, limit=limit)
|
||||
return matchday
|
||||
|
||||
|
||||
@router.post("/{matchday_id}", response_model=Matchday)
|
||||
def update_matchday(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
matchday_id: int,
|
||||
matchday_in: MatchdayUpdate,
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Update matchday.
|
||||
"""
|
||||
|
||||
matchday = crud.matchday.get(db=db, id=matchday_id)
|
||||
if not matchday:
|
||||
raise HTTPException(status_code=404, detail="Matchday not found")
|
||||
|
||||
matchday = crud.matchday.update(db=db, db_obj=matchday, obj_in=matchday_in)
|
||||
return matchday
|
||||
|
||||
|
||||
@router.put("/players/{matchday_id}", response_model=Matchday)
|
||||
def add_player_matchday(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
player_id: int,
|
||||
matchday_id: int,
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Add player to matchday.
|
||||
"""
|
||||
if crud.player.get(db, id=player_id) is None:
|
||||
raise HTTPException(status_code=404, detail="Player not found")
|
||||
if crud.matchday.get(db=db, id=matchday_id) is None:
|
||||
raise HTTPException(status_code=404, detail="Matchday not found")
|
||||
if crud.matchday.is_player_in_matchday(
|
||||
db=db, player_id=player_id, matchday_id=matchday_id
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=404, detail="Player is already in team"
|
||||
)
|
||||
matchday = crud.matchday.add_player_in_matchday(db, matchday_id, player_id)
|
||||
return matchday
|
||||
|
|
@ -1,31 +1,30 @@
|
|||
from typing import Any, List
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from pydantic.networks import EmailStr
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud, models, schemas
|
||||
from app import crud
|
||||
from app.api import deps
|
||||
from app.core.config import settings
|
||||
from app.schemas.player import PlayerUpdate
|
||||
|
||||
from app.models.player import Player, PlayerCreate, PlayerUpdate, \
|
||||
PlayerTeamsMatchdays
|
||||
from app.models.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/{id}", response_model=schemas.Player)
|
||||
@router.get("/{player_id}", response_model=PlayerTeamsMatchdays)
|
||||
def read_player(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
firstname: str,
|
||||
lastname: str,
|
||||
current_user: models.User = Depends(deps.get_current_active_user),
|
||||
player_id: int,
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Get player by firstname and lastname.
|
||||
Get player by id.
|
||||
"""
|
||||
player = crud.player.get_player_by_name(
|
||||
db=db, firstname=firstname, lastname=lastname
|
||||
player = crud.player.get(
|
||||
db=db, id=player_id
|
||||
)
|
||||
if not player:
|
||||
raise HTTPException(status_code=404, detail="player not found")
|
||||
|
|
@ -34,56 +33,60 @@ def read_player(
|
|||
return player
|
||||
|
||||
|
||||
@router.post("/", response_model=schemas.Player)
|
||||
@router.post("/", response_model=List[Player])
|
||||
def create_player(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
player_in: schemas.PlayerCreate,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
players_in: list[PlayerCreate],
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Create new user.
|
||||
"""
|
||||
player = crud.player.get_player_by_name(
|
||||
db, firstname=player_in.firstname, lastname=player_in.lastname
|
||||
)
|
||||
if player:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="The user with this username already exists in the system.",
|
||||
player_out = []
|
||||
for player_in in players_in:
|
||||
player = crud.player.get_player_by_name(
|
||||
db, firstname=player_in.firstname, lastname=player_in.lastname
|
||||
)
|
||||
player = crud.player.create(db, obj_in=player_in)
|
||||
if player:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"The user with this username already exists in the "
|
||||
f"system. Player is {player}",
|
||||
)
|
||||
player = crud.player.create(db, obj_in=player_in)
|
||||
player_out.append(player)
|
||||
|
||||
return player
|
||||
return player_out
|
||||
|
||||
|
||||
@router.get("/", response_model=List[schemas.Player])
|
||||
@router.get("/", response_model=List[PlayerTeamsMatchdays])
|
||||
def get_players(
|
||||
db: Session = Depends(deps.get_db),
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Retrieve all players.
|
||||
"""
|
||||
player = crud.player.get_players(db, skip=skip, limit=limit)
|
||||
player = crud.player.get_multi(db, skip=skip, limit=limit)
|
||||
return player
|
||||
|
||||
|
||||
@router.post("/{id}", response_model=schemas.Player)
|
||||
@router.post("/{player_id}", response_model=Player)
|
||||
def update_player(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
id: int,
|
||||
player_id: int,
|
||||
player_in: PlayerUpdate,
|
||||
current_user: models.User = Depends(deps.get_current_active_user),
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Update player.
|
||||
"""
|
||||
|
||||
player = crud.player.get(db=db, id=id)
|
||||
player = crud.player.get(db=db, id=player_id)
|
||||
if not player:
|
||||
raise HTTPException(status_code=404, detail="Player not found")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,24 +4,25 @@ from fastapi import APIRouter, Depends, HTTPException
|
|||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud, models, schemas
|
||||
from app import crud
|
||||
from app.api import deps
|
||||
|
||||
from app.models.team import Team, TeamCreate, TeamWithPlayers
|
||||
from app.models.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/{id}", response_model=schemas.Team)
|
||||
@router.get("/{team_id}", response_model=Team)
|
||||
def get_team(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
id: int,
|
||||
current_user: models.User = Depends(deps.get_current_active_user),
|
||||
team_id: int,
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Get team by id.
|
||||
"""
|
||||
team = crud.team.get_team(db=db, team_id=id)
|
||||
team = crud.team.get_team(db=db, team_id=team_id)
|
||||
if not team:
|
||||
raise HTTPException(status_code=404, detail="player not found")
|
||||
if not crud.user.is_superuser(current_user):
|
||||
|
|
@ -29,26 +30,26 @@ def get_team(
|
|||
return team
|
||||
|
||||
|
||||
@router.get("/", response_model=List[schemas.Team])
|
||||
@router.get("/", response_model=List[TeamWithPlayers])
|
||||
def get_teams(
|
||||
db: Session = Depends(deps.get_db),
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Retrieve teams.
|
||||
"""
|
||||
team = crud.team.get_teams(db, skip=skip, limit=limit)
|
||||
team = crud.team.get_multi( db, skip=skip, limit=limit)
|
||||
return team
|
||||
|
||||
|
||||
@router.post("/", response_model=schemas.Team)
|
||||
@router.post("/", response_model=Team)
|
||||
def create_team(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
team_in: schemas.TeamCreate,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
team_in: TeamCreate,
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Create team.
|
||||
|
|
@ -59,20 +60,20 @@ def create_team(
|
|||
return team
|
||||
|
||||
|
||||
@router.put("/players/{team_id}", response_model=schemas.Team)
|
||||
@router.put("/players/{team_id}", response_model=Team)
|
||||
def add_player_team(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
player_id: int,
|
||||
team_id: int,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Add player to team.
|
||||
"""
|
||||
if crud.player.get_player(db, player_id=player_id) is None:
|
||||
if crud.player.get(db, id=player_id) is None:
|
||||
raise HTTPException(status_code=404, detail="Player not found")
|
||||
if crud.team.get_team(db=db, team_id=team_id) is None:
|
||||
if crud.team.get(db=db, id=team_id) is None:
|
||||
raise HTTPException(status_code=404, detail="Team not found")
|
||||
if crud.team.is_player_in_team(
|
||||
db=db, player_id=player_id, team_id=team_id
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ from fastapi.encoders import jsonable_encoder
|
|||
from pydantic.networks import EmailStr
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud, models, schemas
|
||||
from app import crud, models
|
||||
from app.api import deps
|
||||
from app.core.config import settings
|
||||
|
||||
from app.models.user import UserUpdate, User, UserCreate
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/", response_model=List[schemas.User])
|
||||
@router.get("/", response_model=List[User])
|
||||
def read_users(
|
||||
db: Session = Depends(deps.get_db),
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Retrieve users.
|
||||
|
|
@ -27,12 +27,12 @@ def read_users(
|
|||
return users
|
||||
|
||||
|
||||
@router.post("/", response_model=schemas.User)
|
||||
@router.post("/", response_model=User)
|
||||
def create_user(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
user_in: schemas.UserCreate,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
user_in: UserCreate,
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Create new user.
|
||||
|
|
@ -48,20 +48,20 @@ def create_user(
|
|||
return user
|
||||
|
||||
|
||||
@router.put("/me", response_model=schemas.User)
|
||||
@router.put("/me", response_model=User)
|
||||
def update_user_me(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
password: str = Body(None),
|
||||
full_name: str = Body(None),
|
||||
email: EmailStr = Body(None),
|
||||
current_user: models.User = Depends(deps.get_current_active_user),
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Update own user.
|
||||
"""
|
||||
current_user_data = jsonable_encoder(current_user)
|
||||
user_in = schemas.UserUpdate(**current_user_data)
|
||||
user_in = UserUpdate(**current_user_data)
|
||||
if password is not None:
|
||||
user_in.password = password
|
||||
if full_name is not None:
|
||||
|
|
@ -72,10 +72,10 @@ def update_user_me(
|
|||
return user
|
||||
|
||||
|
||||
@router.get("/me", response_model=schemas.User)
|
||||
@router.get("/me", response_model=User)
|
||||
def read_user_me(
|
||||
db: Session = Depends(deps.get_db),
|
||||
current_user: models.User = Depends(deps.get_current_active_user),
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
) -> Any:
|
||||
"""
|
||||
Get current user.
|
||||
|
|
@ -83,7 +83,7 @@ def read_user_me(
|
|||
return current_user
|
||||
|
||||
|
||||
@router.post("/open", response_model=schemas.User)
|
||||
@router.post("/open", response_model=User)
|
||||
def create_user_open(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
|
|
@ -105,17 +105,17 @@ def create_user_open(
|
|||
status_code=400,
|
||||
detail="The user with this username already exists in the system",
|
||||
)
|
||||
user_in = schemas.UserCreate(
|
||||
user_in = UserCreate(
|
||||
password=password, email=email, full_name=full_name
|
||||
)
|
||||
user = crud.user.create(db, obj_in=user_in)
|
||||
return user
|
||||
|
||||
|
||||
@router.get("/{user_id}", response_model=schemas.User)
|
||||
@router.get("/{user_id}", response_model=User)
|
||||
def read_user_by_id(
|
||||
user_id: int,
|
||||
current_user: models.User = Depends(deps.get_current_active_user),
|
||||
current_user: User = Depends(deps.get_current_active_user),
|
||||
db: Session = Depends(deps.get_db),
|
||||
) -> Any:
|
||||
"""
|
||||
|
|
@ -131,13 +131,13 @@ def read_user_by_id(
|
|||
return user
|
||||
|
||||
|
||||
@router.put("/{user_id}", response_model=schemas.User)
|
||||
@router.put("/{user_id}", response_model=User)
|
||||
def update_user(
|
||||
*,
|
||||
db: Session = Depends(deps.get_db),
|
||||
user_id: int,
|
||||
user_in: schemas.UserUpdate,
|
||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
||||
user_in: UserUpdate,
|
||||
current_user: User = Depends(deps.get_current_active_superuser),
|
||||
) -> Any:
|
||||
"""
|
||||
Update a user.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ from jose import jwt
|
|||
from pydantic import ValidationError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud, models, schemas
|
||||
from app import crud
|
||||
from app.models.token import TokenPayload
|
||||
from app.models.user import User
|
||||
from app.core import security
|
||||
from app.core.config import settings
|
||||
from app.db.session import SessionLocal
|
||||
|
|
@ -26,12 +28,12 @@ def get_db() -> Generator:
|
|||
|
||||
def get_current_user(
|
||||
db: Session = Depends(get_db), token: str = Depends(reusable_oauth2)
|
||||
) -> models.User:
|
||||
) -> User:
|
||||
try:
|
||||
payload = jwt.decode(
|
||||
token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
|
||||
)
|
||||
token_data = schemas.TokenPayload(**payload)
|
||||
token_data = TokenPayload(**payload)
|
||||
except (jwt.JWTError, ValidationError):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
|
@ -44,16 +46,17 @@ def get_current_user(
|
|||
|
||||
|
||||
def get_current_active_user(
|
||||
current_user: models.User = Depends(get_current_user),
|
||||
) -> models.User:
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> User:
|
||||
if not crud.user.is_active(current_user):
|
||||
raise HTTPException(status_code=400, detail="Inactive user")
|
||||
return current_user
|
||||
|
||||
|
||||
def get_current_active_superuser(
|
||||
current_user: models.User = Depends(get_current_user),
|
||||
) -> models.User:
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> User:
|
||||
|
||||
if not crud.user.is_superuser(current_user):
|
||||
raise HTTPException(
|
||||
status_code=400, detail="The user doesn't have enough privileges"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from .crud_user import user
|
||||
from .crud_player import player
|
||||
from .crud_team import team
|
||||
from .crud_matchday import matchday
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import Any, Dict, Generic, List, Optional, Type, TypeVar, Union
|
|||
from fastapi.encoders import jsonable_encoder
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlmodel import select
|
||||
|
||||
from app.db.base_class import Base
|
||||
|
||||
|
|
@ -22,12 +23,14 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
|
|||
self.model = model
|
||||
|
||||
def get(self, db: Session, id: Any) -> Optional[ModelType]:
|
||||
return db.query(self.model).filter(self.model.id == id).first()
|
||||
statement = select(self.model).where(self.model.id == id)
|
||||
return db.execute(statement).scalar_one_or_none()
|
||||
|
||||
def get_multi(
|
||||
self, db: Session, *, skip: int = 0, limit: int = 100
|
||||
) -> List[ModelType]:
|
||||
return db.query(self.model).offset(skip).limit(limit).all()
|
||||
statement = select(self.model).offset(skip).limit(limit)
|
||||
return db.execute(statement).scalars().all()
|
||||
|
||||
def create(self, db: Session, *, obj_in: CreateSchemaType) -> ModelType:
|
||||
obj_in_data = jsonable_encoder(obj_in)
|
||||
|
|
@ -58,7 +61,7 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
|
|||
return db_obj
|
||||
|
||||
def remove(self, db: Session, *, id: int) -> ModelType:
|
||||
obj = db.query(self.model).get(id)
|
||||
obj = db.execute(self.model).get(id)
|
||||
db.delete(obj)
|
||||
db.commit()
|
||||
return obj
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
from typing import Any, Dict, Union, Optional
|
||||
|
||||
from sqlmodel import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.crud import player as crud_player
|
||||
from app.crud.base import CRUDBase
|
||||
from app.models.matchday import Matchday, MatchdayCreate, MatchdayUpdate
|
||||
|
||||
|
||||
class CRUDMatchday(CRUDBase[Matchday, MatchdayCreate, MatchdayUpdate]):
|
||||
|
||||
def create(self, db: Session, *, obj_in: MatchdayCreate) -> Matchday:
|
||||
db_obj = Matchday(
|
||||
day=obj_in.day)
|
||||
|
||||
db.add(db_obj)
|
||||
db.commit()
|
||||
db.refresh(db_obj)
|
||||
return db_obj
|
||||
|
||||
def get_unique_day(self, db: Session, *, obj_in: Matchday) -> Any:
|
||||
day = obj_in.day
|
||||
statement = select(Matchday).where(Matchday.day == day)
|
||||
result = db.execute(statement).all()
|
||||
return result
|
||||
|
||||
def add_player_in_matchday(self, db: Session, matchday_id: int, player_id: int
|
||||
) -> Matchday:
|
||||
matchday_in = self.get(db=db, id=matchday_id)
|
||||
db_player = crud_player.get(db=db, id=player_id)
|
||||
matchday_in.players.append(db_player)
|
||||
db.commit()
|
||||
return matchday_in
|
||||
|
||||
def is_player_in_matchday(
|
||||
self, db: Session, *, player_id: int, matchday_id: int
|
||||
) -> bool:
|
||||
matchday = self.get(db=db, id=matchday_id)
|
||||
if matchday is None:
|
||||
return False
|
||||
db_player = crud_player.get(db=db, id=player_id)
|
||||
return db_player in matchday.players
|
||||
|
||||
matchday = CRUDMatchday(Matchday)
|
||||
|
|
@ -3,8 +3,7 @@ from typing import Any, Dict, Optional, Union
|
|||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.crud.base import CRUDBase
|
||||
from app.models.player import Player
|
||||
from app.schemas.player import PlayerCreate, PlayerUpdate, PlayerUpdateTeam
|
||||
from app.models.player import Player, PlayerCreate, PlayerUpdate
|
||||
|
||||
|
||||
class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):
|
||||
|
|
@ -21,12 +20,6 @@ class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):
|
|||
.first()
|
||||
)
|
||||
|
||||
def get_player(self, db: Session, *, player_id: int) -> Optional[Player]:
|
||||
return db.query(Player).filter(Player.id == player_id).first()
|
||||
|
||||
def get_players(self, db: Session, skip: int = 0, limit: int = 100):
|
||||
return db.query(Player).offset(skip).limit(limit).all()
|
||||
|
||||
def create(self, db: Session, *, obj_in: PlayerCreate) -> Player:
|
||||
db_obj = Player(
|
||||
firstname=obj_in.firstname,
|
||||
|
|
@ -38,4 +31,5 @@ class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):
|
|||
return db_obj
|
||||
|
||||
|
||||
|
||||
player = CRUDPlayer(Player)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,14 @@
|
|||
from typing import Any, Dict, Optional, Union, List
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlmodel import select
|
||||
|
||||
from app.crud.base import CRUDBase
|
||||
from app.crud import player as crud_player
|
||||
from app.models.team import Team
|
||||
|
||||
from app.schemas.team import TeamCreate, TeamUpdate
|
||||
from app.models.team import Team, TeamCreate, TeamUpdate
|
||||
|
||||
|
||||
class CRUDTeam(CRUDBase[Team, TeamCreate, TeamUpdate]):
|
||||
def get_team(self, db: Session, *, team_id: int) -> Optional[Team]:
|
||||
return db.query(Team).filter(Team.team_id == team_id).first()
|
||||
|
||||
def get_teams(
|
||||
self, db: Session, skip: int = 0, limit: int = 100
|
||||
) -> List[Team]:
|
||||
return db.query(Team).offset(skip).limit(limit).all()
|
||||
|
||||
def create(self, db: Session, *, obj_in: TeamCreate) -> Team:
|
||||
db_obj = Team(teamname=obj_in.teamname)
|
||||
|
|
@ -28,19 +20,19 @@ class CRUDTeam(CRUDBase[Team, TeamCreate, TeamUpdate]):
|
|||
def add_player_in_team(
|
||||
self, db: Session, team_id: int, player_id: int
|
||||
) -> Team:
|
||||
team = self.get_team(db=db, team_id=team_id)
|
||||
db_player = crud_player.get_player(db=db, player_id=player_id)
|
||||
team.players.append(db_player)
|
||||
team_in = self.get(db=db, id=team_id)
|
||||
db_player = crud_player.get(db=db, id=player_id)
|
||||
team_in.players.append(db_player)
|
||||
db.commit()
|
||||
return team
|
||||
return team_in
|
||||
|
||||
def is_player_in_team(
|
||||
self, db: Session, *, player_id: int, team_id: int
|
||||
) -> bool:
|
||||
team = self.get_team(db=db, team_id=team_id)
|
||||
team = self.get(db=db, id=team_id)
|
||||
if team is None:
|
||||
return False
|
||||
db_player = crud_player.get_player(db=db, player_id=player_id)
|
||||
db_player = crud_player.get(db=db, id=player_id)
|
||||
return db_player in team.players
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ from sqlalchemy.orm import Session
|
|||
|
||||
from app.core.security import get_password_hash, verify_password
|
||||
from app.crud.base import CRUDBase
|
||||
from app.models.user import User
|
||||
from app.schemas.user import UserCreate, UserUpdate
|
||||
from app.models.user import User, UserCreate, UserUpdate
|
||||
|
||||
|
||||
|
||||
class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]):
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
from typing import Any
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy.ext.declarative import as_declarative, declared_attr
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from sqlmodel import Field, SQLModel
|
||||
|
||||
|
||||
@as_declarative()
|
||||
class Base:
|
||||
id: Any
|
||||
class Base(SQLModel):
|
||||
id: Optional[int] = Field(default=None, primary_key=True, index=True)
|
||||
__name__: str
|
||||
# Generate __tablename__ automatically
|
||||
@declared_attr
|
||||
def __tablename__(cls) -> str:
|
||||
return cls.__name__.lower()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from sqlalchemy.orm import Session
|
||||
|
||||
from app import crud, schemas
|
||||
from app import crud
|
||||
from app.core.config import settings
|
||||
from app.db import base # noqa: F401
|
||||
|
||||
|
|
@ -9,6 +9,9 @@ from app.db import base # noqa: F401
|
|||
# for more details: https://github.com/tiangolo/full-stack-fastapi-postgresql/issues/28
|
||||
from app.db.base_class import Base
|
||||
from app.db.session import engine
|
||||
from app.models.player import Player, PlayerCreate
|
||||
from app.models.team import TeamCreate, TeamWithPlayers
|
||||
from app.models.user import UserCreate
|
||||
|
||||
|
||||
def init_db(db: Session) -> None:
|
||||
|
|
@ -19,9 +22,34 @@ def init_db(db: Session) -> None:
|
|||
|
||||
user = crud.user.get_by_email(db, email=settings.FIRST_SUPERUSER)
|
||||
if not user:
|
||||
user_in = schemas.UserCreate(
|
||||
user_in = UserCreate(
|
||||
email=settings.FIRST_SUPERUSER,
|
||||
password=settings.FIRST_SUPERUSER_PASSWORD,
|
||||
is_superuser=True,
|
||||
)
|
||||
user = crud.user.create(db, obj_in=user_in) # noqa: F841
|
||||
|
||||
players = crud.player.get_multi(db=db)
|
||||
|
||||
if not players:
|
||||
|
||||
player_in = PlayerCreate(
|
||||
firstname="Simon",
|
||||
lastname="Milvert",
|
||||
)
|
||||
|
||||
player = crud.player.create(db=db, obj_in=player_in) # noqa: F841
|
||||
player_in = PlayerCreate(
|
||||
firstname="Johan",
|
||||
lastname="Moden")
|
||||
|
||||
|
||||
player = crud.player.create(db=db, obj_in=player_in) # noqa: F841
|
||||
|
||||
teams = crud.team.get_multi(db=db)
|
||||
|
||||
if not True:
|
||||
print("Create Team")
|
||||
player = crud.player.get(db, id=1)
|
||||
team_in = TeamWithPlayers(teamname='1', players=[player])
|
||||
team = crud.team.create(db, obj_in=team_in) # noqa: F841
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
from sqlalchemy import create_engine
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from app.core.config import settings
|
||||
|
||||
from sqlmodel import create_engine, SQLModel
|
||||
|
||||
engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
|
||||
def create_db_and_tables():
|
||||
SQLModel.metadata.create_all(engine)
|
||||
|
||||
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
|
|
|||
13
app/main.py
13
app/main.py
|
|
@ -1,12 +1,18 @@
|
|||
import logging
|
||||
|
||||
import uvicorn
|
||||
from fastapi import FastAPI
|
||||
from loguru import logger
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
|
||||
from app.api.api_v1.api import api_router
|
||||
from app.core.config import settings
|
||||
from app.db.init_db import init_db
|
||||
from app.db.session import SessionLocal
|
||||
from app.db.session import SessionLocal, create_db_and_tables
|
||||
from app.utils import configure_log_handler
|
||||
|
||||
db = SessionLocal()
|
||||
configure_log_handler(log_level=logging.DEBUG)
|
||||
init_db(db)
|
||||
|
||||
|
||||
|
|
@ -14,6 +20,10 @@ app = FastAPI(
|
|||
title=settings.PROJECT_NAME,
|
||||
openapi_url=f"{settings.API_V1_STR}/openapi.json",
|
||||
)
|
||||
@app.on_event("startup")
|
||||
def on_startup():
|
||||
create_db_and_tables()
|
||||
|
||||
|
||||
# Set all CORS enabled origins
|
||||
if settings.BACKEND_CORS_ORIGINS:
|
||||
|
|
@ -28,3 +38,4 @@ if settings.BACKEND_CORS_ORIGINS:
|
|||
)
|
||||
|
||||
app.include_router(api_router, prefix=settings.API_V1_STR)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
# from .match import Match
|
||||
# from .matchday import Matchday
|
||||
from .player import Player
|
||||
from .team import Team
|
||||
from .user import User
|
||||
from app.models.matchday import Matchday, MatchdayWithPlayers
|
||||
from app.models.player import Player, PlayerTeamsMatchdays
|
||||
from app.models.team import Team, TeamWithPlayers
|
||||
|
||||
|
||||
Player.update_forward_refs(Team=Team, Matchday=Matchday)
|
||||
PlayerTeamsMatchdays.update_forward_refs(Team=Team, Matchday=Matchday)
|
||||
|
||||
Team.update_forward_refs(Player=Player)
|
||||
TeamWithPlayers.update_forward_refs(Player=Player)
|
||||
|
||||
Matchday.update_forward_refs(Player=Player)
|
||||
MatchdayWithPlayers.update_forward_refs(Player=Player)
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
from sqlalchemy import Column, DateTime, ForeignKey, Integer, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from typing import Optional
|
||||
|
||||
from app.db.database import Base
|
||||
from sqlmodel import SQLModel, Field
|
||||
|
||||
from app.db.base_class import Base
|
||||
|
||||
|
||||
class Match(Base):
|
||||
class Match(SQLModel, Base, table=True):
|
||||
matchname: Optional[str] = Field(nullable=False)
|
||||
|
||||
"""
|
||||
match_id = Column(Integer, primary_key=True)
|
||||
team_1 = Column(ForeignKey("team.id"), nullable=False)
|
||||
team_2 = Column(ForeignKey("team.id"), nullable=False)
|
||||
|
|
@ -18,3 +21,4 @@ class Match(Base):
|
|||
team = relationship("Team", primaryjoin="Match.team_1 == Team.team_id")
|
||||
team1 = relationship("Team", primaryjoin="Match.team_2 == Team.team_id")
|
||||
team2 = relationship("Team", primaryjoin="Match.winner == Team.team_id")
|
||||
"""
|
||||
|
|
@ -1,17 +1,36 @@
|
|||
from sqlalchemy import Column, DateTime, ForeignKey, Integer, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from datetime import date, datetime
|
||||
from typing import List, Optional, TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import Date
|
||||
from sqlmodel import SQLModel, Relationship, Field, Column, func
|
||||
|
||||
from app.db.base_class import Base
|
||||
from app.models.matchdayplayer import MatchdayPlayerLink
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.models.player import Player
|
||||
|
||||
|
||||
class MatchdayPlayer(Base):
|
||||
|
||||
player_id = Column("players_id", ForeignKey("players.id"), primary_key=True)
|
||||
matchday_id = Column("teams_id", ForeignKey("teams.id"), primary_key=True)
|
||||
class MatchdayBase(SQLModel):
|
||||
day: date
|
||||
|
||||
|
||||
class Matchday(Base):
|
||||
class Matchday(MatchdayBase, Base, table=True):
|
||||
day: date = Field(
|
||||
default=None,
|
||||
sa_column=Column(Date, server_default=func.now()))
|
||||
players: List["Player"] = Relationship(back_populates="matchdays",
|
||||
link_model=MatchdayPlayerLink)
|
||||
|
||||
matchday_id = Column(Integer, primary_key=True)
|
||||
day = Column(DateTime, nullable=False)
|
||||
players = relationship("Player", secondary="matchdayplayer")
|
||||
|
||||
class MatchdayCreate(MatchdayBase):
|
||||
day: date
|
||||
|
||||
|
||||
class MatchdayUpdate(MatchdayBase):
|
||||
day: date
|
||||
|
||||
|
||||
class MatchdayWithPlayers(MatchdayBase):
|
||||
day: date
|
||||
players: Optional[List["Player"]]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
from typing import Optional
|
||||
from sqlmodel import SQLModel, Field
|
||||
|
||||
class MatchdayPlayerLink(SQLModel, table=True):
|
||||
|
||||
player_id: Optional[int] = Field(
|
||||
default=None, foreign_key="player.id", primary_key=True
|
||||
)
|
||||
matchday_id: Optional[int] = Field(
|
||||
default=None, foreign_key="matchday.id", primary_key=True
|
||||
)
|
||||
|
|
@ -1,16 +1,35 @@
|
|||
from sqlalchemy import Column, Integer, String, ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from typing import Optional, List, TYPE_CHECKING
|
||||
|
||||
from sqlmodel import SQLModel, Field, Relationship
|
||||
from app.db.base_class import Base
|
||||
|
||||
from app.models.matchdayplayer import MatchdayPlayerLink
|
||||
from app.models.teamplayers import TeamPlayerLink
|
||||
|
||||
class Player(Base):
|
||||
if TYPE_CHECKING:
|
||||
from app.models import Team, Matchday
|
||||
class PlayerBase(SQLModel):
|
||||
firstname: str = Field(nullable=False)
|
||||
lastname: str = Field(nullable=False)
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
firstname = Column(String, nullable=True)
|
||||
lastname = Column(String, nullable=True)
|
||||
team_id = Column(Integer, ForeignKey("team.team_id"))
|
||||
team = relationship("Team", back_populates="players")
|
||||
|
||||
team_id = Column(Integer, ForeignKey("team.team_id"))
|
||||
team = relationship("Team", back_populates="players")
|
||||
class Player(PlayerBase, Base, table=True):
|
||||
teams: List["Team"] = Relationship(back_populates="players",
|
||||
link_model=TeamPlayerLink)
|
||||
matchdays: List["Matchday"] = Relationship(back_populates="players",
|
||||
link_model=MatchdayPlayerLink)
|
||||
|
||||
|
||||
class PlayerCreate(PlayerBase):
|
||||
firstname: str
|
||||
lastname: str
|
||||
|
||||
|
||||
class PlayerUpdate(PlayerBase):
|
||||
firstname: str
|
||||
lastname: str
|
||||
|
||||
class PlayerTeamsMatchdays(PlayerBase):
|
||||
matchdays: List["Matchday"]
|
||||
teams: List["Team"]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,34 @@
|
|||
from sqlalchemy import Column, DateTime, ForeignKey, Integer, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from typing import Optional, List, TYPE_CHECKING
|
||||
|
||||
from sqlmodel import SQLModel, Field, Relationship
|
||||
|
||||
from app.db.base_class import Base
|
||||
|
||||
from app.models.teamplayers import TeamPlayerLink
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.models.player import Player
|
||||
|
||||
class TeamBase(SQLModel):
|
||||
teamname: Optional[str] = Field(nullable=False)
|
||||
|
||||
|
||||
class Team(TeamBase, Base, table=True):
|
||||
players: List["Player"] = Relationship(back_populates="teams",
|
||||
link_model=TeamPlayerLink
|
||||
)
|
||||
|
||||
|
||||
class TeamCreate(TeamBase):
|
||||
teamname: str
|
||||
|
||||
|
||||
class TeamWithPlayers(TeamBase):
|
||||
teamname: str
|
||||
players: List["Player"]
|
||||
|
||||
|
||||
class TeamUpdate(TeamBase):
|
||||
teamname: str
|
||||
|
||||
class Team(Base):
|
||||
|
||||
team_id = Column(Integer, primary_key=True, index=True)
|
||||
teamname = Column(String, nullable=False)
|
||||
players = relationship("Player", back_populates="team")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
from typing import Optional
|
||||
|
||||
from sqlmodel import SQLModel, Field, Relationship
|
||||
|
||||
|
||||
class TeamPlayerLink(SQLModel, table=True):
|
||||
team_id: Optional[int] = Field(
|
||||
default=None, foreign_key="team.id", primary_key=True
|
||||
)
|
||||
player_id: Optional[int] = Field(
|
||||
default=None, foreign_key="player.id", primary_key=True
|
||||
)
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class Token(BaseModel):
|
||||
access_token: str
|
||||
token_type: str
|
||||
|
|
@ -1,12 +1,29 @@
|
|||
from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Boolean
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import EmailStr
|
||||
from sqlmodel import SQLModel, Field
|
||||
from app.db.base_class import Base
|
||||
|
||||
|
||||
class User(Base):
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
full_name = Column(String, index=True)
|
||||
email = Column(String, unique=True, index=True, nullable=False)
|
||||
hashed_password = Column(String, nullable=False)
|
||||
is_active = Column(Boolean(), default=True)
|
||||
is_superuser = Column(Boolean(), default=False)
|
||||
class UserBase(SQLModel):
|
||||
|
||||
full_name: Optional[str] = Field(index=True)
|
||||
email: Optional[EmailStr] = Field(unique=True, index=True, nullable=False)
|
||||
hashed_password: Optional[str] = Field(nullable=False)
|
||||
is_active: Optional[bool] = Field(default=True)
|
||||
is_superuser: bool = Field(default=False)
|
||||
|
||||
|
||||
class User(UserBase, Base, table=True):
|
||||
pass
|
||||
|
||||
|
||||
class UserCreate(UserBase):
|
||||
email: EmailStr
|
||||
password: str
|
||||
|
||||
|
||||
# Properties to receive via API on update
|
||||
class UserUpdate(UserBase):
|
||||
password: Optional[str] = None
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from .user import User, UserCreate, UserInDB, UserUpdate
|
||||
from .token import Token, TokenPayload
|
||||
from .msg import Msg
|
||||
from .player import Player, PlayerCreate, PlayerInDB
|
||||
from .team import Team, TeamCreate, TeamInDBBase
|
||||
#from .user import User, UserCreate, UserInDB, UserUpdate
|
||||
#from .player import Player, PlayerCreate, PlayerInDB
|
||||
#from .team import Team, TeamCreate, TeamInDBBase
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, EmailStr
|
||||
|
||||
|
||||
# Shared properties
|
||||
class PlayerBase(BaseModel):
|
||||
firstname: Optional[str] = None
|
||||
lastname: Optional[str] = None
|
||||
|
||||
|
||||
# Properties to receive via API on creation
|
||||
class PlayerCreate(PlayerBase):
|
||||
firstname: str
|
||||
lastname: str
|
||||
|
||||
|
||||
class PlayerInDBBase(PlayerBase):
|
||||
id: Optional[int] = None
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class PlayerUpdate(PlayerBase):
|
||||
firstname: str
|
||||
lastname: str
|
||||
|
||||
|
||||
class PlayerUpdateTeam(PlayerBase):
|
||||
team_id: Optional[int]
|
||||
|
||||
|
||||
# Additional properties to return via API
|
||||
class Player(PlayerInDBBase):
|
||||
pass
|
||||
|
||||
|
||||
# Additional properties stored in DB
|
||||
class PlayerInDB(PlayerInDBBase):
|
||||
pass
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
# Shared properties
|
||||
from app.schemas import Player
|
||||
|
||||
|
||||
class TeamBase(BaseModel):
|
||||
teamname: Optional[str] = None
|
||||
|
||||
|
||||
# Properties to receive via API on creation
|
||||
class TeamCreate(TeamBase):
|
||||
teamname: Optional[str]
|
||||
|
||||
|
||||
class TeamInDBBase(TeamBase):
|
||||
players: list[Player] = []
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class TeamUpdate(TeamBase):
|
||||
pass
|
||||
|
||||
|
||||
# Additional properties to return via API
|
||||
class Team(TeamInDBBase):
|
||||
|
||||
team_id: Optional[int] = None
|
||||
players: list[Player] = []
|
||||
|
||||
|
||||
# Additional properties stored in DB
|
||||
class TeamInDB(TeamInDBBase):
|
||||
pass
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, EmailStr
|
||||
|
||||
|
||||
# Shared properties
|
||||
class UserBase(BaseModel):
|
||||
email: Optional[EmailStr] = None
|
||||
is_active: Optional[bool] = True
|
||||
is_superuser: bool = False
|
||||
full_name: Optional[str] = None
|
||||
|
||||
|
||||
# Properties to receive via API on creation
|
||||
class UserCreate(UserBase):
|
||||
email: EmailStr
|
||||
password: str
|
||||
|
||||
|
||||
# Properties to receive via API on update
|
||||
class UserUpdate(UserBase):
|
||||
password: Optional[str] = None
|
||||
|
||||
|
||||
class UserInDBBase(UserBase):
|
||||
id: Optional[int] = None
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
# Additional properties to return via API
|
||||
class User(UserInDBBase):
|
||||
pass
|
||||
|
||||
|
||||
# Additional properties stored in DB
|
||||
class UserInDB(UserInDBBase):
|
||||
hashed_password: str
|
||||
38
app/utils.py
38
app/utils.py
|
|
@ -8,6 +8,44 @@ from emails.template import JinjaTemplate
|
|||
from jose import jwt
|
||||
|
||||
from app.core.config import settings
|
||||
import sys
|
||||
import logging
|
||||
from loguru import logger
|
||||
|
||||
logger.remove()
|
||||
logger.add(
|
||||
sys.stdout,
|
||||
format="<green>{time:YYYY/MM/DD HH:mm:ss}</green> <level>{level: <5} <cyan>{name}</cyan> {message}</level>",
|
||||
level="DEBUG",
|
||||
)
|
||||
|
||||
|
||||
class InterceptHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
# Get corresponding Loguru level if it exists.
|
||||
try:
|
||||
level = logger.level(record.levelname).name
|
||||
except ValueError:
|
||||
level = record.levelno
|
||||
|
||||
# Find caller from where originated the logged message.
|
||||
frame, depth = sys._getframe(6), 6
|
||||
while frame and frame.f_code.co_filename == logging.__file__:
|
||||
frame = frame.f_back
|
||||
depth += 1
|
||||
|
||||
logger.opt(
|
||||
depth=depth, exception=record.exc_info
|
||||
).log(
|
||||
"DEBUG", record.getMessage()
|
||||
)
|
||||
|
||||
|
||||
def configure_log_handler(*, log_level=logging.WARNING):
|
||||
logging.basicConfig(handlers=[InterceptHandler()],
|
||||
level=logging.NOTSET, force=True)
|
||||
for target in ['sqlalchemy.engine.Engine', 'sqlalchemy.engine']:
|
||||
logging.getLogger(target).setLevel(log_level)
|
||||
|
||||
|
||||
def send_email(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import uvicorn
|
||||
from loguru import logger
|
||||
|
||||
from app.main import app
|
||||
|
||||
|
||||
def main():
|
||||
uvicorn.run("debug_run:app", host="0.0.0.0", port=1234, reload=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("begin")
|
||||
main()
|
||||
logger.info("done")
|
||||
BIN
floorball.db
BIN
floorball.db
Binary file not shown.
|
|
@ -383,6 +383,21 @@ category = "dev"
|
|||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "loguru"
|
||||
version = "0.6.0"
|
||||
description = "Python logging made (stupidly) simple"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
|
||||
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "lxml"
|
||||
version = "4.9.1"
|
||||
|
|
@ -754,6 +769,30 @@ postgresql_psycopg2cffi = ["psycopg2cffi"]
|
|||
pymysql = ["pymysql", "pymysql (<1)"]
|
||||
sqlcipher = ["sqlcipher3-binary"]
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy2-stubs"
|
||||
version = "0.0.2a27"
|
||||
description = "Typing Stubs for SQLAlchemy 1.4"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = ">=3.7.4"
|
||||
|
||||
[[package]]
|
||||
name = "sqlmodel"
|
||||
version = "0.0.8"
|
||||
description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.1,<4.0.0"
|
||||
|
||||
[package.dependencies]
|
||||
pydantic = ">=1.8.2,<2.0.0"
|
||||
SQLAlchemy = ">=1.4.17,<=1.4.41"
|
||||
sqlalchemy2-stubs = "*"
|
||||
|
||||
[[package]]
|
||||
name = "starlette"
|
||||
version = "0.19.1"
|
||||
|
|
@ -868,6 +907,17 @@ platformdirs = ">=2.4,<3"
|
|||
docs = ["proselint (>=0.13)", "sphinx (>=5.1.1)", "sphinx-argparse (>=0.3.1)", "sphinx-rtd-theme (>=1)", "towncrier (>=21.9)"]
|
||||
testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "win32-setctime"
|
||||
version = "1.1.0"
|
||||
description = "A small Python utility to set file creation time on Windows"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.extras]
|
||||
dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "wrapt"
|
||||
version = "1.14.1"
|
||||
|
|
@ -879,7 +929,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "875e82447867f92eb96260ad048da2e4967d2c8285ecaac9dca37dd839d7d78f"
|
||||
content-hash = "f51b93ad173b06640d39b5143150dd0219b20bfcd5c3c9a0a4036b5638d12925"
|
||||
|
||||
[metadata.files]
|
||||
anyio = [
|
||||
|
|
@ -1257,6 +1307,10 @@ lazy-object-proxy = [
|
|||
{file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"},
|
||||
{file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"},
|
||||
]
|
||||
loguru = [
|
||||
{file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
|
||||
{file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
|
||||
]
|
||||
lxml = [
|
||||
{file = "lxml-4.9.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc"},
|
||||
|
|
@ -1536,6 +1590,14 @@ sqlalchemy = [
|
|||
{file = "SQLAlchemy-1.4.40-cp39-cp39-win_amd64.whl", hash = "sha256:bf073c619b5a7f7cd731507d0fdc7329bee14b247a63b0419929e4acd24afea8"},
|
||||
{file = "SQLAlchemy-1.4.40.tar.gz", hash = "sha256:44a660506080cc975e1dfa5776fe5f6315ddc626a77b50bf0eee18b0389ea265"},
|
||||
]
|
||||
sqlalchemy2-stubs = [
|
||||
{file = "sqlalchemy2-stubs-0.0.2a27.tar.gz", hash = "sha256:f79bce50b7837a2c2374ef4480b41e2b8a8226f313f347dc2a70526a4191db93"},
|
||||
{file = "sqlalchemy2_stubs-0.0.2a27-py3-none-any.whl", hash = "sha256:6cea12fec3c261f6e0e14a95d2cc4914e373095e68ec4fc2eb473183ac2b17a2"},
|
||||
]
|
||||
sqlmodel = [
|
||||
{file = "sqlmodel-0.0.8-py3-none-any.whl", hash = "sha256:0fd805719e0c5d4f22be32eb3ffc856eca3f7f20e8c7aa3e117ad91684b518ee"},
|
||||
{file = "sqlmodel-0.0.8.tar.gz", hash = "sha256:3371b4d1ad59d2ffd0c530582c2140b6c06b090b32af9b9c6412986d7b117036"},
|
||||
]
|
||||
starlette = [
|
||||
{file = "starlette-0.19.1-py3-none-any.whl", hash = "sha256:5a60c5c2d051f3a8eb546136aa0c9399773a689595e099e0877704d5888279bf"},
|
||||
{file = "starlette-0.19.1.tar.gz", hash = "sha256:c6d21096774ecb9639acad41b86b7706e52ba3bf1dc13ea4ed9ad593d47e24c7"},
|
||||
|
|
@ -1572,6 +1634,10 @@ virtualenv = [
|
|||
{file = "virtualenv-20.16.3-py2.py3-none-any.whl", hash = "sha256:4193b7bc8a6cd23e4eb251ac64f29b4398ab2c233531e66e40b19a6b7b0d30c1"},
|
||||
{file = "virtualenv-20.16.3.tar.gz", hash = "sha256:d86ea0bb50e06252d79e6c241507cb904fcd66090c3271381372d6221a3970f9"},
|
||||
]
|
||||
win32-setctime = [
|
||||
{file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
|
||||
{file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
|
||||
]
|
||||
wrapt = [
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
|
||||
{file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"},
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ python-jose = {extras = ["cryptography"], version = "^3.3.0"}
|
|||
pydantic = {extras = ["email"], version = "^1.10.0"}
|
||||
python-multipart = "^0.0.5"
|
||||
emails = "^0.6"
|
||||
sqlmodel = "^0.0.8"
|
||||
loguru = "^0.6.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^7.1.2"
|
||||
|
|
@ -30,6 +32,8 @@ isort = "^5.10.1"
|
|||
line-length = 79
|
||||
target-version = [ "py39",]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
web = "app.main:"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
|
|
|
|||
Loading…
Reference in New Issue