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 login
|
||||||
from app.api.api_v1.endpoints import player
|
from app.api.api_v1.endpoints import player
|
||||||
from app.api.api_v1.endpoints import team
|
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 = APIRouter()
|
||||||
api_router.include_router(login.router, tags=["login"])
|
api_router.include_router(login.router, tags=["login"])
|
||||||
api_router.include_router(users.router, prefix="/users", tags=["users"])
|
api_router.include_router(users.router, prefix="/users", tags=["users"])
|
||||||
api_router.include_router(player.router, prefix="/player", tags=["player"])
|
api_router.include_router(player.router, prefix="/player", tags=["player"])
|
||||||
api_router.include_router(team.router, prefix="/team", tags=["team"])
|
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 fastapi.security import OAuth2PasswordRequestForm
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app import crud, models, schemas
|
from app import crud
|
||||||
from app.api import deps
|
from app.api import deps
|
||||||
from app.core import security
|
from app.core import security
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.core.security import get_password_hash
|
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 (
|
from app.utils import (
|
||||||
generate_password_reset_token,
|
generate_password_reset_token,
|
||||||
send_reset_password_email,
|
send_reset_password_email,
|
||||||
|
|
@ -19,7 +22,7 @@ from app.utils import (
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/login/access-token", response_model=schemas.Token)
|
@router.post("/login/access-token", response_model=Token)
|
||||||
def login_access_token(
|
def login_access_token(
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
form_data: OAuth2PasswordRequestForm = Depends(),
|
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(
|
def test_token(
|
||||||
current_user: models.User = Depends(deps.get_current_user),
|
current_user: User = Depends(deps.get_current_user),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Test access token
|
Test access token
|
||||||
|
|
@ -57,7 +60,7 @@ def test_token(
|
||||||
return current_user
|
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:
|
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
|
||||||
"""
|
"""
|
||||||
Password Recovery
|
Password Recovery
|
||||||
|
|
@ -76,7 +79,7 @@ def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
|
||||||
return {"msg": "Password recovery email sent"}
|
return {"msg": "Password recovery email sent"}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/reset-password/", response_model=schemas.Msg)
|
@router.post("/reset-password/", response_model=Msg)
|
||||||
def reset_password(
|
def reset_password(
|
||||||
token: str = Body(...),
|
token: str = Body(...),
|
||||||
new_password: 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 typing import Any, List
|
||||||
|
|
||||||
from fastapi import APIRouter, Body, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from fastapi.encoders import jsonable_encoder
|
|
||||||
from pydantic.networks import EmailStr
|
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app import crud, models, schemas
|
from app import crud
|
||||||
from app.api import deps
|
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 = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{id}", response_model=schemas.Player)
|
@router.get("/{player_id}", response_model=PlayerTeamsMatchdays)
|
||||||
def read_player(
|
def read_player(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
firstname: str,
|
player_id: int,
|
||||||
lastname: str,
|
current_user: User = Depends(deps.get_current_active_user),
|
||||||
current_user: models.User = Depends(deps.get_current_active_user),
|
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Get player by firstname and lastname.
|
Get player by id.
|
||||||
"""
|
"""
|
||||||
player = crud.player.get_player_by_name(
|
player = crud.player.get(
|
||||||
db=db, firstname=firstname, lastname=lastname
|
db=db, id=player_id
|
||||||
)
|
)
|
||||||
if not player:
|
if not player:
|
||||||
raise HTTPException(status_code=404, detail="player not found")
|
raise HTTPException(status_code=404, detail="player not found")
|
||||||
|
|
@ -34,56 +33,60 @@ def read_player(
|
||||||
return player
|
return player
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", response_model=schemas.Player)
|
@router.post("/", response_model=List[Player])
|
||||||
def create_player(
|
def create_player(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
player_in: schemas.PlayerCreate,
|
players_in: list[PlayerCreate],
|
||||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
current_user: User = Depends(deps.get_current_active_superuser),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Create new user.
|
Create new user.
|
||||||
"""
|
"""
|
||||||
player = crud.player.get_player_by_name(
|
player_out = []
|
||||||
db, firstname=player_in.firstname, lastname=player_in.lastname
|
for player_in in players_in:
|
||||||
)
|
player = crud.player.get_player_by_name(
|
||||||
if player:
|
db, firstname=player_in.firstname, lastname=player_in.lastname
|
||||||
raise HTTPException(
|
|
||||||
status_code=400,
|
|
||||||
detail="The user with this username already exists in the system.",
|
|
||||||
)
|
)
|
||||||
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(
|
def get_players(
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
current_user: User = Depends(deps.get_current_active_superuser),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Retrieve all players.
|
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
|
return player
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{id}", response_model=schemas.Player)
|
@router.post("/{player_id}", response_model=Player)
|
||||||
def update_player(
|
def update_player(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
id: int,
|
player_id: int,
|
||||||
player_in: PlayerUpdate,
|
player_in: PlayerUpdate,
|
||||||
current_user: models.User = Depends(deps.get_current_active_user),
|
current_user: User = Depends(deps.get_current_active_user),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Update player.
|
Update player.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
player = crud.player.get(db=db, id=id)
|
player = crud.player.get(db=db, id=player_id)
|
||||||
if not player:
|
if not player:
|
||||||
raise HTTPException(status_code=404, detail="Player not found")
|
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 sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app import crud, models, schemas
|
from app import crud
|
||||||
from app.api import deps
|
from app.api import deps
|
||||||
|
from app.models.team import Team, TeamCreate, TeamWithPlayers
|
||||||
|
from app.models.user import User
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{id}", response_model=schemas.Team)
|
@router.get("/{team_id}", response_model=Team)
|
||||||
def get_team(
|
def get_team(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
id: int,
|
team_id: int,
|
||||||
current_user: models.User = Depends(deps.get_current_active_user),
|
current_user: User = Depends(deps.get_current_active_user),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Get team by id.
|
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:
|
if not team:
|
||||||
raise HTTPException(status_code=404, detail="player not found")
|
raise HTTPException(status_code=404, detail="player not found")
|
||||||
if not crud.user.is_superuser(current_user):
|
if not crud.user.is_superuser(current_user):
|
||||||
|
|
@ -29,26 +30,26 @@ def get_team(
|
||||||
return team
|
return team
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[schemas.Team])
|
@router.get("/", response_model=List[TeamWithPlayers])
|
||||||
def get_teams(
|
def get_teams(
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
current_user: User = Depends(deps.get_current_active_superuser),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Retrieve teams.
|
Retrieve teams.
|
||||||
"""
|
"""
|
||||||
team = crud.team.get_teams(db, skip=skip, limit=limit)
|
team = crud.team.get_multi( db, skip=skip, limit=limit)
|
||||||
return team
|
return team
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", response_model=schemas.Team)
|
@router.post("/", response_model=Team)
|
||||||
def create_team(
|
def create_team(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
team_in: schemas.TeamCreate,
|
team_in: TeamCreate,
|
||||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
current_user: User = Depends(deps.get_current_active_superuser),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Create team.
|
Create team.
|
||||||
|
|
@ -59,20 +60,20 @@ def create_team(
|
||||||
return team
|
return team
|
||||||
|
|
||||||
|
|
||||||
@router.put("/players/{team_id}", response_model=schemas.Team)
|
@router.put("/players/{team_id}", response_model=Team)
|
||||||
def add_player_team(
|
def add_player_team(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
player_id: int,
|
player_id: int,
|
||||||
team_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:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Add player to team.
|
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")
|
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")
|
raise HTTPException(status_code=404, detail="Team not found")
|
||||||
if crud.team.is_player_in_team(
|
if crud.team.is_player_in_team(
|
||||||
db=db, player_id=player_id, team_id=team_id
|
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 pydantic.networks import EmailStr
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app import crud, models, schemas
|
from app import crud, models
|
||||||
from app.api import deps
|
from app.api import deps
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
|
from app.models.user import UserUpdate, User, UserCreate
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[schemas.User])
|
@router.get("/", response_model=List[User])
|
||||||
def read_users(
|
def read_users(
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
skip: int = 0,
|
skip: int = 0,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
current_user: User = Depends(deps.get_current_active_superuser),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Retrieve users.
|
Retrieve users.
|
||||||
|
|
@ -27,12 +27,12 @@ def read_users(
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", response_model=schemas.User)
|
@router.post("/", response_model=User)
|
||||||
def create_user(
|
def create_user(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
user_in: schemas.UserCreate,
|
user_in: UserCreate,
|
||||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
current_user: User = Depends(deps.get_current_active_superuser),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Create new user.
|
Create new user.
|
||||||
|
|
@ -48,20 +48,20 @@ def create_user(
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
@router.put("/me", response_model=schemas.User)
|
@router.put("/me", response_model=User)
|
||||||
def update_user_me(
|
def update_user_me(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
password: str = Body(None),
|
password: str = Body(None),
|
||||||
full_name: str = Body(None),
|
full_name: str = Body(None),
|
||||||
email: EmailStr = 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:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Update own user.
|
Update own user.
|
||||||
"""
|
"""
|
||||||
current_user_data = jsonable_encoder(current_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:
|
if password is not None:
|
||||||
user_in.password = password
|
user_in.password = password
|
||||||
if full_name is not None:
|
if full_name is not None:
|
||||||
|
|
@ -72,10 +72,10 @@ def update_user_me(
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
@router.get("/me", response_model=schemas.User)
|
@router.get("/me", response_model=User)
|
||||||
def read_user_me(
|
def read_user_me(
|
||||||
db: Session = Depends(deps.get_db),
|
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:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Get current user.
|
Get current user.
|
||||||
|
|
@ -83,7 +83,7 @@ def read_user_me(
|
||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
@router.post("/open", response_model=schemas.User)
|
@router.post("/open", response_model=User)
|
||||||
def create_user_open(
|
def create_user_open(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
|
|
@ -105,17 +105,17 @@ def create_user_open(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
detail="The user with this username already exists in the system",
|
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
|
password=password, email=email, full_name=full_name
|
||||||
)
|
)
|
||||||
user = crud.user.create(db, obj_in=user_in)
|
user = crud.user.create(db, obj_in=user_in)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{user_id}", response_model=schemas.User)
|
@router.get("/{user_id}", response_model=User)
|
||||||
def read_user_by_id(
|
def read_user_by_id(
|
||||||
user_id: int,
|
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),
|
db: Session = Depends(deps.get_db),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
|
|
@ -131,13 +131,13 @@ def read_user_by_id(
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{user_id}", response_model=schemas.User)
|
@router.put("/{user_id}", response_model=User)
|
||||||
def update_user(
|
def update_user(
|
||||||
*,
|
*,
|
||||||
db: Session = Depends(deps.get_db),
|
db: Session = Depends(deps.get_db),
|
||||||
user_id: int,
|
user_id: int,
|
||||||
user_in: schemas.UserUpdate,
|
user_in: UserUpdate,
|
||||||
current_user: models.User = Depends(deps.get_current_active_superuser),
|
current_user: User = Depends(deps.get_current_active_superuser),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Update a user.
|
Update a user.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ from jose import jwt
|
||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
from sqlalchemy.orm import Session
|
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 import security
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.db.session import SessionLocal
|
from app.db.session import SessionLocal
|
||||||
|
|
@ -26,12 +28,12 @@ def get_db() -> Generator:
|
||||||
|
|
||||||
def get_current_user(
|
def get_current_user(
|
||||||
db: Session = Depends(get_db), token: str = Depends(reusable_oauth2)
|
db: Session = Depends(get_db), token: str = Depends(reusable_oauth2)
|
||||||
) -> models.User:
|
) -> User:
|
||||||
try:
|
try:
|
||||||
payload = jwt.decode(
|
payload = jwt.decode(
|
||||||
token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
|
token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
|
||||||
)
|
)
|
||||||
token_data = schemas.TokenPayload(**payload)
|
token_data = TokenPayload(**payload)
|
||||||
except (jwt.JWTError, ValidationError):
|
except (jwt.JWTError, ValidationError):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
|
@ -44,16 +46,17 @@ def get_current_user(
|
||||||
|
|
||||||
|
|
||||||
def get_current_active_user(
|
def get_current_active_user(
|
||||||
current_user: models.User = Depends(get_current_user),
|
current_user: User = Depends(get_current_user),
|
||||||
) -> models.User:
|
) -> User:
|
||||||
if not crud.user.is_active(current_user):
|
if not crud.user.is_active(current_user):
|
||||||
raise HTTPException(status_code=400, detail="Inactive user")
|
raise HTTPException(status_code=400, detail="Inactive user")
|
||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
def get_current_active_superuser(
|
def get_current_active_superuser(
|
||||||
current_user: models.User = Depends(get_current_user),
|
current_user: User = Depends(get_current_user),
|
||||||
) -> models.User:
|
) -> User:
|
||||||
|
|
||||||
if not crud.user.is_superuser(current_user):
|
if not crud.user.is_superuser(current_user):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=400, detail="The user doesn't have enough privileges"
|
status_code=400, detail="The user doesn't have enough privileges"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
from .crud_user import user
|
from .crud_user import user
|
||||||
from .crud_player import player
|
from .crud_player import player
|
||||||
from .crud_team import team
|
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 fastapi.encoders import jsonable_encoder
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlmodel import select
|
||||||
|
|
||||||
from app.db.base_class import Base
|
from app.db.base_class import Base
|
||||||
|
|
||||||
|
|
@ -22,12 +23,14 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
|
||||||
self.model = model
|
self.model = model
|
||||||
|
|
||||||
def get(self, db: Session, id: Any) -> Optional[ModelType]:
|
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(
|
def get_multi(
|
||||||
self, db: Session, *, skip: int = 0, limit: int = 100
|
self, db: Session, *, skip: int = 0, limit: int = 100
|
||||||
) -> List[ModelType]:
|
) -> 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:
|
def create(self, db: Session, *, obj_in: CreateSchemaType) -> ModelType:
|
||||||
obj_in_data = jsonable_encoder(obj_in)
|
obj_in_data = jsonable_encoder(obj_in)
|
||||||
|
|
@ -58,7 +61,7 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
|
||||||
return db_obj
|
return db_obj
|
||||||
|
|
||||||
def remove(self, db: Session, *, id: int) -> ModelType:
|
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.delete(obj)
|
||||||
db.commit()
|
db.commit()
|
||||||
return obj
|
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 sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.crud.base import CRUDBase
|
from app.crud.base import CRUDBase
|
||||||
from app.models.player import Player
|
from app.models.player import Player, PlayerCreate, PlayerUpdate
|
||||||
from app.schemas.player import PlayerCreate, PlayerUpdate, PlayerUpdateTeam
|
|
||||||
|
|
||||||
|
|
||||||
class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):
|
class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):
|
||||||
|
|
@ -21,12 +20,6 @@ class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):
|
||||||
.first()
|
.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:
|
def create(self, db: Session, *, obj_in: PlayerCreate) -> Player:
|
||||||
db_obj = Player(
|
db_obj = Player(
|
||||||
firstname=obj_in.firstname,
|
firstname=obj_in.firstname,
|
||||||
|
|
@ -38,4 +31,5 @@ class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):
|
||||||
return db_obj
|
return db_obj
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
player = CRUDPlayer(Player)
|
player = CRUDPlayer(Player)
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,14 @@
|
||||||
from typing import Any, Dict, Optional, Union, List
|
from typing import Any, Dict, Optional, Union, List
|
||||||
|
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlmodel import select
|
||||||
|
|
||||||
from app.crud.base import CRUDBase
|
from app.crud.base import CRUDBase
|
||||||
from app.crud import player as crud_player
|
from app.crud import player as crud_player
|
||||||
from app.models.team import Team
|
from app.models.team import Team, TeamCreate, TeamUpdate
|
||||||
|
|
||||||
from app.schemas.team import TeamCreate, TeamUpdate
|
|
||||||
|
|
||||||
|
|
||||||
class CRUDTeam(CRUDBase[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:
|
def create(self, db: Session, *, obj_in: TeamCreate) -> Team:
|
||||||
db_obj = Team(teamname=obj_in.teamname)
|
db_obj = Team(teamname=obj_in.teamname)
|
||||||
|
|
@ -28,19 +20,19 @@ class CRUDTeam(CRUDBase[Team, TeamCreate, TeamUpdate]):
|
||||||
def add_player_in_team(
|
def add_player_in_team(
|
||||||
self, db: Session, team_id: int, player_id: int
|
self, db: Session, team_id: int, player_id: int
|
||||||
) -> Team:
|
) -> Team:
|
||||||
team = self.get_team(db=db, team_id=team_id)
|
team_in = self.get(db=db, id=team_id)
|
||||||
db_player = crud_player.get_player(db=db, player_id=player_id)
|
db_player = crud_player.get(db=db, id=player_id)
|
||||||
team.players.append(db_player)
|
team_in.players.append(db_player)
|
||||||
db.commit()
|
db.commit()
|
||||||
return team
|
return team_in
|
||||||
|
|
||||||
def is_player_in_team(
|
def is_player_in_team(
|
||||||
self, db: Session, *, player_id: int, team_id: int
|
self, db: Session, *, player_id: int, team_id: int
|
||||||
) -> bool:
|
) -> bool:
|
||||||
team = self.get_team(db=db, team_id=team_id)
|
team = self.get(db=db, id=team_id)
|
||||||
if team is None:
|
if team is None:
|
||||||
return False
|
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
|
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.core.security import get_password_hash, verify_password
|
||||||
from app.crud.base import CRUDBase
|
from app.crud.base import CRUDBase
|
||||||
from app.models.user import User
|
from app.models.user import User, UserCreate, UserUpdate
|
||||||
from app.schemas.user import UserCreate, UserUpdate
|
|
||||||
|
|
||||||
|
|
||||||
class CRUDUser(CRUDBase[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(SQLModel):
|
||||||
class Base:
|
id: Optional[int] = Field(default=None, primary_key=True, index=True)
|
||||||
id: Any
|
|
||||||
__name__: str
|
__name__: str
|
||||||
# Generate __tablename__ automatically
|
# Generate __tablename__ automatically
|
||||||
@declared_attr
|
|
||||||
def __tablename__(cls) -> str:
|
|
||||||
return cls.__name__.lower()
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app import crud, schemas
|
from app import crud
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.db import base # noqa: F401
|
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
|
# for more details: https://github.com/tiangolo/full-stack-fastapi-postgresql/issues/28
|
||||||
from app.db.base_class import Base
|
from app.db.base_class import Base
|
||||||
from app.db.session import engine
|
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:
|
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)
|
user = crud.user.get_by_email(db, email=settings.FIRST_SUPERUSER)
|
||||||
if not user:
|
if not user:
|
||||||
user_in = schemas.UserCreate(
|
user_in = UserCreate(
|
||||||
email=settings.FIRST_SUPERUSER,
|
email=settings.FIRST_SUPERUSER,
|
||||||
password=settings.FIRST_SUPERUSER_PASSWORD,
|
password=settings.FIRST_SUPERUSER_PASSWORD,
|
||||||
is_superuser=True,
|
is_superuser=True,
|
||||||
)
|
)
|
||||||
user = crud.user.create(db, obj_in=user_in) # noqa: F841
|
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 sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
|
|
||||||
|
from sqlmodel import create_engine, SQLModel
|
||||||
|
|
||||||
engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
|
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)
|
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 fastapi import FastAPI
|
||||||
|
from loguru import logger
|
||||||
from starlette.middleware.cors import CORSMiddleware
|
from starlette.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
from app.api.api_v1.api import api_router
|
from app.api.api_v1.api import api_router
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.db.init_db import init_db
|
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()
|
db = SessionLocal()
|
||||||
|
configure_log_handler(log_level=logging.DEBUG)
|
||||||
init_db(db)
|
init_db(db)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,6 +20,10 @@ app = FastAPI(
|
||||||
title=settings.PROJECT_NAME,
|
title=settings.PROJECT_NAME,
|
||||||
openapi_url=f"{settings.API_V1_STR}/openapi.json",
|
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
|
# Set all CORS enabled origins
|
||||||
if settings.BACKEND_CORS_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)
|
app.include_router(api_router, prefix=settings.API_V1_STR)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
# from .match import Match
|
from app.models.matchday import Matchday, MatchdayWithPlayers
|
||||||
# from .matchday import Matchday
|
from app.models.player import Player, PlayerTeamsMatchdays
|
||||||
from .player import Player
|
from app.models.team import Team, TeamWithPlayers
|
||||||
from .team import Team
|
|
||||||
from .user import User
|
|
||||||
|
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 typing import Optional
|
||||||
from sqlalchemy.orm import relationship
|
|
||||||
|
|
||||||
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)
|
match_id = Column(Integer, primary_key=True)
|
||||||
team_1 = Column(ForeignKey("team.id"), nullable=False)
|
team_1 = Column(ForeignKey("team.id"), nullable=False)
|
||||||
team_2 = 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")
|
team = relationship("Team", primaryjoin="Match.team_1 == Team.team_id")
|
||||||
team1 = relationship("Team", primaryjoin="Match.team_2 == Team.team_id")
|
team1 = relationship("Team", primaryjoin="Match.team_2 == Team.team_id")
|
||||||
team2 = relationship("Team", primaryjoin="Match.winner == 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 datetime import date, datetime
|
||||||
from sqlalchemy.orm import relationship
|
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.db.base_class import Base
|
||||||
|
from app.models.matchdayplayer import MatchdayPlayerLink
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from app.models.player import Player
|
||||||
|
|
||||||
|
|
||||||
class MatchdayPlayer(Base):
|
class MatchdayBase(SQLModel):
|
||||||
|
day: date
|
||||||
player_id = Column("players_id", ForeignKey("players.id"), primary_key=True)
|
|
||||||
matchday_id = Column("teams_id", ForeignKey("teams.id"), primary_key=True)
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
class MatchdayCreate(MatchdayBase):
|
||||||
players = relationship("Player", secondary="matchdayplayer")
|
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 typing import Optional, List, TYPE_CHECKING
|
||||||
from sqlalchemy.orm import relationship
|
|
||||||
|
|
||||||
|
from sqlmodel import SQLModel, Field, Relationship
|
||||||
from app.db.base_class import Base
|
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"))
|
class Player(PlayerBase, Base, table=True):
|
||||||
team = relationship("Team", back_populates="players")
|
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 typing import Optional, List, TYPE_CHECKING
|
||||||
from sqlalchemy.orm import relationship
|
|
||||||
|
from sqlmodel import SQLModel, Field, Relationship
|
||||||
|
|
||||||
from app.db.base_class import Base
|
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 typing import Optional
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class Token(BaseModel):
|
class Token(BaseModel):
|
||||||
access_token: str
|
access_token: str
|
||||||
token_type: 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
|
from app.db.base_class import Base
|
||||||
|
|
||||||
|
|
||||||
class User(Base):
|
class UserBase(SQLModel):
|
||||||
id = Column(Integer, primary_key=True, index=True)
|
|
||||||
full_name = Column(String, index=True)
|
full_name: Optional[str] = Field(index=True)
|
||||||
email = Column(String, unique=True, index=True, nullable=False)
|
email: Optional[EmailStr] = Field(unique=True, index=True, nullable=False)
|
||||||
hashed_password = Column(String, nullable=False)
|
hashed_password: Optional[str] = Field(nullable=False)
|
||||||
is_active = Column(Boolean(), default=True)
|
is_active: Optional[bool] = Field(default=True)
|
||||||
is_superuser = Column(Boolean(), default=False)
|
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 .user import User, UserCreate, UserInDB, UserUpdate
|
||||||
from .token import Token, TokenPayload
|
#from .player import Player, PlayerCreate, PlayerInDB
|
||||||
from .msg import Msg
|
#from .team import Team, TeamCreate, TeamInDBBase
|
||||||
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 jose import jwt
|
||||||
|
|
||||||
from app.core.config import settings
|
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(
|
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
|
optional = false
|
||||||
python-versions = ">=3.6"
|
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]]
|
[[package]]
|
||||||
name = "lxml"
|
name = "lxml"
|
||||||
version = "4.9.1"
|
version = "4.9.1"
|
||||||
|
|
@ -754,6 +769,30 @@ postgresql_psycopg2cffi = ["psycopg2cffi"]
|
||||||
pymysql = ["pymysql", "pymysql (<1)"]
|
pymysql = ["pymysql", "pymysql (<1)"]
|
||||||
sqlcipher = ["sqlcipher3-binary"]
|
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]]
|
[[package]]
|
||||||
name = "starlette"
|
name = "starlette"
|
||||||
version = "0.19.1"
|
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)"]
|
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)"]
|
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]]
|
[[package]]
|
||||||
name = "wrapt"
|
name = "wrapt"
|
||||||
version = "1.14.1"
|
version = "1.14.1"
|
||||||
|
|
@ -879,7 +929,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "875e82447867f92eb96260ad048da2e4967d2c8285ecaac9dca37dd839d7d78f"
|
content-hash = "f51b93ad173b06640d39b5143150dd0219b20bfcd5c3c9a0a4036b5638d12925"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
anyio = [
|
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-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"},
|
||||||
{file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"},
|
{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 = [
|
lxml = [
|
||||||
{file = "lxml-4.9.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed"},
|
{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"},
|
{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-cp39-cp39-win_amd64.whl", hash = "sha256:bf073c619b5a7f7cd731507d0fdc7329bee14b247a63b0419929e4acd24afea8"},
|
||||||
{file = "SQLAlchemy-1.4.40.tar.gz", hash = "sha256:44a660506080cc975e1dfa5776fe5f6315ddc626a77b50bf0eee18b0389ea265"},
|
{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 = [
|
starlette = [
|
||||||
{file = "starlette-0.19.1-py3-none-any.whl", hash = "sha256:5a60c5c2d051f3a8eb546136aa0c9399773a689595e099e0877704d5888279bf"},
|
{file = "starlette-0.19.1-py3-none-any.whl", hash = "sha256:5a60c5c2d051f3a8eb546136aa0c9399773a689595e099e0877704d5888279bf"},
|
||||||
{file = "starlette-0.19.1.tar.gz", hash = "sha256:c6d21096774ecb9639acad41b86b7706e52ba3bf1dc13ea4ed9ad593d47e24c7"},
|
{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-py2.py3-none-any.whl", hash = "sha256:4193b7bc8a6cd23e4eb251ac64f29b4398ab2c233531e66e40b19a6b7b0d30c1"},
|
||||||
{file = "virtualenv-20.16.3.tar.gz", hash = "sha256:d86ea0bb50e06252d79e6c241507cb904fcd66090c3271381372d6221a3970f9"},
|
{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 = [
|
wrapt = [
|
||||||
{file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
|
{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"},
|
{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"}
|
pydantic = {extras = ["email"], version = "^1.10.0"}
|
||||||
python-multipart = "^0.0.5"
|
python-multipart = "^0.0.5"
|
||||||
emails = "^0.6"
|
emails = "^0.6"
|
||||||
|
sqlmodel = "^0.0.8"
|
||||||
|
loguru = "^0.6.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pytest = "^7.1.2"
|
pytest = "^7.1.2"
|
||||||
|
|
@ -30,6 +32,8 @@ isort = "^5.10.1"
|
||||||
line-length = 79
|
line-length = 79
|
||||||
target-version = [ "py39",]
|
target-version = [ "py39",]
|
||||||
|
|
||||||
|
[tool.poetry.scripts]
|
||||||
|
web = "app.main:"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue