munch-ease-backend/main.py
2024-01-13 17:59:35 +11:00

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