diff --git a/Dockerfile.cron b/Dockerfile.cron deleted file mode 100644 index 3ed6096..0000000 --- a/Dockerfile.cron +++ /dev/null @@ -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"] diff --git a/Makefile b/Makefile index 6303706..f700749 100644 --- a/Makefile +++ b/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' diff --git a/env.template b/env.template index 06e26c5..015a6ea 100644 --- a/env.template +++ b/env.template @@ -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 diff --git a/fooder/controller_old/__init__.py b/fooder/controller_old/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/fooder/controller_old/base.py b/fooder/controller_old/base.py deleted file mode 100644 index a9948b8..0000000 --- a/fooder/controller_old/base.py +++ /dev/null @@ -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) diff --git a/fooder/controller_old/diary.py b/fooder/controller_old/diary.py deleted file mode 100644 index 42dda75..0000000 --- a/fooder/controller_old/diary.py +++ /dev/null @@ -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]) diff --git a/fooder/controller_old/entry.py b/fooder/controller_old/entry.py deleted file mode 100644 index a2772dc..0000000 --- a/fooder/controller_old/entry.py +++ /dev/null @@ -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]) diff --git a/fooder/controller_old/meal.py b/fooder/controller_old/meal.py deleted file mode 100644 index 42bd5d5..0000000 --- a/fooder/controller_old/meal.py +++ /dev/null @@ -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]) diff --git a/fooder/controller_old/preset.py b/fooder/controller_old/preset.py deleted file mode 100644 index 9ed0367..0000000 --- a/fooder/controller_old/preset.py +++ /dev/null @@ -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) diff --git a/fooder/controller_old/product.py b/fooder/controller_old/product.py deleted file mode 100644 index d4a83ff..0000000 --- a/fooder/controller_old/product.py +++ /dev/null @@ -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]) diff --git a/fooder/controller_old/tasks.py b/fooder/controller_old/tasks.py deleted file mode 100644 index c5f37c8..0000000 --- a/fooder/controller_old/tasks.py +++ /dev/null @@ -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)) diff --git a/fooder/controller_old/token.py b/fooder/controller_old/token.py deleted file mode 100644 index b0b3445..0000000 --- a/fooder/controller_old/token.py +++ /dev/null @@ -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", - ) diff --git a/fooder/controller_old/user.py b/fooder/controller_old/user.py deleted file mode 100644 index de48c9d..0000000 --- a/fooder/controller_old/user.py +++ /dev/null @@ -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]) diff --git a/fooder/model/diary.py b/fooder/model/diary.py deleted file mode 100644 index 3d37f83..0000000 --- a/fooder/model/diary.py +++ /dev/null @@ -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 diff --git a/fooder/model/entry.py b/fooder/model/entry.py deleted file mode 100644 index 98e0225..0000000 --- a/fooder/model/entry.py +++ /dev/null @@ -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 diff --git a/fooder/model/meal.py b/fooder/model/meal.py deleted file mode 100644 index cec9c20..0000000 --- a/fooder/model/meal.py +++ /dev/null @@ -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 diff --git a/fooder/model/preset.py b/fooder/model/preset.py deleted file mode 100644 index cd6559e..0000000 --- a/fooder/model/preset.py +++ /dev/null @@ -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] diff --git a/fooder/model/preset_entry.py b/fooder/model/preset_entry.py deleted file mode 100644 index e0e4add..0000000 --- a/fooder/model/preset_entry.py +++ /dev/null @@ -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 diff --git a/fooder/model/user.py b/fooder/model/user.py deleted file mode 100644 index 3203518..0000000 --- a/fooder/model/user.py +++ /dev/null @@ -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 diff --git a/fooder/settings.py b/fooder/settings.py index 1f29985..b02b68c 100644 --- a/fooder/settings.py +++ b/fooder/settings.py @@ -15,8 +15,6 @@ class Settings(BaseSettings): ALLOWED_ORIGINS: list[str] = ["*"] - API_KEY: str - PASSWORD_SCHEMES: list[str] = ["bcrypt"] diff --git a/fooder/view/diary.py b/fooder/view/diary.py deleted file mode 100644 index c375f85..0000000 --- a/fooder/view/diary.py +++ /dev/null @@ -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) diff --git a/fooder/view/entry.py b/fooder/view/entry.py deleted file mode 100644 index 2ca3f05..0000000 --- a/fooder/view/entry.py +++ /dev/null @@ -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) diff --git a/fooder/view/meal.py b/fooder/view/meal.py deleted file mode 100644 index 40a1f73..0000000 --- a/fooder/view/meal.py +++ /dev/null @@ -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) diff --git a/fooder/view/preset.py b/fooder/view/preset.py deleted file mode 100644 index 9631099..0000000 --- a/fooder/view/preset.py +++ /dev/null @@ -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) diff --git a/fooder/view/tasks.py b/fooder/view/tasks.py deleted file mode 100644 index c2dd672..0000000 --- a/fooder/view/tasks.py +++ /dev/null @@ -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() diff --git a/fooder/view/user.py b/fooder/view/user.py deleted file mode 100644 index 48375d8..0000000 --- a/fooder/view/user.py +++ /dev/null @@ -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) diff --git a/mypy.ini b/mypy.ini index 3358d6b..8e19889 100644 --- a/mypy.ini +++ b/mypy.ini @@ -10,6 +10,3 @@ platform = linux warn_unused_configs = True warn_unused_ignores = True - -[mypy-fooder.controller.*] -disable_error_code=override