mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-05 13:35:23 +02:00
api documentation
This commit is contained in:
parent
53b4717810
commit
36db9f2e86
8 changed files with 175 additions and 41 deletions
|
@ -1,4 +1,3 @@
|
|||
# from datetime import datetime
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
|
12
mealie/models/migration_models.py
Normal file
12
mealie/models/migration_models.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
from pydantic.main import BaseModel
|
||||
|
||||
|
||||
class ChowdownURL(BaseModel):
|
||||
url: str
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"url": "https://chowdownrepo.com/repo",
|
||||
}
|
||||
}
|
56
mealie/models/recipe_models.py
Normal file
56
mealie/models/recipe_models.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from typing import List, Optional
|
||||
|
||||
import pydantic
|
||||
from pydantic.main import BaseModel
|
||||
|
||||
|
||||
class RecipeResponse(BaseModel):
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": [
|
||||
{
|
||||
"slug": "crockpot-buffalo-chicken",
|
||||
"image": "crockpot-buffalo-chicken.jpg",
|
||||
"name": "Crockpot Buffalo Chicken",
|
||||
},
|
||||
{
|
||||
"slug": "downtown-marinade",
|
||||
"image": "downtown-marinade.jpg",
|
||||
"name": "Downtown Marinade",
|
||||
},
|
||||
{
|
||||
"slug": "detroit-style-pepperoni-pizza",
|
||||
"image": "detroit-style-pepperoni-pizza.jpg",
|
||||
"name": "Detroit-Style Pepperoni Pizza",
|
||||
},
|
||||
{
|
||||
"slug": "crispy-carrots",
|
||||
"image": "crispy-carrots.jpg",
|
||||
"name": "Crispy Carrots",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
class AllRecipeRequest(BaseModel):
|
||||
properties: List[str]
|
||||
limit: Optional[int]
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"properties": ["name", "slug", "image"],
|
||||
"limit": 100,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RecipeURLIn(BaseModel):
|
||||
class Config:
|
||||
schema_extra = {"example": {"url": "https://myfavoriterecipes.com/recipes"}}
|
||||
|
||||
class SlugResponse(BaseModel):
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": "adult-mac-and-cheese"
|
||||
}
|
|
@ -1,22 +1,23 @@
|
|||
from pprint import pprint
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from models.recipe_models import SlugResponse
|
||||
from services.meal_services import MealPlan
|
||||
from utils.snackbar import SnackResponse
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/api/meal-plan/all/", tags=["Meal Plan"])
|
||||
@router.get("/api/meal-plan/all/", tags=["Meal Plan"], response_model=List[MealPlan])
|
||||
async def get_all_meals():
|
||||
""" Returns a list of all available meal plans """
|
||||
""" Returns a list of all available Meal Plan """
|
||||
|
||||
return MealPlan.get_all()
|
||||
|
||||
|
||||
@router.post("/api/meal-plan/create/", tags=["Meal Plan"])
|
||||
async def set_meal_plan(data: MealPlan):
|
||||
""" Creates a mealplan database entry"""
|
||||
""" Creates a meal plan database entry """
|
||||
data.process_meals()
|
||||
data.save_to_db()
|
||||
|
||||
|
@ -30,7 +31,7 @@ async def set_meal_plan(data: MealPlan):
|
|||
|
||||
@router.post("/api/meal-plan/{plan_id}/update/", tags=["Meal Plan"])
|
||||
async def update_meal_plan(plan_id: str, meal_plan: MealPlan):
|
||||
""" Updates a Meal Plan Based off ID """
|
||||
""" Updates a meal plan based off ID """
|
||||
|
||||
try:
|
||||
meal_plan.process_meals()
|
||||
|
@ -46,21 +47,24 @@ async def update_meal_plan(plan_id: str, meal_plan: MealPlan):
|
|||
|
||||
@router.delete("/api/meal-plan/{plan_id}/delete/", tags=["Meal Plan"])
|
||||
async def delete_meal_plan(plan_id):
|
||||
""" Doc Str """
|
||||
""" Removes a meal plan from the database """
|
||||
|
||||
MealPlan.delete(plan_id)
|
||||
|
||||
return SnackResponse.success("Mealplan Deleted")
|
||||
|
||||
|
||||
@router.get("/api/meal-plan/today/", tags=["Meal Plan"])
|
||||
@router.get("/api/meal-plan/today/", tags=["Meal Plan"], response_model=SlugResponse)
|
||||
async def get_today():
|
||||
""" Returns the meal plan data for today """
|
||||
"""
|
||||
Returns the recipe slug for the meal scheduled for today.
|
||||
If no meal is scheduled nothing is returned
|
||||
"""
|
||||
|
||||
return MealPlan.today()
|
||||
|
||||
|
||||
@router.get("/api/meal-plan/this-week/", tags=["Meal Plan"])
|
||||
@router.get("/api/meal-plan/this-week/", tags=["Meal Plan"], response_model=MealPlan)
|
||||
async def get_this_week():
|
||||
""" Returns the meal plan data for this week """
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from fastapi import APIRouter, HTTPException
|
||||
from models.backup_models import BackupJob
|
||||
from models.migration_models import ChowdownURL
|
||||
from services.migrations.chowdown import chowdown_migrate as chowdow_migrate
|
||||
from utils.snackbar import SnackResponse
|
||||
|
||||
|
@ -7,10 +8,10 @@ router = APIRouter()
|
|||
|
||||
|
||||
@router.post("/api/migration/chowdown/repo/", tags=["Migration"])
|
||||
async def import_chowdown_recipes(repo: dict):
|
||||
async def import_chowdown_recipes(repo: ChowdownURL):
|
||||
""" Import Chowsdown Recipes from Repo URL """
|
||||
try:
|
||||
report = chowdow_migrate(repo.get("url"))
|
||||
report = chowdow_migrate(repo.url)
|
||||
return SnackResponse.success(
|
||||
"Recipes Imported from Git Repo, see report for failures.",
|
||||
additional_data=report,
|
||||
|
|
|
@ -2,6 +2,12 @@ from typing import List, Optional
|
|||
|
||||
from fastapi import APIRouter, File, Form, HTTPException, Query
|
||||
from fastapi.responses import FileResponse
|
||||
from models.recipe_models import (
|
||||
AllRecipeRequest,
|
||||
RecipeResponse,
|
||||
RecipeURLIn,
|
||||
SlugResponse,
|
||||
)
|
||||
from services.image_services import read_image, write_image
|
||||
from services.recipe_services import Recipe, read_requested_values
|
||||
from services.scrape_services import create_from_url
|
||||
|
@ -10,17 +16,42 @@ from utils.snackbar import SnackResponse
|
|||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/api/all-recipes/", tags=["Recipes"])
|
||||
@router.get("/api/all-recipes/", tags=["Recipes"], response_model=RecipeResponse)
|
||||
async def get_all_recipes(
|
||||
keys: Optional[List[str]] = Query(...), num: Optional[int] = 100
|
||||
) -> Optional[List[str]]:
|
||||
""" Returns key data for all recipes """
|
||||
):
|
||||
"""
|
||||
Returns key data for all recipes based off the query paramters provided.
|
||||
For example, if slug, image, and name are provided you will recieve a list of
|
||||
recipes containing the slug, image, and name property. By default, responses
|
||||
are limited to 100.
|
||||
|
||||
**Note:** You may experience problems with with query parameters. As an alternative
|
||||
you may also use the post method and provide a body.
|
||||
See the *Post* method for more details.
|
||||
"""
|
||||
|
||||
all_recipes = read_requested_values(keys, num)
|
||||
return all_recipes
|
||||
|
||||
|
||||
@router.get("/api/recipe/{recipe_slug}/", tags=["Recipes"])
|
||||
@router.post("/api/all-recipes/", tags=["Recipes"], response_model=RecipeResponse)
|
||||
async def get_all_recipes_post(body: AllRecipeRequest):
|
||||
"""
|
||||
Returns key data for all recipes based off the body data provided.
|
||||
For example, if slug, image, and name are provided you will recieve a list of
|
||||
recipes containing the slug, image, and name property.
|
||||
|
||||
Refer to the body example for data formats.
|
||||
|
||||
"""
|
||||
|
||||
all_recipes = read_requested_values(body.properties, body.limit)
|
||||
|
||||
return all_recipes
|
||||
|
||||
|
||||
@router.get("/api/recipe/{recipe_slug}/", tags=["Recipes"], response_model=Recipe)
|
||||
async def get_recipe(recipe_slug: str):
|
||||
""" Takes in a recipe slug, returns all data for a recipe """
|
||||
recipe = Recipe.get_by_slug(recipe_slug)
|
||||
|
@ -37,24 +68,21 @@ async def get_recipe_img(recipe_slug: str):
|
|||
|
||||
|
||||
# Recipe Creations
|
||||
@router.post("/api/recipe/create-url/", tags=["Recipes"], status_code=201)
|
||||
async def get_recipe_url(url: dict):
|
||||
""" Takes in a URL and Attempts to scrape data and load it into the database """
|
||||
@router.post(
|
||||
"/api/recipe/create-url/",
|
||||
tags=["Recipes"],
|
||||
status_code=201,
|
||||
response_model=SlugResponse,
|
||||
)
|
||||
async def parse_recipe_url(url: RecipeURLIn):
|
||||
""" Takes in a URL and attempts to scrape data and load it into the database """
|
||||
|
||||
url = url.get("url")
|
||||
slug = create_from_url(url)
|
||||
|
||||
# try:
|
||||
# slug = create_from_url(url)
|
||||
# except:
|
||||
# raise HTTPException(
|
||||
# status_code=400, detail=SnackResponse.error("Unable to Parse URL")
|
||||
# )
|
||||
slug = create_from_url(url.url)
|
||||
|
||||
return slug
|
||||
|
||||
|
||||
@router.post("/api/recipe/create/", tags=["Recipes"])
|
||||
@router.post("/api/recipe/create/", tags=["Recipes"], response_model=SlugResponse)
|
||||
async def create_from_json(data: Recipe) -> str:
|
||||
""" Takes in a JSON string and loads data into the database as a new entry"""
|
||||
created_recipe = data.save_to_db()
|
||||
|
@ -63,7 +91,7 @@ async def create_from_json(data: Recipe) -> str:
|
|||
|
||||
|
||||
@router.post("/api/recipe/{recipe_slug}/update/image/", tags=["Recipes"])
|
||||
def update_image(
|
||||
def update_recipe_image(
|
||||
recipe_slug: str, image: bytes = File(...), extension: str = Form(...)
|
||||
):
|
||||
""" Removes an existing image and replaces it with the incoming file. """
|
||||
|
@ -73,7 +101,7 @@ def update_image(
|
|||
|
||||
|
||||
@router.post("/api/recipe/{recipe_slug}/update/", tags=["Recipes"])
|
||||
async def update(recipe_slug: str, data: Recipe):
|
||||
async def update_recipe(recipe_slug: str, data: Recipe):
|
||||
""" Updates a recipe by existing slug and data. Data should containt """
|
||||
|
||||
data.update(recipe_slug)
|
||||
|
@ -82,7 +110,7 @@ async def update(recipe_slug: str, data: Recipe):
|
|||
|
||||
|
||||
@router.delete("/api/recipe/{recipe_slug}/delete/", tags=["Recipes"])
|
||||
async def delete(recipe_slug: str):
|
||||
async def delete_recipe(recipe_slug: str):
|
||||
""" Deletes a recipe by slug """
|
||||
|
||||
try:
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from typing import List
|
||||
|
||||
from db.mongo_setup import global_init
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from services.scheduler_services import Scheduler, post_webhooks
|
||||
|
@ -11,16 +13,16 @@ scheduler = Scheduler()
|
|||
scheduler.startup_scheduler()
|
||||
|
||||
|
||||
@router.get("/api/site-settings/", tags=["Settings"])
|
||||
@router.get("/api/site-settings/", tags=["Settings"], response_model=SiteSettings)
|
||||
async def get_main_settings():
|
||||
""" Returns basic site Settings """
|
||||
""" Returns basic site settings """
|
||||
|
||||
return SiteSettings.get_site_settings()
|
||||
|
||||
|
||||
@router.post("/api/site-settings/webhooks/test/", tags=["Settings"])
|
||||
async def test_webhooks():
|
||||
""" Test Webhooks """
|
||||
""" Run the function to test your webhooks """
|
||||
|
||||
return post_webhooks()
|
||||
|
||||
|
@ -40,22 +42,26 @@ async def update_settings(data: SiteSettings):
|
|||
return SnackResponse.success("Settings Updated")
|
||||
|
||||
|
||||
@router.get("/api/site-settings/themes/", tags=["Themes"])
|
||||
@router.get(
|
||||
"/api/site-settings/themes/", tags=["Themes"], response_model=List[SiteTheme]
|
||||
)
|
||||
async def get_all_themes():
|
||||
""" Returns all site themes """
|
||||
|
||||
return SiteTheme.get_all()
|
||||
|
||||
|
||||
@router.get("/api/site-settings/themes/{theme_name}/", tags=["Themes"])
|
||||
@router.get(
|
||||
"/api/site-settings/themes/{theme_name}/", tags=["Themes"], response_model=SiteTheme
|
||||
)
|
||||
async def get_single_theme(theme_name: str):
|
||||
""" Returns basic site Settings """
|
||||
""" Returns a named theme """
|
||||
return SiteTheme.get_by_name(theme_name)
|
||||
|
||||
|
||||
@router.post("/api/site-settings/themes/create/", tags=["Themes"])
|
||||
async def create_theme(data: SiteTheme):
|
||||
""" Creates a Site Color Theme """
|
||||
""" Creates a site color theme database entry """
|
||||
|
||||
try:
|
||||
data.save_to_db()
|
||||
|
@ -69,7 +75,7 @@ async def create_theme(data: SiteTheme):
|
|||
|
||||
@router.post("/api/site-settings/themes/{theme_name}/update/", tags=["Themes"])
|
||||
async def update_theme(theme_name: str, data: SiteTheme):
|
||||
""" Returns basic site Settings """
|
||||
""" Update a theme database entry """
|
||||
try:
|
||||
data.update_document()
|
||||
except:
|
||||
|
@ -82,7 +88,7 @@ async def update_theme(theme_name: str, data: SiteTheme):
|
|||
|
||||
@router.delete("/api/site-settings/themes/{theme_name}/delete/", tags=["Themes"])
|
||||
async def delete_theme(theme_name: str):
|
||||
""" Returns basic site Settings """
|
||||
""" Deletes theme from the database """
|
||||
try:
|
||||
SiteTheme.delete_theme(theme_name)
|
||||
except:
|
||||
|
|
|
@ -24,6 +24,18 @@ class SiteSettings(BaseModel):
|
|||
name: str = "main"
|
||||
webhooks: Webhooks
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"name": "main",
|
||||
"webhooks": {
|
||||
"webhookTime": "00:00",
|
||||
"webhookURLs": ["https://mywebhookurl.com/webhook"],
|
||||
"enable": False,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _unpack_doc(document: SiteSettingsDocument):
|
||||
document = json.loads(document.to_json())
|
||||
|
@ -65,6 +77,22 @@ class SiteTheme(BaseModel):
|
|||
name: str
|
||||
colors: Colors
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"example": {
|
||||
"name": "default",
|
||||
"colors": {
|
||||
"primary": "#E58325",
|
||||
"accent": "#00457A",
|
||||
"secondary": "#973542",
|
||||
"success": "#5AB1BB",
|
||||
"info": "#4990BA",
|
||||
"warning": "#FF4081",
|
||||
"error": "#EF5350",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(theme_name):
|
||||
document = SiteThemeDocument.objects.get(name=theme_name)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue