feat: re-write get all routes to use pagination (#1424)

rewrite get_all routes to use a pagination pattern to allow for better implementations of search, filter, and sorting on the frontend or by any client without fetching all the data. Additionally we added a CI check for running the Nuxt built to confirm that no TS errors were present. Finally, I had to remove the header support for the Shopping lists as the browser caching based off last_updated header was not allowing it to read recent updates due to how we're handling the updated_at property in the database with nested fields. This will have to be looked at in the future to reimplement. I'm unsure how many other routes have a similar issue. 

Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
This commit is contained in:
Michael Genson
2022-06-25 14:39:38 -05:00
committed by GitHub
parent c158672d12
commit cb15db2d27
55 changed files with 683 additions and 197 deletions

View File

@@ -5,9 +5,9 @@ from pydantic import UUID4
from mealie.schema.group.group import GroupAdminUpdate
from mealie.schema.mapper import mapper
from mealie.schema.query import GetAll
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.response.responses import ErrorResponse
from mealie.schema.user.user import GroupBase, GroupInDB
from mealie.schema.user.user import GroupBase, GroupInDB, GroupPagination
from mealie.services.group_services.group_service import GroupService
from .._base import BaseAdminController, controller
@@ -39,9 +39,15 @@ class AdminUserManagementRoutes(BaseAdminController):
self.registered_exceptions,
)
@router.get("", response_model=list[GroupInDB])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, override=GroupInDB)
@router.get("", response_model=GroupPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=GroupInDB,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=GroupInDB, status_code=status.HTTP_201_CREATED)
def create_one(self, data: GroupBase):

View File

@@ -7,9 +7,9 @@ from mealie.core import security
from mealie.routes._base import BaseAdminController, controller
from mealie.routes._base.dependencies import SharedDependencies
from mealie.routes._base.mixins import HttpRepo
from mealie.schema.query import GetAll
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.response.responses import ErrorResponse
from mealie.schema.user.user import UserIn, UserOut
from mealie.schema.user.user import UserIn, UserOut, UserPagination
router = APIRouter(prefix="/users", tags=["Admin: Users"])
@@ -32,9 +32,15 @@ class AdminUserManagementRoutes(BaseAdminController):
def mixins(self):
return HttpRepo[UserIn, UserOut, UserOut](self.repo, self.deps.logger, self.registered_exceptions)
@router.get("", response_model=list[UserOut])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, override=UserOut)
@router.get("", response_model=UserPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=UserOut,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=UserOut, status_code=201)
def create_one(self, data: UserIn):

View File

@@ -1,8 +1,9 @@
from fastapi import BackgroundTasks
from fastapi import BackgroundTasks, Depends
from mealie.routes._base import BaseAdminController, controller
from mealie.routes._base.routers import UserAPIRouter
from mealie.schema.server.tasks import ServerTask, ServerTaskNames
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.server.tasks import ServerTask, ServerTaskNames, ServerTaskPagination
from mealie.services.server_tasks import BackgroundExecutor, test_executor_func
router = UserAPIRouter()
@@ -10,9 +11,15 @@ router = UserAPIRouter()
@controller(router)
class AdminServerTasksController(BaseAdminController):
@router.get("/server-tasks", response_model=list[ServerTask])
def get_all(self):
return self.repos.server_tasks.get_all(order_by="created_at")
@router.get("/server-tasks", response_model=ServerTaskPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repos.server_tasks.page_all(
pagination=q,
override=ServerTask,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("/server-tasks", response_model=ServerTask, status_code=201)
def create_test_tasks(self, bg_tasks: BackgroundTasks):

View File

@@ -8,13 +8,14 @@ from mealie.core.exceptions import mealie_registered_exceptions
from mealie.routes._base.base_controllers import BaseUserController
from mealie.routes._base.controller import controller
from mealie.routes._base.mixins import HttpRepo
from mealie.schema.query import GetAll
from mealie.schema.recipe.recipe_comments import (
RecipeCommentCreate,
RecipeCommentOut,
RecipeCommentPagination,
RecipeCommentSave,
RecipeCommentUpdate,
)
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.response.responses import ErrorResponse, SuccessResponse
router = APIRouter(prefix="/comments", tags=["Recipe: Comments"])
@@ -38,12 +39,18 @@ class RecipeCommentRoutes(BaseUserController):
if comment.user_id != self.deps.acting_user.id and not self.deps.acting_user.admin:
raise HTTPException(
status_code=403,
detail=ErrorResponse.response(message="Comment does not belong to user"),
detail=ErrorResponse(message="Comment does not belong to user"),
)
@router.get("", response_model=list[RecipeCommentOut])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, override=RecipeCommentOut)
@router.get("", response_model=RecipeCommentPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=RecipeCommentOut,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=RecipeCommentOut, status_code=201)
def create_one(self, data: RecipeCommentCreate):

View File

@@ -9,6 +9,8 @@ from mealie.routes._base.mixins import HttpRepo
from mealie.routes._base.routers import MealieCrudRoute
from mealie.schema import mapper
from mealie.schema.cookbook import CreateCookBook, ReadCookBook, RecipeCookBook, SaveCookBook, UpdateCookBook
from mealie.schema.cookbook.cookbook import CookBookPagination
from mealie.schema.response.pagination import PaginationQuery
from mealie.services.event_bus_service.event_bus_service import EventBusService, EventSource
from mealie.services.event_bus_service.message_types import EventTypes
@@ -38,11 +40,15 @@ class GroupCookbookController(BaseUserController):
self.registered_exceptions,
)
@router.get("", response_model=list[ReadCookBook])
def get_all(self):
items = self.repo.get_all()
items.sort(key=lambda x: x.position)
return items
@router.get("", response_model=CookBookPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=ReadCookBook,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=ReadCookBook, status_code=201)
def create_one(self, data: CreateCookBook):

View File

@@ -13,9 +13,10 @@ from mealie.schema.group.group_events import (
GroupEventNotifierPrivate,
GroupEventNotifierSave,
GroupEventNotifierUpdate,
GroupEventPagination,
)
from mealie.schema.mapper import cast
from mealie.schema.query import GetAll
from mealie.schema.response.pagination import PaginationQuery
from mealie.services.event_bus_service.event_bus_service import EventBusService
router = APIRouter(
@@ -41,9 +42,15 @@ class GroupEventsNotifierController(BaseUserController):
def mixins(self) -> HttpRepo:
return HttpRepo(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
@router.get("", response_model=list[GroupEventNotifierOut])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit)
@router.get("", response_model=GroupEventPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=GroupEventNotifierOut,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=GroupEventNotifierOut, status_code=201)
def create_one(self, data: GroupEventNotifierCreate):

View File

@@ -14,8 +14,9 @@ from mealie.schema.labels import (
MultiPurposeLabelSummary,
MultiPurposeLabelUpdate,
)
from mealie.schema.labels.multi_purpose_label import MultiPurposeLabelPagination
from mealie.schema.mapper import cast
from mealie.schema.query import GetAll
from mealie.schema.response.pagination import PaginationQuery
router = APIRouter(prefix="/groups/labels", tags=["Group: Multi Purpose Labels"], route_class=MealieCrudRoute)
@@ -36,9 +37,15 @@ class MultiPurposeLabelsController(BaseUserController):
def mixins(self) -> HttpRepo:
return HttpRepo(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
@router.get("", response_model=list[MultiPurposeLabelSummary])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, override=MultiPurposeLabelSummary)
@router.get("", response_model=MultiPurposeLabelPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=MultiPurposeLabelSummary,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=MultiPurposeLabelOut)
def create_one(self, data: MultiPurposeLabelCreate):

View File

@@ -1,5 +1,6 @@
from functools import cached_property
from fastapi import Depends
from pydantic import UUID4
from mealie.routes._base.base_controllers import BaseUserController
@@ -7,7 +8,8 @@ from mealie.routes._base.controller import controller
from mealie.routes._base.mixins import HttpRepo
from mealie.routes._base.routers import UserAPIRouter
from mealie.schema import mapper
from mealie.schema.meal_plan.plan_rules import PlanRulesCreate, PlanRulesOut, PlanRulesSave
from mealie.schema.meal_plan.plan_rules import PlanRulesCreate, PlanRulesOut, PlanRulesPagination, PlanRulesSave
from mealie.schema.response.pagination import PaginationQuery
router = UserAPIRouter(prefix="/groups/mealplans/rules", tags=["Groups: Mealplan Rules"])
@@ -22,9 +24,15 @@ class GroupMealplanConfigController(BaseUserController):
def mixins(self):
return HttpRepo[PlanRulesCreate, PlanRulesOut, PlanRulesOut](self.repo, self.deps.logger)
@router.get("", response_model=list[PlanRulesOut])
def get_all(self):
return self.repo.get_all(override=PlanRulesOut)
@router.get("", response_model=PlanRulesPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=PlanRulesOut,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=PlanRulesOut, status_code=201)
def create_one(self, data: PlanRulesCreate):

View File

@@ -6,27 +6,25 @@ from pydantic import UUID4
from mealie.routes._base.base_controllers import BaseUserController
from mealie.routes._base.controller import controller
from mealie.routes._base.mixins import HttpRepo
from mealie.routes._base.routers import MealieCrudRoute
from mealie.schema.group.group_shopping_list import (
ShoppingListCreate,
ShoppingListItemCreate,
ShoppingListItemOut,
ShoppingListItemUpdate,
ShoppingListOut,
ShoppingListPagination,
ShoppingListSave,
ShoppingListSummary,
ShoppingListUpdate,
)
from mealie.schema.mapper import cast
from mealie.schema.query import GetAll
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.response.responses import SuccessResponse
from mealie.services.event_bus_service.event_bus_service import EventBusService, EventSource
from mealie.services.event_bus_service.message_types import EventTypes
from mealie.services.group_services.shopping_lists import ShoppingListService
item_router = APIRouter(
prefix="/groups/shopping/items", tags=["Group: Shopping List Items"], route_class=MealieCrudRoute
)
item_router = APIRouter(prefix="/groups/shopping/items", tags=["Group: Shopping List Items"])
@controller(item_router)
@@ -98,7 +96,6 @@ class ShoppingListItemController(BaseUserController):
return shopping_list_item
@item_router.head("/{item_id}", response_model=ShoppingListItemOut)
@item_router.get("/{item_id}", response_model=ShoppingListItemOut)
def get_one(self, item_id: UUID4):
return self.mixins.get_one(item_id)
@@ -148,7 +145,7 @@ class ShoppingListItemController(BaseUserController):
return shopping_list_item
router = APIRouter(prefix="/groups/shopping/lists", tags=["Group: Shopping Lists"], route_class=MealieCrudRoute)
router = APIRouter(prefix="/groups/shopping/lists", tags=["Group: Shopping Lists"])
@controller(router)
@@ -170,9 +167,15 @@ class ShoppingListController(BaseUserController):
def mixins(self) -> HttpRepo[ShoppingListCreate, ShoppingListOut, ShoppingListSave]:
return HttpRepo(self.repo, self.deps.logger, self.registered_exceptions, "An unexpected error occurred.")
@router.get("", response_model=list[ShoppingListSummary])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, override=ShoppingListSummary)
@router.get("", response_model=ShoppingListPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=ShoppingListSummary,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=ShoppingListOut, status_code=201)
def create_one(self, data: ShoppingListCreate):
@@ -193,7 +196,6 @@ class ShoppingListController(BaseUserController):
return val
@router.head("/{item_id}", response_model=ShoppingListOut)
@router.get("/{item_id}", response_model=ShoppingListOut)
def get_one(self, item_id: UUID4):
return self.mixins.get_one(item_id)

View File

@@ -7,8 +7,8 @@ from mealie.routes._base.base_controllers import BaseUserController
from mealie.routes._base.controller import controller
from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper
from mealie.schema.group.webhook import CreateWebhook, ReadWebhook, SaveWebhook
from mealie.schema.query import GetAll
from mealie.schema.group.webhook import CreateWebhook, ReadWebhook, SaveWebhook, WebhookPagination
from mealie.schema.response.pagination import PaginationQuery
router = APIRouter(prefix="/groups/webhooks", tags=["Groups: Webhooks"])
@@ -23,9 +23,15 @@ class ReadWebhookController(BaseUserController):
def mixins(self) -> HttpRepo:
return HttpRepo[CreateWebhook, SaveWebhook, CreateWebhook](self.repo, self.deps.logger)
@router.get("", response_model=list[ReadWebhook])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, override=ReadWebhook)
@router.get("", response_model=WebhookPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=ReadWebhook,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=ReadWebhook, status_code=201)
def create_one(self, data: CreateWebhook):

View File

@@ -7,8 +7,9 @@ from mealie.routes._base import BaseUserController, controller
from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper
from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
from mealie.schema.recipe.recipe import RecipeCategory
from mealie.schema.recipe.recipe import RecipeCategory, RecipeCategoryPagination
from mealie.schema.recipe.recipe_category import CategoryBase, CategorySave
from mealie.schema.response.pagination import PaginationQuery
from mealie.services import urls
from mealie.services.event_bus_service.event_bus_service import EventBusService, EventSource
from mealie.services.event_bus_service.message_types import EventTypes
@@ -40,10 +41,16 @@ class RecipeCategoryController(BaseUserController):
def mixins(self):
return HttpRepo(self.repo, self.deps.logger)
@router.get("", response_model=list[RecipeCategory])
def get_all(self):
@router.get("", response_model=RecipeCategoryPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
"""Returns a list of available categories in the database"""
return self.repo.get_all(override=RecipeCategory)
response = self.repo.page_all(
pagination=q,
override=RecipeCategory,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", status_code=201)
def create_one(self, category: CategoryIn):

View File

@@ -7,8 +7,9 @@ from mealie.routes._base import BaseUserController, controller
from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper
from mealie.schema.recipe import RecipeTagResponse, TagIn
from mealie.schema.recipe.recipe import RecipeTag
from mealie.schema.recipe.recipe import RecipeTag, RecipeTagPagination
from mealie.schema.recipe.recipe_category import TagSave
from mealie.schema.response.pagination import PaginationQuery
from mealie.services import urls
from mealie.services.event_bus_service.event_bus_service import EventBusService, EventSource
from mealie.services.event_bus_service.message_types import EventTypes
@@ -29,10 +30,16 @@ class TagController(BaseUserController):
def mixins(self):
return HttpRepo(self.repo, self.deps.logger)
@router.get("")
async def get_all(self):
@router.get("", response_model=RecipeTagPagination)
async def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
"""Returns a list of available tags in the database"""
return self.repo.get_all(override=RecipeTag)
response = self.repo.page_all(
pagination=q,
override=RecipeTag,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.get("/empty")
def get_empty_tags(self):

View File

@@ -7,9 +7,9 @@ from mealie.routes._base.base_controllers import BaseUserController
from mealie.routes._base.controller import controller
from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper
from mealie.schema.query import GetAll
from mealie.schema.recipe.recipe import RecipeTool
from mealie.schema.recipe.recipe import RecipeTool, RecipeToolPagination
from mealie.schema.recipe.recipe_tool import RecipeToolCreate, RecipeToolResponse, RecipeToolSave
from mealie.schema.response.pagination import PaginationQuery
router = APIRouter(prefix="/tools", tags=["Organizer: Tools"])
@@ -24,9 +24,15 @@ class RecipeToolController(BaseUserController):
def mixins(self) -> HttpRepo:
return HttpRepo[RecipeToolCreate, RecipeTool, RecipeToolCreate](self.repo, self.deps.logger)
@router.get("", response_model=list[RecipeTool])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, override=RecipeTool)
@router.get("", response_model=RecipeToolPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=RecipeTool,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=RecipeTool, status_code=201)
def create_one(self, data: RecipeToolCreate):

View File

@@ -20,9 +20,8 @@ from mealie.repos.repository_recipes import RepositoryRecipes
from mealie.routes._base import BaseUserController, controller
from mealie.routes._base.mixins import HttpRepo
from mealie.routes._base.routers import MealieCrudRoute, UserAPIRouter
from mealie.schema.query import GetAll
from mealie.schema.recipe import Recipe, RecipeImageTypes, ScrapeRecipe
from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipeSummary
from mealie.schema.recipe.recipe import CreateRecipe, CreateRecipeByUrlBulk, RecipePaginationQuery, RecipeSummary
from mealie.schema.recipe.recipe_asset import RecipeAsset
from mealie.schema.recipe.recipe_scraper import ScrapeRecipeTest
from mealie.schema.recipe.request_helpers import RecipeZipTokenResponse, UpdateImageResponse
@@ -53,10 +52,6 @@ class BaseRecipeController(BaseUserController):
return HttpRepo[CreateRecipe, Recipe, Recipe](self.repo, self.deps.logger)
class RecipeGetAll(GetAll):
load_food: bool = False
class FormatResponse(BaseModel):
jjson: list[str] = Field(..., alias="json")
zip: list[str]
@@ -196,18 +191,16 @@ class RecipeController(BaseRecipeController):
# CRUD Operations
@router.get("", response_model=list[RecipeSummary])
def get_all(self, q: RecipeGetAll = Depends(RecipeGetAll)):
items = self.repo.summary(
self.user.group_id,
start=q.start,
limit=q.limit,
load_foods=q.load_food,
order_by=q.order_by,
order_descending=q.order_descending,
def get_all(self, q: RecipePaginationQuery = Depends(RecipePaginationQuery)):
response = self.repo.page_all(
pagination=q,
load_food=q.load_food,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
new_items = []
for item in items:
for item in response.items:
# Pydantic/FastAPI can't seem to serialize the ingredient field on thier own.
new_item = item.__dict__
@@ -216,10 +209,11 @@ class RecipeController(BaseRecipeController):
new_items.append(new_item)
json_compatible_item_data = jsonable_encoder(RecipeSummary.construct(**x) for x in new_items)
response.items = [RecipeSummary.construct(**x) for x in new_items]
json_compatible_response = jsonable_encoder(response)
# Response is returned directly, to avoid validation and improve performance
return JSONResponse(content=json_compatible_item_data)
return JSONResponse(content=json_compatible_response)
@router.get("/{slug}", response_model=Recipe)
def get_one(self, slug: str):

View File

@@ -8,8 +8,14 @@ from mealie.routes._base.controller import controller
from mealie.routes._base.mixins import HttpRepo
from mealie.routes._base.routers import MealieCrudRoute
from mealie.schema import mapper
from mealie.schema.query import GetAll
from mealie.schema.recipe.recipe_ingredient import CreateIngredientFood, IngredientFood, MergeFood, SaveIngredientFood
from mealie.schema.recipe.recipe_ingredient import (
CreateIngredientFood,
IngredientFood,
IngredientFoodPagination,
MergeFood,
SaveIngredientFood,
)
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.response.responses import SuccessResponse
router = APIRouter(prefix="/foods", tags=["Recipes: Foods"], route_class=MealieCrudRoute)
@@ -38,9 +44,15 @@ class IngredientFoodsController(BaseUserController):
self.deps.logger.error(e)
raise HTTPException(500, "Failed to merge foods") from e
@router.get("", response_model=list[IngredientFood])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, order_by=q.order_by, order_descending=q.order_descending)
@router.get("", response_model=IngredientFoodPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=IngredientFood,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=IngredientFood, status_code=201)
def create_one(self, data: CreateIngredientFood):

View File

@@ -8,8 +8,14 @@ from mealie.routes._base.controller import controller
from mealie.routes._base.mixins import HttpRepo
from mealie.routes._base.routers import MealieCrudRoute
from mealie.schema import mapper
from mealie.schema.query import GetAll
from mealie.schema.recipe.recipe_ingredient import CreateIngredientUnit, IngredientUnit, MergeUnit, SaveIngredientUnit
from mealie.schema.recipe.recipe_ingredient import (
CreateIngredientUnit,
IngredientUnit,
IngredientUnitPagination,
MergeUnit,
SaveIngredientUnit,
)
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.response.responses import SuccessResponse
router = APIRouter(prefix="/units", tags=["Recipes: Units"], route_class=MealieCrudRoute)
@@ -38,9 +44,15 @@ class IngredientUnitsController(BaseUserController):
self.deps.logger.error(e)
raise HTTPException(500, "Failed to merge units") from e
@router.get("", response_model=list[IngredientUnit])
def get_all(self, q: GetAll = Depends(GetAll)):
return self.repo.get_all(start=q.start, limit=q.limit, order_by=q.order_by, order_descending=q.order_descending)
@router.get("", response_model=IngredientUnitPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repo.page_all(
pagination=q,
override=IngredientUnit,
)
response.set_pagination_guides(router.url_path_for("get_all"), q.dict())
return response
@router.post("", response_model=IngredientUnit, status_code=201)
def create_one(self, data: CreateIngredientUnit):

View File

@@ -1,4 +1,4 @@
from fastapi import HTTPException, status
from fastapi import Depends, HTTPException, status
from pydantic import UUID4
from mealie.core.security import hash_password, verify_password
@@ -8,7 +8,9 @@ from mealie.routes._base.mixins import HttpRepo
from mealie.routes._base.routers import AdminAPIRouter, UserAPIRouter
from mealie.routes.users._helpers import assert_user_change_allowed
from mealie.schema.response import ErrorResponse, SuccessResponse
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.user import ChangePassword, UserBase, UserIn, UserOut
from mealie.schema.user.user import UserPagination
user_router = UserAPIRouter(prefix="/users", tags=["Users: CRUD"])
admin_router = AdminAPIRouter(prefix="/users", tags=["Users: Admin CRUD"])
@@ -20,9 +22,15 @@ class AdminUserController(BaseAdminController):
def mixins(self) -> HttpRepo:
return HttpRepo[UserIn, UserOut, UserBase](self.repos.users, self.deps.logger)
@admin_router.get("", response_model=list[UserOut])
def get_all_users(self):
return self.repos.users.get_all()
@admin_router.get("", response_model=UserPagination)
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
response = self.repos.users.page_all(
pagination=q,
override=UserOut,
)
response.set_pagination_guides(admin_router.url_path_for("get_all"), q.dict())
return response
@admin_router.post("", response_model=UserOut, status_code=201)
def create_user(self, new_user: UserIn):