83 lines
No EOL
2.8 KiB
Python
83 lines
No EOL
2.8 KiB
Python
import sqlite3
|
|
import product, recipe, db
|
|
|
|
from pydantic import BaseModel
|
|
from typing import List, Annotated
|
|
from fastapi import FastAPI, Depends, Query
|
|
from fastapi.responses import JSONResponse
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
app = FastAPI()
|
|
|
|
# Add CORS middleware
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"]
|
|
)
|
|
|
|
# Dependency to create SQLite connection
|
|
async def get_db():
|
|
sql_db = await db.connect()
|
|
try:
|
|
yield sql_db
|
|
finally:
|
|
await sql_db.close()
|
|
|
|
@app.get("/recipes/parse")
|
|
async def parse_recipe_handler(url: str, conn: sqlite3.Connection = Depends(get_db)) -> recipe.Recipe:
|
|
parsed = await recipe.parse_recipe(conn, url)
|
|
if not parsed:
|
|
return JSONResponse(status_code=400, content={'message': 'Recipe not found'})
|
|
return parsed
|
|
|
|
@app.get("/recipes/ingredients/parse")
|
|
async def parse_ingredients(lines: Annotated[
|
|
List[str],
|
|
Query(alias="ingredients",
|
|
title="Array of ingredients to parse")],
|
|
conn: sqlite3.Connection = Depends(get_db)) -> List[recipe.Ingredient]:
|
|
ingredients = recipe.parse_ingredient_from_nlp(lines)
|
|
recipe.match_existing_products(conn, ingredients)
|
|
return ingredients
|
|
|
|
class ProductUrl(BaseModel):
|
|
url: str
|
|
tags: List[str] = []
|
|
|
|
@app.post("/products/")
|
|
async def create_product(url: ProductUrl, conn: sqlite3.Connection = Depends(get_db)) -> product.Product:
|
|
return await product.get_or_create(conn, url.url, url.tags)
|
|
|
|
@app.get("/recipes/{recipe_id}")
|
|
async def get_recipe(recipe_id: int, conn: sqlite3.Connection = Depends(get_db)) -> recipe.Recipe:
|
|
r = await recipe.find_recipe_by_id(conn, recipe_id)
|
|
if not r:
|
|
return JSONResponse(status_code=404, content={'message': 'Recipe not found'})
|
|
|
|
r.ingredients = []
|
|
async for ingredient in recipe.find_ingredients_by_recipe_id(conn, recipe_id):
|
|
ingredient.product = await product.find_product_by_id(conn, ingredient.product_id)
|
|
r.ingredients.append(ingredient)
|
|
|
|
return r
|
|
|
|
@app.post('/recipes/')
|
|
async def create_recipe(item: recipe.Recipe, conn: sqlite3.Connection = Depends(get_db)) -> recipe.Recipe:
|
|
if not item.ingredients:
|
|
return JSONResponse(status_code=400, content={'message': 'Recipe must have at least one ingredient'})
|
|
|
|
for ingredient in item.ingredients:
|
|
if not ingredient.product:
|
|
return JSONResponse(status_code=400, content={'message': 'Ingredient must have a product'})
|
|
|
|
await recipe.insert_recipe(conn, item)
|
|
for ingredient in item.ingredients:
|
|
ingredient.recipe_id = item.id
|
|
ingredient.product_id = ingredient.product.id
|
|
await recipe.insert_ingredient(conn, ingredient)
|
|
await conn.commit()
|
|
|
|
return item |