[refactor] cleanup dead code
This commit is contained in:
parent
2deb66f7e5
commit
20437905ba
27 changed files with 7 additions and 791 deletions
|
|
@ -1,6 +0,0 @@
|
|||
FROM alpine
|
||||
|
||||
RUN apk add --no-cache curl
|
||||
RUN crontab -l | { cat; echo '1 * * * * curl -X POST "http://tasks:8000/api/cache_product_usage_data" -H "Authorization: Bearer ${API_KEY}"'; } | crontab -
|
||||
|
||||
CMD ["crond", "-f", "-l", "2"]
|
||||
24
Makefile
24
Makefile
|
|
@ -4,56 +4,46 @@ VERSION=0.`git rev-list --count HEAD`
|
|||
DOCKER_BUILD=docker build
|
||||
|
||||
ifeq ($(shell uname -m), arm64)
|
||||
DOCKER_BUILD=docker buildx build --platform linux/amd64
|
||||
DOCKER_BUILD=docker buildx build --platform linux/amd64 --load
|
||||
endif
|
||||
|
||||
api: fooder Dockerfile requirements.txt
|
||||
api: fooder Dockerfile requirements/docker.txt
|
||||
$(DOCKER_BUILD) -t registry.domandoman.xyz/fooder/api -f Dockerfile .
|
||||
|
||||
cron: Dockerfile.cron
|
||||
$(DOCKER_BUILD) -t registry.domandoman.xyz/fooder/cron -f Dockerfile.cron .
|
||||
|
||||
build: api cron
|
||||
build: api
|
||||
|
||||
push:
|
||||
docker push registry.domandoman.xyz/fooder/api
|
||||
docker push registry.domandoman.xyz/fooder/cron
|
||||
|
||||
.PHONY: black mypy flake lint version create-venv test
|
||||
black:
|
||||
python -m black fooder
|
||||
|
||||
.PHONY: mypy
|
||||
mypy:
|
||||
python -m mypy fooder
|
||||
|
||||
.PHONY: flake
|
||||
flake:
|
||||
python -m flake8 fooder
|
||||
|
||||
.PHONY: lint
|
||||
lint: black mypy flake
|
||||
|
||||
.PHONY: version
|
||||
version:
|
||||
@echo $(VERSION)
|
||||
|
||||
.PHONY: create-venv
|
||||
create-venv:
|
||||
python3 -m venv .venv --prompt="fooderapi-venv" --system-site-packages
|
||||
bash -c "source .venv/bin/activate && pip install -r requirements/local.txt"
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
./test.sh
|
||||
|
||||
.PHONY: alembic
|
||||
alembic:
|
||||
# Alembic
|
||||
.PHONY: alembic alembic-upgrade alembic-downgrade
|
||||
alembic: fooder
|
||||
docker compose exec -e MSG="$(MSG)" api bash -c 'alembic -c /opt/fooder/fooder/alembic.ini revision --autogenerate -m "$${MSG}"'
|
||||
|
||||
.PHONY: alembic-upgrade
|
||||
alembic-upgrade:
|
||||
docker compose exec api bash -c 'alembic -c /opt/fooder/fooder/alembic.ini upgrade head'
|
||||
|
||||
.PHONY: alembic-downgrade
|
||||
alembic-downgrade:
|
||||
docker compose exec api bash -c 'alembic -c /opt/fooder/fooder/alembic.ini downgrade -1'
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ DB_URI="postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@database/${PO
|
|||
ECHO_SQL=0
|
||||
|
||||
SECRET_KEY="${SECRET_KEY}" # generate with $ openssl rand -hex 32
|
||||
API_KEY="${API_KEY}" # generate with $ openssl rand -hex 32
|
||||
REFRESH_SECRET_KEY="${REFRESH_SECRET_KEY}" # generate with $ openssl rand -hex 32
|
||||
ALGORITHM="HS256"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=30
|
||||
|
||||
API_KEY="${API_KEY}" # generate with $ openssl rand -hex 32
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
from typing import Annotated, Any
|
||||
|
||||
from fastapi import Depends
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker
|
||||
|
||||
from ..auth import authorize_api_key, get_current_user
|
||||
from ..db import get_db_session, AsyncSession
|
||||
from ..domain.user import User
|
||||
|
||||
UserDependency = Annotated[User, Depends(get_current_user)]
|
||||
ApiKeyDependency = Annotated[None, Depends(authorize_api_key)]
|
||||
|
||||
|
||||
class BaseController:
|
||||
def __init__(self, session: AsyncSession) -> None:
|
||||
self.session = session
|
||||
|
||||
async def call(self, *args, **kwargs) -> Any:
|
||||
raise NotImplementedError
|
||||
|
||||
async def __call__(self, *args, **kwargs) -> Any:
|
||||
return await self.call(*args, **kwargs)
|
||||
|
||||
|
||||
class AuthorizedController(BaseController):
|
||||
def __init__(self, session: AsyncSession, user: UserDependency) -> None:
|
||||
super().__init__(session)
|
||||
self.user = user
|
||||
|
||||
|
||||
class TasksSessionController(BaseController):
|
||||
def __init__(self, session: AsyncSession, api_key: ApiKeyDependency) -> None:
|
||||
super().__init__(session)
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
from datetime import date
|
||||
|
||||
from fastapi import HTTPException
|
||||
|
||||
from ..domain.diary import Diary as DBDiary
|
||||
from ..model.diary import Diary
|
||||
from .base import AuthorizedController
|
||||
|
||||
|
||||
class GetDiary(AuthorizedController):
|
||||
async def call(self, date: date) -> Diary:
|
||||
diary = await DBDiary.get_diary(self.session, self.user.id, date)
|
||||
|
||||
if diary is not None:
|
||||
return Diary.from_orm(diary)
|
||||
else:
|
||||
try:
|
||||
await DBDiary.create(session, self.user.id, date)
|
||||
await session.commit()
|
||||
return Diary.from_orm(
|
||||
await DBDiary.get_diary(session, self.user.id, date)
|
||||
)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
from fastapi import HTTPException
|
||||
|
||||
from ..domain.entry import Entry as DBEntry
|
||||
from ..domain.meal import Meal as DBMeal
|
||||
from ..model.entry import CreateEntryPayload, Entry, UpdateEntryPayload
|
||||
from .base import AuthorizedController
|
||||
|
||||
|
||||
class CreateEntry(AuthorizedController):
|
||||
async def call(self, content: CreateEntryPayload) -> Entry:
|
||||
async with self.async_session.begin() as session:
|
||||
meal = await DBMeal.get_by_id(session, self.user.id, content.meal_id)
|
||||
if meal is None:
|
||||
raise HTTPException(status_code=404, detail="meal not found")
|
||||
|
||||
try:
|
||||
entry = await DBEntry.create(
|
||||
session, content.meal_id, content.product_id, content.grams
|
||||
)
|
||||
return Entry.from_orm(entry)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
||||
|
||||
class UpdateEntry(AuthorizedController):
|
||||
async def call(self, entry_id: int, content: UpdateEntryPayload) -> Entry:
|
||||
async with self.async_session.begin() as session:
|
||||
entry = await DBEntry.get_by_id(session, self.user.id, entry_id)
|
||||
if entry is None:
|
||||
raise HTTPException(status_code=404, detail="entry not found")
|
||||
|
||||
try:
|
||||
await entry.update(
|
||||
session, content.meal_id, content.product_id, content.grams
|
||||
)
|
||||
return Entry.from_orm(entry)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
||||
|
||||
class DeleteEntry(AuthorizedController):
|
||||
async def call(self, entry_id: int) -> None:
|
||||
async with self.async_session.begin() as session:
|
||||
entry = await DBEntry.get_by_id(session, self.user.id, entry_id)
|
||||
if entry is None:
|
||||
raise HTTPException(status_code=404, detail="entry not found")
|
||||
|
||||
try:
|
||||
await entry.delete(session)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
from fastapi import HTTPException
|
||||
|
||||
from ..domain.diary import Diary as DBDiary
|
||||
from ..domain.meal import Meal as DBMeal
|
||||
from ..domain.preset import Preset as DBPreset
|
||||
from ..model.meal import (
|
||||
CreateMealFromPresetPayload,
|
||||
CreateMealPayload,
|
||||
Meal,
|
||||
RenameMealPayload,
|
||||
SaveMealPayload,
|
||||
)
|
||||
from ..model.preset import Preset
|
||||
from .base import AuthorizedController
|
||||
|
||||
|
||||
class CreateMeal(AuthorizedController):
|
||||
async def call(self, content: CreateMealPayload) -> Meal:
|
||||
async with self.async_session.begin() as session:
|
||||
if not await DBDiary.has_permission(
|
||||
session, self.user.id, content.diary_id
|
||||
):
|
||||
raise HTTPException(status_code=404, detail="not found")
|
||||
|
||||
try:
|
||||
meal = await DBMeal.create(session, content.diary_id, content.name)
|
||||
return Meal.from_orm(meal)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
||||
|
||||
class SaveMeal(AuthorizedController):
|
||||
async def call(self, meal_id: int, payload: SaveMealPayload) -> Preset:
|
||||
async with self.async_session.begin() as session:
|
||||
meal = await DBMeal.get_by_id(session, self.user.id, meal_id)
|
||||
if meal is None:
|
||||
raise HTTPException(status_code=404, detail="meal not found")
|
||||
|
||||
try:
|
||||
return Preset.from_orm(
|
||||
await DBPreset.create(
|
||||
session,
|
||||
user_id=self.user.id,
|
||||
name=payload.name or meal.name,
|
||||
meal=meal,
|
||||
)
|
||||
)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
||||
|
||||
class RenameMeal(AuthorizedController):
|
||||
async def call(self, meal_id: int, payload: RenameMealPayload) -> Meal:
|
||||
async with self.async_session.begin() as session:
|
||||
meal = await DBMeal.get_by_id(session, self.user.id, meal_id)
|
||||
if meal is None:
|
||||
raise HTTPException(status_code=404, detail="meal not found")
|
||||
meal.name = payload.name
|
||||
await session.flush()
|
||||
return Meal.from_orm(meal)
|
||||
|
||||
|
||||
class DeleteMeal(AuthorizedController):
|
||||
async def call(self, meal_id: int) -> None:
|
||||
async with self.async_session.begin() as session:
|
||||
meal = await DBMeal.get_by_id(session, self.user.id, meal_id)
|
||||
if meal is None:
|
||||
raise HTTPException(status_code=404, detail="meal not found")
|
||||
|
||||
try:
|
||||
await meal.delete(session)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
||||
|
||||
class CreateMealFromPreset(AuthorizedController):
|
||||
async def call(self, content: CreateMealFromPresetPayload) -> Meal:
|
||||
async with self.async_session.begin() as session:
|
||||
if not await DBDiary.has_permission(
|
||||
session, self.user.id, content.diary_id
|
||||
):
|
||||
raise HTTPException(status_code=404, detail="diary not found")
|
||||
|
||||
preset = await DBPreset.get(session, self.user.id, content.preset_id)
|
||||
|
||||
if preset is None:
|
||||
raise HTTPException(status_code=404, detail="preset not found")
|
||||
|
||||
try:
|
||||
meal = await DBMeal.create_from_preset(
|
||||
session, content.diary_id, content.name, preset
|
||||
)
|
||||
return Meal.from_orm(meal)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
from typing import AsyncIterator, Optional
|
||||
|
||||
from fastapi import HTTPException
|
||||
|
||||
from ..domain.preset import Preset as DBPreset
|
||||
from ..model.preset import Preset, PresetDetails
|
||||
from .base import AuthorizedController
|
||||
|
||||
|
||||
class ListPresets(AuthorizedController):
|
||||
async def call(
|
||||
self, limit: int, offset: int, q: Optional[str]
|
||||
) -> AsyncIterator[Preset]:
|
||||
async with self.async_session() as session:
|
||||
async for preset in DBPreset.list_all(
|
||||
session, user_id=self.user.id, limit=limit, offset=offset, q=q
|
||||
):
|
||||
yield Preset.from_orm(preset)
|
||||
|
||||
|
||||
class GetPreset(AuthorizedController):
|
||||
async def call(self, id: int) -> PresetDetails:
|
||||
async with self.async_session() as session:
|
||||
preset = await DBPreset.get(session, self.user.id, id)
|
||||
|
||||
if preset is not None:
|
||||
return PresetDetails.from_orm(preset)
|
||||
|
||||
raise HTTPException(status_code=404, detail="preset not found")
|
||||
|
||||
|
||||
class DeletePreset(AuthorizedController):
|
||||
async def call(
|
||||
self,
|
||||
id: int,
|
||||
) -> None:
|
||||
async with self.async_session.begin() as session:
|
||||
preset = await DBPreset.get(session, self.user.id, id)
|
||||
|
||||
if preset is None:
|
||||
raise HTTPException(status_code=404, detail="preset not found")
|
||||
|
||||
await preset.delete(session)
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
from typing import AsyncIterator, Optional
|
||||
|
||||
from fastapi import HTTPException
|
||||
|
||||
from ..domain.product import Product as DBProduct
|
||||
from ..model.product import CreateProductPayload, Product
|
||||
from ..utils import product_finder
|
||||
from .base import AuthorizedController
|
||||
|
||||
|
||||
class CreateProduct(AuthorizedController):
|
||||
async def call(self, content: CreateProductPayload) -> Product:
|
||||
async with self.async_session.begin() as session:
|
||||
try:
|
||||
product = await DBProduct.create(
|
||||
session,
|
||||
content.name,
|
||||
content.carb,
|
||||
content.protein,
|
||||
content.fat,
|
||||
content.fiber,
|
||||
)
|
||||
return Product.from_orm(product)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
||||
|
||||
class ListProduct(AuthorizedController):
|
||||
async def call(
|
||||
self, limit: int, offset: int, q: Optional[str]
|
||||
) -> AsyncIterator[Product]:
|
||||
async with self.async_session() as session:
|
||||
async for product in DBProduct.list_all(
|
||||
session, limit=limit, offset=offset, q=q
|
||||
):
|
||||
yield Product.from_orm(product)
|
||||
|
||||
|
||||
class GetProductByBarCode(AuthorizedController):
|
||||
async def call(self, barcode: str) -> Product:
|
||||
async with self.async_session() as session:
|
||||
product = await DBProduct.get_by_barcode(session, barcode)
|
||||
|
||||
if product:
|
||||
return Product.from_orm(product)
|
||||
|
||||
try:
|
||||
product_data = product_finder.find(barcode)
|
||||
except product_finder.NotFound:
|
||||
raise HTTPException(status_code=404, detail="Product not found")
|
||||
except product_finder.ParseError:
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Product was found, but unable to import"
|
||||
)
|
||||
|
||||
try:
|
||||
product = await DBProduct.create(
|
||||
session,
|
||||
product_data.name,
|
||||
product_data.carb,
|
||||
product_data.protein,
|
||||
product_data.fat,
|
||||
product_data.fiber,
|
||||
product_data.kcal,
|
||||
barcode,
|
||||
)
|
||||
await session.commit()
|
||||
|
||||
return Product.from_orm(
|
||||
await DBProduct.get_by_barcode(session, barcode)
|
||||
)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
from fastapi import HTTPException
|
||||
|
||||
from ..domain.product import Product as DBProduct
|
||||
from .base import TasksSessionController
|
||||
|
||||
|
||||
class CacheProductUsageData(TasksSessionController):
|
||||
async def call(self) -> None:
|
||||
async with self.async_session.begin() as session:
|
||||
try:
|
||||
await DBProduct.cache_usage_data(session)
|
||||
await session.commit()
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
from fastapi import HTTPException
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
|
||||
from ..auth import (
|
||||
authenticate_user,
|
||||
create_access_token,
|
||||
create_refresh_token,
|
||||
verify_refresh_token,
|
||||
)
|
||||
from ..domain.user import User as DBUser
|
||||
from ..model.token import RefreshTokenPayload, Token
|
||||
from .base import BaseController
|
||||
|
||||
|
||||
class CreateToken(BaseController):
|
||||
async def call(self, content: OAuth2PasswordRequestForm) -> Token:
|
||||
async with self.async_session.begin() as session:
|
||||
user = await authenticate_user(session, content.username, content.password)
|
||||
|
||||
if user is None:
|
||||
raise HTTPException(
|
||||
status_code=401, detail="Invalid username or password"
|
||||
)
|
||||
|
||||
refresh_token = await create_refresh_token(session, user)
|
||||
access_token = create_access_token(user)
|
||||
|
||||
return Token(
|
||||
access_token=access_token,
|
||||
refresh_token=refresh_token.token,
|
||||
token_type="bearer",
|
||||
)
|
||||
|
||||
|
||||
class RefreshToken(BaseController):
|
||||
async def call(self, content: RefreshTokenPayload) -> Token:
|
||||
async with self.async_session.begin() as session:
|
||||
current_token = await verify_refresh_token(session, content.refresh_token)
|
||||
|
||||
if current_token is None:
|
||||
raise HTTPException(status_code=401, detail="Invalid token")
|
||||
|
||||
user = await DBUser.get(session, current_token.user_id)
|
||||
|
||||
if user is None:
|
||||
raise HTTPException(status_code=401, detail="Invalid token")
|
||||
|
||||
assert user is not None
|
||||
await current_token.delete(session)
|
||||
|
||||
refresh_token = await create_refresh_token(session, user)
|
||||
access_token = create_access_token(user)
|
||||
|
||||
return Token(
|
||||
access_token=access_token,
|
||||
refresh_token=refresh_token.token,
|
||||
token_type="bearer",
|
||||
)
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
from fastapi import HTTPException
|
||||
|
||||
from ..domain.user import User as DBUser
|
||||
from ..model.user import CreateUserPayload, User
|
||||
from .base import BaseController
|
||||
|
||||
|
||||
class CreateUser(BaseController):
|
||||
async def call(self, content: CreateUserPayload) -> User:
|
||||
async with self.async_session.begin() as session:
|
||||
try:
|
||||
user = await DBUser.create(
|
||||
session,
|
||||
content.username,
|
||||
content.password,
|
||||
)
|
||||
return User.from_orm(user)
|
||||
except AssertionError as e:
|
||||
raise HTTPException(status_code=400, detail=e.args[0])
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
from datetime import date
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .meal import Meal
|
||||
|
||||
|
||||
class Diary(BaseModel):
|
||||
"""Diary represents user diary for given day"""
|
||||
|
||||
id: int
|
||||
date: date
|
||||
meals: List[Meal]
|
||||
calories: float
|
||||
protein: float
|
||||
carb: float
|
||||
fat: float
|
||||
fiber: float
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .product import Product
|
||||
|
||||
|
||||
class Entry(BaseModel):
|
||||
"""Entry."""
|
||||
|
||||
id: int
|
||||
grams: float
|
||||
product: Product
|
||||
meal_id: int
|
||||
calories: float
|
||||
protein: float
|
||||
carb: float
|
||||
fat: float
|
||||
fiber: float
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class CreateEntryPayload(BaseModel):
|
||||
"""CreateEntryPayload."""
|
||||
|
||||
grams: float
|
||||
product_id: int
|
||||
meal_id: int
|
||||
|
||||
|
||||
class UpdateEntryPayload(BaseModel):
|
||||
"""CreateEntryPayload."""
|
||||
|
||||
grams: Optional[float] = None
|
||||
product_id: Optional[int] = None
|
||||
meal_id: Optional[int] = None
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .entry import Entry
|
||||
|
||||
|
||||
class Meal(BaseModel):
|
||||
"""Meal."""
|
||||
|
||||
id: int
|
||||
name: str
|
||||
order: int
|
||||
calories: float
|
||||
protein: float
|
||||
carb: float
|
||||
fat: float
|
||||
fiber: float
|
||||
entries: List[Entry]
|
||||
diary_id: int
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class CreateMealPayload(BaseModel):
|
||||
"""CreateMealPayload."""
|
||||
|
||||
name: Optional[str]
|
||||
diary_id: int
|
||||
|
||||
|
||||
class RenameMealPayload(BaseModel):
|
||||
"""RenameMealPayload."""
|
||||
|
||||
name: str
|
||||
|
||||
|
||||
class SaveMealPayload(BaseModel):
|
||||
"""SaveMealPayload."""
|
||||
|
||||
name: Optional[str]
|
||||
|
||||
|
||||
class CreateMealFromPresetPayload(BaseModel):
|
||||
"""CreateMealPayload."""
|
||||
|
||||
name: Optional[str]
|
||||
diary_id: int
|
||||
preset_id: int
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
from typing import List
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .preset_entry import PresetEntry
|
||||
|
||||
|
||||
class Preset(BaseModel):
|
||||
"""Preset."""
|
||||
|
||||
id: int
|
||||
name: str
|
||||
calories: float
|
||||
protein: float
|
||||
carb: float
|
||||
fat: float
|
||||
fiber: float
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class PresetDetails(Preset):
|
||||
"""PresetDetails."""
|
||||
|
||||
entries: List[PresetEntry]
|
||||
|
||||
|
||||
class ListPresetsPayload(BaseModel):
|
||||
"""ListPresetsPayload."""
|
||||
|
||||
presets: List[Preset]
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
from pydantic import BaseModel
|
||||
|
||||
from .product import Product
|
||||
|
||||
|
||||
class PresetEntry(BaseModel):
|
||||
"""PresetEntry."""
|
||||
|
||||
id: int
|
||||
grams: float
|
||||
product: Product
|
||||
preset_id: int
|
||||
calories: float
|
||||
protein: float
|
||||
carb: float
|
||||
fat: float
|
||||
fiber: float
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
username: str
|
||||
|
||||
|
||||
class CreateUserPayload(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
|
|
@ -15,8 +15,6 @@ class Settings(BaseSettings):
|
|||
|
||||
ALLOWED_ORIGINS: list[str] = ["*"]
|
||||
|
||||
API_KEY: str
|
||||
|
||||
PASSWORD_SCHEMES: list[str] = ["bcrypt"]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
from datetime import date
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
|
||||
from ..controller.diary import GetDiary
|
||||
from ..model.diary import Diary
|
||||
|
||||
router = APIRouter(tags=["diary"])
|
||||
|
||||
|
||||
@router.get("", response_model=Diary)
|
||||
async def get_diary(
|
||||
request: Request,
|
||||
date: date,
|
||||
controller: GetDiary = Depends(GetDiary),
|
||||
):
|
||||
return await controller.call(date)
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
from fastapi import APIRouter, Depends, Request
|
||||
|
||||
from ..controller.entry import CreateEntry, DeleteEntry, UpdateEntry
|
||||
from ..model.entry import CreateEntryPayload, Entry, UpdateEntryPayload
|
||||
|
||||
router = APIRouter(tags=["entry"])
|
||||
|
||||
|
||||
@router.post("", response_model=Entry)
|
||||
async def create_entry(
|
||||
request: Request,
|
||||
data: CreateEntryPayload,
|
||||
contoller: CreateEntry = Depends(CreateEntry),
|
||||
):
|
||||
return await contoller.call(data)
|
||||
|
||||
|
||||
@router.patch("/{entry_id}", response_model=Entry)
|
||||
async def update_entry(
|
||||
request: Request,
|
||||
entry_id: int,
|
||||
data: UpdateEntryPayload,
|
||||
contoller: UpdateEntry = Depends(UpdateEntry),
|
||||
):
|
||||
return await contoller.call(entry_id, data)
|
||||
|
||||
|
||||
@router.delete("/{entry_id}")
|
||||
async def delete_entry(
|
||||
request: Request,
|
||||
entry_id: int,
|
||||
contoller: DeleteEntry = Depends(DeleteEntry),
|
||||
):
|
||||
return await contoller.call(entry_id)
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
from fastapi import APIRouter, Depends, Request
|
||||
|
||||
from ..controller.meal import CreateMeal, CreateMealFromPreset, DeleteMeal, RenameMeal, SaveMeal
|
||||
from ..model.meal import (
|
||||
CreateMealFromPresetPayload,
|
||||
CreateMealPayload,
|
||||
Meal,
|
||||
RenameMealPayload,
|
||||
SaveMealPayload,
|
||||
)
|
||||
from ..model.preset import Preset
|
||||
|
||||
router = APIRouter(tags=["meal"])
|
||||
|
||||
|
||||
@router.post("", response_model=Meal)
|
||||
async def create_meal(
|
||||
request: Request,
|
||||
data: CreateMealPayload,
|
||||
contoller: CreateMeal = Depends(CreateMeal),
|
||||
):
|
||||
return await contoller.call(data)
|
||||
|
||||
|
||||
@router.post("/{meal_id}/save", response_model=Preset)
|
||||
async def save_meal(
|
||||
request: Request,
|
||||
meal_id: int,
|
||||
data: SaveMealPayload,
|
||||
contoller: SaveMeal = Depends(SaveMeal),
|
||||
):
|
||||
return await contoller.call(meal_id, data)
|
||||
|
||||
|
||||
@router.patch("/{meal_id}", response_model=Meal)
|
||||
async def rename_meal(
|
||||
request: Request,
|
||||
meal_id: int,
|
||||
data: RenameMealPayload,
|
||||
contoller: RenameMeal = Depends(RenameMeal),
|
||||
):
|
||||
return await contoller.call(meal_id, data)
|
||||
|
||||
|
||||
@router.delete("/{meal_id}")
|
||||
async def delete_meal(
|
||||
request: Request,
|
||||
meal_id: int,
|
||||
contoller: DeleteMeal = Depends(DeleteMeal),
|
||||
):
|
||||
return await contoller.call(meal_id)
|
||||
|
||||
|
||||
@router.post("/from_preset", response_model=Meal)
|
||||
async def create_meal_from_preset(
|
||||
request: Request,
|
||||
data: CreateMealFromPresetPayload,
|
||||
contoller: CreateMealFromPreset = Depends(CreateMealFromPreset),
|
||||
):
|
||||
return await contoller.call(data)
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
from fastapi import APIRouter, Depends, Request
|
||||
|
||||
from ..controller.preset import DeletePreset, GetPreset, ListPresets
|
||||
from ..model.preset import ListPresetsPayload, PresetDetails
|
||||
|
||||
router = APIRouter(tags=["preset"])
|
||||
|
||||
|
||||
@router.get("", response_model=ListPresetsPayload)
|
||||
async def list_presets(
|
||||
request: Request,
|
||||
limit: int = 10,
|
||||
offset: int = 0,
|
||||
q: str | None = None,
|
||||
controller: ListPresets = Depends(ListPresets),
|
||||
):
|
||||
return ListPresetsPayload(
|
||||
presets=[p async for p in controller.call(limit=limit, offset=offset, q=q)]
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{preset_id}", response_model=PresetDetails)
|
||||
async def get_preset(
|
||||
request: Request,
|
||||
preset_id: int,
|
||||
controller: GetPreset = Depends(GetPreset),
|
||||
):
|
||||
return await controller.call(preset_id)
|
||||
|
||||
|
||||
@router.delete("/{preset_id}")
|
||||
async def delete_preset(
|
||||
request: Request,
|
||||
preset_id: int,
|
||||
controller: DeletePreset = Depends(DeletePreset),
|
||||
):
|
||||
await controller.call(preset_id)
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
from fastapi import APIRouter, Depends, Request
|
||||
|
||||
from ..controller.tasks import CacheProductUsageData
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["tasks"])
|
||||
|
||||
|
||||
@router.post("/cache_product_usage_data")
|
||||
async def cache_product_usage_data(
|
||||
request: Request,
|
||||
contoller: CacheProductUsageData = Depends(CacheProductUsageData),
|
||||
):
|
||||
return await contoller.call()
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
from fastapi import APIRouter, Depends, Request
|
||||
|
||||
from fooder.controller.user import CreateUser
|
||||
from fooder.model.user import CreateUserPayload, User
|
||||
|
||||
router = APIRouter(tags=["user"])
|
||||
|
||||
|
||||
@router.post("", response_model=User)
|
||||
async def create_user(
|
||||
request: Request,
|
||||
data: CreateUserPayload,
|
||||
contoller: CreateUser = Depends(CreateUser),
|
||||
):
|
||||
return await contoller.call(data)
|
||||
3
mypy.ini
3
mypy.ini
|
|
@ -10,6 +10,3 @@ platform = linux
|
|||
|
||||
warn_unused_configs = True
|
||||
warn_unused_ignores = True
|
||||
|
||||
[mypy-fooder.controller.*]
|
||||
disable_error_code=override
|
||||
|
|
|
|||
Loading…
Reference in a new issue