refactor(backend): ♻️ cleanup HTTP service classes and remove database singleton (#687)

* refactor(backend): ♻️ cleanup duplicate code in http services

* refactor(backend): ♻️ refactor database away from singleton design

removed the database single and instead injected the session into a new Database class that is created during each request life-cycle. Now sessions no longer need to be passed into each method on the database

All tests pass, but there are likely some hidden breaking changes that were not discovered.

* fix venv

* disable venv cache

* fix install script

* bump poetry version

* postgres fixes

* revert install

* fix db initialization for postgres

* add postgres to docker

* refactor(backend): ♻️ cleanup unused and duplicate code in http services

* refactor(backend): remove sessions from arguments

* refactor(backend): ♻️ convert units and ingredients to use http service class

* test(backend):  add unit and food tests

* lint

* update tags

* re-enable cache

* fix missing fraction in db

* fix lint

Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
Hayden
2021-09-19 15:31:34 -08:00
committed by GitHub
parent c0e3f04c23
commit 476aefeeb0
68 changed files with 1131 additions and 1084 deletions

View File

@@ -6,7 +6,7 @@ from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user
from mealie.core.security import create_access_token
from mealie.db.database import db
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.routes.routers import UserAPIRouter
from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB, PrivateUser
@@ -33,7 +33,9 @@ async def create_api_token(
parent_id=current_user.id,
)
new_token_in_db = db.api_tokens.create(session, token_model)
db = get_database(session)
new_token_in_db = db.api_tokens.create(token_model)
if new_token_in_db:
return {"token": token}
@@ -46,13 +48,14 @@ async def delete_api_token(
session: Session = Depends(generate_session),
):
""" Delete api_token from the Database """
token: LongLiveTokenInDB = db.api_tokens.get(session, token_id)
db = get_database(session)
token: LongLiveTokenInDB = db.api_tokens.get(token_id)
if not token:
raise HTTPException(status.HTTP_404_NOT_FOUND, f"Could not locate token with id '{token_id}' in database")
if token.user.email == current_user.email:
deleted_token = db.api_tokens.delete(session, token_id)
deleted_token = db.api_tokens.delete(token_id)
return {"token_delete": deleted_token.name}
else:
raise HTTPException(status.HTTP_403_FORBIDDEN)

View File

@@ -4,7 +4,7 @@ from sqlalchemy.orm.session import Session
from mealie.core import security
from mealie.core.dependencies import get_current_user
from mealie.core.security import hash_password
from mealie.db.database import db
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed
@@ -17,7 +17,8 @@ admin_router = AdminAPIRouter(prefix="")
@admin_router.get("", response_model=list[UserOut])
async def get_all_users(session: Session = Depends(generate_session)):
return db.users.get_all(session)
db = get_database(session)
return db.users.get_all()
@admin_router.post("", response_model=UserOut, status_code=201)
@@ -33,12 +34,14 @@ async def create_user(
create_user_event, "User Created", f"Created by {current_user.full_name}", session=session
)
return db.users.create(session, new_user.dict())
db = get_database(session)
return db.users.create(new_user.dict())
@admin_router.get("/{id}", response_model=UserOut)
async def get_user(id: int, session: Session = Depends(generate_session)):
return db.users.get(session, id)
db = get_database(session)
return db.users.get(id)
@admin_router.delete("/{id}")
@@ -56,7 +59,8 @@ def delete_user(
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="SUPER_USER")
try:
db.users.delete(session, id)
db = get_database(session)
db.users.delete(id)
background_tasks.add_task(create_user_event, "User Deleted", f"User ID: {id}", session=session)
except Exception:
raise HTTPException(status.HTTP_400_BAD_REQUEST)
@@ -87,7 +91,9 @@ async def update_user(
# prevent an admin from demoting themself
raise HTTPException(status.HTTP_403_FORBIDDEN)
db.users.update(session, id, new_data.dict())
db = get_database(session)
db.users.update(id, new_data.dict())
if current_user.id == id:
access_token = security.create_access_token(data=dict(sub=new_data.email))
return {"access_token": access_token, "token_type": "bearer"}

View File

@@ -2,7 +2,7 @@ from fastapi import Depends
from sqlalchemy.orm.session import Session
from mealie.core.dependencies import get_current_user
from mealie.db.database import db
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.routes.routers import UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed
@@ -14,8 +14,8 @@ user_router = UserAPIRouter()
@user_router.get("/{id}/favorites", response_model=UserFavorites)
async def get_favorites(id: str, session: Session = Depends(generate_session)):
""" Get user's favorite recipes """
return db.users.get(session, id, override_schema=UserFavorites)
db = get_database(session)
return db.users.get(id, override_schema=UserFavorites)
@user_router.post("/{id}/favorites/{slug}")
@@ -29,7 +29,8 @@ def add_favorite(
assert_user_change_allowed(id, current_user)
current_user.favorite_recipes.append(slug)
db.users.update(session, current_user.id, current_user)
db = get_database(session)
db.users.update(current_user.id, current_user)
@user_router.delete("/{id}/favorites/{slug}")
@@ -43,6 +44,7 @@ def remove_favorite(
assert_user_change_allowed(id, current_user)
current_user.favorite_recipes = [x for x in current_user.favorite_recipes if x != slug]
db.users.update(session, current_user.id, current_user)
db = get_database(session)
db.users.update(current_user.id, current_user)
return

View File

@@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
from mealie.core.config import settings
from mealie.core.security import hash_password
from mealie.db.database import db
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.routes.routers import UserAPIRouter
from mealie.schema.user import ChangePassword
@@ -15,7 +15,9 @@ user_router = UserAPIRouter(prefix="")
@user_router.put("/{id}/reset-password")
async def reset_user_password(id: int, session: Session = Depends(generate_session)):
new_password = hash_password(settings.DEFAULT_PASSWORD)
db.users.update_password(session, id, new_password)
db = get_database(session)
db.users.update_password(id, new_password)
@user_router.put("/{id}/password")