77 lines
4 KiB
Python
77 lines
4 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import List, Optional
|
|
|
|
import aiosqlite
|
|
from fastapi import APIRouter, Depends, Query, Request
|
|
|
|
import ingredients
|
|
import recipes
|
|
import persons
|
|
from common import Page, ProblemDetails
|
|
from main import get_db, cookie_person, error_response # temporary imports during extraction
|
|
|
|
router = APIRouter(prefix="/recipes", tags=["recipes"])
|
|
|
|
|
|
@router.get("", response_model=Page[recipes.Recipe], operation_id="listRecipes", summary="List recipes (paginated)")
|
|
async def list_recipes(
|
|
q: Optional[str] = Query(default=None, description="Optional case-insensitive name filter (matches recipe name with SQL LIKE)."),
|
|
cursor: Optional[str] = Query(default=None, description="Opaque cursor for pagination. Pass the value returned in nextCursor to fetch the next page."),
|
|
limit: int = Query(50, ge=1, le=200, description="Maximum number of items to return (1-200)."),
|
|
conn: aiosqlite.Connection = Depends(get_db),
|
|
request: Request | None = None,
|
|
) -> Page[recipes.Recipe]:
|
|
# Placeholder: implementation will be moved from main.get_recipes in a later step.
|
|
raise NotImplementedError("list_recipes extraction pending")
|
|
|
|
|
|
@router.get("/{recipe_id}", response_model=recipes.Recipe, operation_id="getRecipe", summary="Get a single recipe",
|
|
responses={404: {"model": ProblemDetails, "description": "Recipe not found", "content": {"application/problem+json": {}}}})
|
|
async def get_recipe(
|
|
recipe_id: int, conn: aiosqlite.Connection = Depends(get_db), request: Request | None = None
|
|
) -> recipes.Recipe:
|
|
# Placeholder: implementation will be moved from main.get_recipe in a later step.
|
|
raise NotImplementedError("get_recipe extraction pending")
|
|
|
|
|
|
@router.post("", response_model=recipes.Recipe, operation_id="createRecipe", summary="Create a new recipe (versioning semantics applied)",
|
|
responses={400: {"model": ProblemDetails, "description": "Validation error", "content": {"application/problem+json": {}}}})
|
|
async def create_recipe(
|
|
recipe: recipes.Recipe,
|
|
conn: aiosqlite.Connection = Depends(get_db),
|
|
user: persons.Person = Depends(cookie_person),
|
|
request: Request | None = None,
|
|
) -> recipes.Recipe:
|
|
# Placeholder: implementation will be moved from main.create_recipe in a later step.
|
|
raise NotImplementedError("create_recipe extraction pending")
|
|
|
|
|
|
@router.delete("/{recipe_id}", response_model=recipes.Recipe, operation_id="deleteRecipe", summary="Soft-delete (hide) a recipe",
|
|
responses={404: {"model": ProblemDetails, "description": "Recipe not found", "content": {"application/problem+json": {}}}})
|
|
async def delete_recipe(
|
|
recipe_id: int,
|
|
conn: aiosqlite.Connection = Depends(get_db),
|
|
user: persons.Person = Depends(cookie_person),
|
|
request: Request | None = None,
|
|
) -> recipes.Recipe:
|
|
# Placeholder: implementation will be moved from main.delete_recipe in a later step.
|
|
raise NotImplementedError("delete_recipe extraction pending")
|
|
|
|
|
|
@router.get("/parse", response_model=None, operation_id="parseRecipe", summary="Parse a recipe from a URL",
|
|
responses={400: {"model": ProblemDetails, "description": "Recipe not found", "content": {"application/problem+json": {}}}})
|
|
async def parse_recipe_handler(
|
|
url: str, conn: aiosqlite.Connection = Depends(get_db), person=Depends(cookie_person), request: Request | None = None
|
|
) -> recipes.Recipe:
|
|
# Placeholder: implementation will be moved from main.parse_recipe_handler in a later step.
|
|
raise NotImplementedError("parse_recipe_handler extraction pending")
|
|
|
|
|
|
@router.get("/ingredients/parse", operation_id="parseIngredients", summary="Parse raw ingredient lines")
|
|
async def parse_ingredients(
|
|
lines: List[str] = Query(alias="ingredients", title="Array of ingredients to parse"),
|
|
conn: aiosqlite.Connection = Depends(get_db),
|
|
) -> List[ingredients.Ingredient]:
|
|
# Placeholder: implementation will be moved from main.parse_ingredients in a later step.
|
|
raise NotImplementedError("parse_ingredients extraction pending")
|