first version of backend

This commit is contained in:
Simon 2022-09-19 21:26:05 +02:00
parent 3b6ba0a2a4
commit 170777772d
55 changed files with 222 additions and 218 deletions

View File

@ -1,96 +0,0 @@
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

View File

@ -1,4 +0,0 @@
from app.db.base_class import Base # noqa
# from app.models.item import Item # noqa
from app.models.user import User # noqa

View File

@ -1,24 +0,0 @@
from typing import Optional
from sqlmodel import SQLModel, Field
from app.db.base_class import 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)
day = Column(ForeignKey("matchday.id"), nullable=False)
winner = Column(ForeignKey("team.team_id"), nullable=True)
team_1_result = Column(Integer, nullable=True)
team_2_result = Column(Integer, nullable=True)
matchday = relationship("Matchday")
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")
"""

View File

View File

@ -1,11 +1,11 @@
from fastapi import APIRouter from fastapi import APIRouter
from app.api.api_v1.endpoints import users from backend.app.api.api_v1.endpoints import users
from app.api.api_v1.endpoints import login from backend.app.api.api_v1.endpoints import login
from app.api.api_v1.endpoints import player from backend.app.api.api_v1.endpoints import player
from app.api.api_v1.endpoints import team from backend.app.api.api_v1.endpoints import team
from app.api.api_v1.endpoints import match from backend.app.api.api_v1.endpoints import match
from app.api.api_v1.endpoints import matchday from backend.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"])
@ -13,4 +13,4 @@ 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(matchday.router, prefix="/matchday", tags=["matchday"])
#api_router.include_router(match.router, prefix="/match", tags=["match"]) api_router.include_router(match.router, prefix="/match", tags=["match"])

View File

@ -5,15 +5,15 @@ 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 from backend.app import crud
from app.api import deps from backend.app.api import deps
from app.core import security from backend.app.core import security
from app.core.config import settings from backend.app.core.config import settings
from app.core.security import get_password_hash from backend.app.core.security import get_password_hash
from app.models.msg import Msg from backend.app.models.msg import Msg
from app.models.token import Token from backend.app.models.token import Token
from app.models.user import User from backend.app.models.user import User
from app.utils import ( from backend.app.utils import (
generate_password_reset_token, generate_password_reset_token,
send_reset_password_email, send_reset_password_email,
verify_password_reset_token, verify_password_reset_token,

View File

@ -0,0 +1,83 @@
from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from backend.app import crud
from backend.app.api import deps
from backend.app.models.match import Match, MatchCreate, MatchUpdate
from backend.app.models.user import User
router = APIRouter()
@router.get("/{match_id}", response_model=Match)
def read_match(
*,
db: Session = Depends(deps.get_db),
match_id: int,
current_user: User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get match by id.
"""
match = crud.match.get(
db=db, id=match_id
)
if not match:
raise HTTPException(status_code=404, detail="match not found")
if not crud.user.is_superuser(current_user):
raise HTTPException(status_code=400, detail="Not enough permissions")
return match
@router.post("/", response_model=Match)
def create_match(
*,
db: Session = Depends(deps.get_db),
match_in: MatchCreate,
current_user: User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
match = crud.match.create(db, obj_in=match_in)
return match
@router.get("/", response_model=List[Match])
def get_matchs(
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve all matchs.
"""
match = crud.match.get_multi(db, skip=skip, limit=limit)
return match
@router.post("/{match_id}", response_model=Match)
def update_match(
*,
db: Session = Depends(deps.get_db),
match_id: int,
match_in: MatchUpdate,
current_user: User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update match.
"""
match = crud.match.get(db=db, id=match_id)
if not match:
raise HTTPException(status_code=404, detail="Match not found")
match = crud.match.update(db=db, db_obj=match, obj_in=match_in)
return match

View File

@ -3,12 +3,12 @@ from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app import crud from backend.app import crud
from app.api import deps from backend.app.api import deps
from app.models.matchday import Matchday, MatchdayCreate, MatchdayUpdate, \ from backend.app.models.matchday import Matchday, MatchdayCreate, MatchdayUpdate, \
MatchdayWithPlayers MatchdayWithPlayers
from app.models.user import User from backend.app.models.user import User
router = APIRouter() router = APIRouter()

View File

@ -3,12 +3,12 @@ from typing import Any, List
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app import crud from backend.app import crud
from app.api import deps from backend.app.api import deps
from app.models.player import Player, PlayerCreate, PlayerUpdate, \ from backend.app.models.player import Player, PlayerCreate, PlayerUpdate, \
PlayerTeamsMatchdays PlayerTeamsMatchdays
from app.models.user import User from backend.app.models.user import User
router = APIRouter() router = APIRouter()

View File

@ -4,10 +4,10 @@ from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app import crud from backend.app import crud
from app.api import deps from backend.app.api import deps
from app.models.team import Team, TeamCreate, TeamWithPlayers from backend.app.models.team import Team, TeamCreate, TeamWithPlayers
from app.models.user import User from backend.app.models.user import User
router = APIRouter() router = APIRouter()
@ -40,7 +40,7 @@ def get_teams(
""" """
Retrieve teams. Retrieve teams.
""" """
team = crud.team.get_multi( db, skip=skip, limit=limit) team = crud.team.get_multi(db, skip=skip, limit=limit)
return team return team

View File

@ -5,10 +5,10 @@ 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 from backend.app import crud
from app.api import deps from backend.app.api import deps
from app.core.config import settings from backend.app.core.config import settings
from app.models.user import UserUpdate, User, UserCreate from backend.app.models.user import UserUpdate, User, UserCreate
router = APIRouter() router = APIRouter()

View File

@ -6,12 +6,12 @@ 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 from backend.app import crud
from app.models.token import TokenPayload from backend.app.models.token import TokenPayload
from app.models.user import User from backend.app.models.user import User
from app.core import security from backend.app.core import security
from app.core.config import settings from backend.app.core.config import settings
from app.db.session import SessionLocal from backend.app.db.session import SessionLocal
reusable_oauth2 = OAuth2PasswordBearer( reusable_oauth2 = OAuth2PasswordBearer(
tokenUrl=f"{settings.API_V1_STR}/login/access-token" tokenUrl=f"{settings.API_V1_STR}/login/access-token"

View File

@ -4,7 +4,7 @@ from typing import Any, Union
from jose import jwt from jose import jwt
from passlib.context import CryptContext from passlib.context import CryptContext
from app.core.config import settings from backend.app.core.config import settings
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

View File

@ -2,3 +2,4 @@ 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 from .crud_matchday import matchday
from .crud_match import match

View File

@ -5,7 +5,7 @@ from pydantic import BaseModel
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlmodel import select from sqlmodel import select
from app.db.base_class import Base from backend.app.db.base_class import Base
ModelType = TypeVar("ModelType", bound=Base) ModelType = TypeVar("ModelType", bound=Base)
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel) CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)

View File

@ -0,0 +1,19 @@
from sqlalchemy.orm import Session
from backend.app.crud.base import CRUDBase
from backend.app.models.match import Match, MatchCreate, MatchUpdate
class CRUDMatch(CRUDBase[Match, MatchCreate, MatchUpdate]):
def create(self, db: Session, *, obj_in: MatchCreate) -> Match:
db_obj = Match(
**obj_in.dict()
)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
match = CRUDMatch(Match)

View File

@ -1,11 +1,11 @@
from typing import Any, Dict, Union, Optional from typing import Any
from sqlmodel import select from sqlmodel import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.crud import player as crud_player from backend.app.crud import player as crud_player
from app.crud.base import CRUDBase from backend.app.crud.base import CRUDBase
from app.models.matchday import Matchday, MatchdayCreate, MatchdayUpdate from backend.app.models.matchday import Matchday, MatchdayCreate, MatchdayUpdate
class CRUDMatchday(CRUDBase[Matchday, MatchdayCreate, MatchdayUpdate]): class CRUDMatchday(CRUDBase[Matchday, MatchdayCreate, MatchdayUpdate]):

View File

@ -1,9 +1,9 @@
from typing import Any, Dict, Optional, Union from typing import Optional
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.crud.base import CRUDBase from backend.app.crud.base import CRUDBase
from app.models.player import Player, PlayerCreate, PlayerUpdate from backend.app.models.player import Player, PlayerCreate, PlayerUpdate
class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]): class CRUDPlayer(CRUDBase[Player, PlayerCreate, PlayerUpdate]):

View File

@ -1,11 +1,8 @@
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 backend.app.crud.base import CRUDBase
from app.crud import player as crud_player from backend.app.crud import player as crud_player
from app.models.team import Team, TeamCreate, TeamUpdate from backend.app.models.team import Team, TeamCreate, TeamUpdate
class CRUDTeam(CRUDBase[Team, TeamCreate, TeamUpdate]): class CRUDTeam(CRUDBase[Team, TeamCreate, TeamUpdate]):

View File

@ -2,9 +2,9 @@ from typing import Any, Dict, Optional, Union
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.core.security import get_password_hash, verify_password from backend.app.core.security import get_password_hash, verify_password
from app.crud.base import CRUDBase from backend.app.crud.base import CRUDBase
from app.models.user import User, UserCreate, UserUpdate from backend.app.models.user import User, UserCreate, UserUpdate

4
backend/app/db/base.py Normal file
View File

@ -0,0 +1,4 @@
from backend.app.db.base_class import Base # noqa
# from app.models.item import Item # noqa
from backend.app.models.user import User # noqa

View File

@ -1,17 +1,16 @@
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app import crud from backend.app import crud
from app.core.config import settings from backend.app.core.config import settings
from app.db import base # noqa: F401
# make sure all SQL Alchemy models are imported (app.db.base) before initializing DB # make sure all SQL Alchemy models are imported (app.db.base) before initializing DB
# otherwise, SQL Alchemy might fail to initialize relationships properly # otherwise, SQL Alchemy might fail to initialize relationships properly
# 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 backend.app.db.base_class import Base
from app.db.session import engine from backend.app.db.session import engine
from app.models.player import Player, PlayerCreate from backend.app.models.player import PlayerCreate
from app.models.team import TeamCreate, TeamWithPlayers from backend.app.models.team import TeamWithPlayers
from app.models.user import UserCreate from backend.app.models.user import UserCreate
def init_db(db: Session) -> None: def init_db(db: Session) -> None:

View File

@ -1,7 +1,7 @@
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from app.core.config import settings from backend.app.core.config import settings
from sqlmodel import create_engine, SQLModel from sqlmodel import create_engine, SQLModel

View File

@ -1,15 +1,13 @@
import logging 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 backend.app.api.api_v1.api import api_router
from app.core.config import settings from backend.app.core.config import settings
from app.db.init_db import init_db from backend.app.db.init_db import init_db
from app.db.session import SessionLocal, create_db_and_tables from backend.app.db.session import SessionLocal, create_db_and_tables
from app.utils import configure_log_handler from backend.app.utils import configure_log_handler
db = SessionLocal() db = SessionLocal()
configure_log_handler(log_level=logging.DEBUG) configure_log_handler(log_level=logging.DEBUG)

View File

@ -1,6 +1,6 @@
from app.models.matchday import Matchday, MatchdayWithPlayers from backend.app.models.matchday import Matchday, MatchdayWithPlayers
from app.models.player import Player, PlayerTeamsMatchdays from backend.app.models.player import Player, PlayerTeamsMatchdays
from app.models.team import Team, TeamWithPlayers from backend.app.models.team import Team, TeamWithPlayers
Player.update_forward_refs(Team=Team, Matchday=Matchday) Player.update_forward_refs(Team=Team, Matchday=Matchday)

View File

@ -0,0 +1,30 @@
from typing import Optional
from sqlmodel import SQLModel, Field
from backend.app.db.base_class import Base
class MatchBase(SQLModel):
team_1_result: int | None
team_2_result: int | None
class Match(MatchBase, Base, table=True):
team_1: Optional[int] = Field(default=None, foreign_key="team.id")
team_2: Optional[int] = Field(default=None, foreign_key="team.id")
winner: Optional[int] = Field(default=None, foreign_key="team.id")
day: Optional[int] = Field(default=None, foreign_key="matchday.id")
class MatchCreate(MatchBase):
team_1: Optional[int]
team_2: Optional[int]
winner: Optional[int]
day: Optional[int]
class MatchUpdate(MatchBase):
team_1: Optional[int]
team_2: Optional[int]
winner: Optional[int]
day: Optional[int]

View File

@ -1,14 +1,14 @@
from datetime import date, datetime from datetime import date
from typing import List, Optional, TYPE_CHECKING from typing import List, Optional, TYPE_CHECKING
from sqlalchemy import Date from sqlalchemy import Date
from sqlmodel import SQLModel, Relationship, Field, Column, func from sqlmodel import SQLModel, Relationship, Field, Column, func
from app.db.base_class import Base from backend.app.db.base_class import Base
from app.models.matchdayplayer import MatchdayPlayerLink from backend.app.models.matchdayplayer import MatchdayPlayerLink
if TYPE_CHECKING: if TYPE_CHECKING:
from app.models.player import Player from backend.app.models.player import Player
class MatchdayBase(SQLModel): class MatchdayBase(SQLModel):

View File

@ -1,13 +1,13 @@
from typing import Optional, List, TYPE_CHECKING from typing import List, TYPE_CHECKING
from sqlmodel import SQLModel, Field, Relationship from sqlmodel import SQLModel, Field, Relationship
from app.db.base_class import Base from backend.app.db.base_class import Base
from app.models.matchdayplayer import MatchdayPlayerLink from backend.app.models.matchdayplayer import MatchdayPlayerLink
from app.models.teamplayers import TeamPlayerLink from backend.app.models.teamplayers import TeamPlayerLink
if TYPE_CHECKING: if TYPE_CHECKING:
from app.models import Team, Matchday from backend.app.models import Team, Matchday
class PlayerBase(SQLModel): class PlayerBase(SQLModel):
firstname: str = Field(nullable=False) firstname: str = Field(nullable=False)
lastname: str = Field(nullable=False) lastname: str = Field(nullable=False)

View File

@ -2,12 +2,12 @@ from typing import Optional, List, TYPE_CHECKING
from sqlmodel import SQLModel, Field, Relationship from sqlmodel import SQLModel, Field, Relationship
from app.db.base_class import Base from backend.app.db.base_class import Base
from app.models.teamplayers import TeamPlayerLink from backend.app.models.teamplayers import TeamPlayerLink
if TYPE_CHECKING: if TYPE_CHECKING:
from app.models.player import Player from backend.app.models.player import Player
class TeamBase(SQLModel): class TeamBase(SQLModel):
teamname: Optional[str] = Field(nullable=False) teamname: Optional[str] = Field(nullable=False)

View File

@ -2,7 +2,7 @@ from typing import Optional
from pydantic import EmailStr from pydantic import EmailStr
from sqlmodel import SQLModel, Field from sqlmodel import SQLModel, Field
from app.db.base_class import Base from backend.app.db.base_class import Base
class UserBase(SQLModel): class UserBase(SQLModel):

View File

@ -1,4 +1,3 @@
import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
@ -7,7 +6,7 @@ import emails
from emails.template import JinjaTemplate from emails.template import JinjaTemplate
from jose import jwt from jose import jwt
from app.core.config import settings from backend.app.core.config import settings
import sys import sys
import logging import logging
from loguru import logger from loguru import logger

View File

@ -1,8 +1,6 @@
import uvicorn import uvicorn
from loguru import logger from loguru import logger
from app.main import app
def main(): def main():
uvicorn.run("debug_run:app", host="0.0.0.0", port=1234, reload=True) uvicorn.run("debug_run:app", host="0.0.0.0", port=1234, reload=True)

View File

View File

@ -1,4 +1,4 @@
from app import __version__ from backend.app import __version__
def test_version(): def test_version():