REST API to manage pizzas with ingredients

master
Thomas L 2020-06-18 06:26:24 +02:00
parent 5f61728536
commit 74ebf1a546
2 changed files with 116 additions and 8 deletions

View File

@ -1,7 +1,7 @@
from fastapi import Depends, FastAPI, HTTPException, Response, status
from logging import getLogger
from ormantic.exceptions import NoMatch
from pizzatool.model import Ingredient
from pizzatool.model import Ingredient, Pizza, PizzaIngredient
logger = getLogger(__name__)
@ -20,23 +20,110 @@ async def create_ingredient(name: str, response: Response):
return ingredient
async def get_ingredient(id: int):
async def get_ingredient(ingredient_id: int):
try:
return await Ingredient.objects.get(id=id)
return await Ingredient.objects.get(id=ingredient_id)
except NoMatch:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
@app.get('/ingredients/{id}')
@app.get('/ingredients/{ingredient_id}')
async def read_ingredient(ingredient: Ingredient = Depends(get_ingredient)):
return ingredient
@app.put('/ingredients/{id}', status_code=status.HTTP_204_NO_CONTENT)
async def update_ingredient(name: str, ingredient: Ingredient = Depends(get_ingredient)):
@app.put('/ingredients/{ingredient_id}',
status_code=status.HTTP_204_NO_CONTENT)
async def update_ingredient(
name: str,
ingredient: Ingredient = Depends(get_ingredient)):
await ingredient.update(name=name)
@app.delete('/ingredients/{id}', status_code=status.HTTP_204_NO_CONTENT)
@app.delete('/ingredients/{ingredient_id}',
status_code=status.HTTP_204_NO_CONTENT)
async def delete_ingredient(ingredient: Ingredient = Depends(get_ingredient)):
await ingredient.delete()
@app.get('/pizzas')
async def read_pizzas():
return await Pizza.objects.all()
@app.post('/pizzas', status_code=status.HTTP_201_CREATED)
async def create_pizza(name: str, response: Response):
pizza = await Pizza.objects.create(name=name)
response.headers['Location'] = 'pizzas/%d' % pizza.id
return pizza
async def get_pizza(pizza_id: int):
try:
return await Pizza.objects.get(id=pizza_id)
except NoMatch:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
@app.get('/pizzas/{pizza_id}')
async def read_pizza(pizza: Pizza = Depends(get_pizza)):
return pizza
@app.put('/pizzas/{pizza_id}', status_code=status.HTTP_204_NO_CONTENT)
async def update_pizza(name: str, pizza: Pizza = Depends(get_pizza)):
await pizza.update(name=name)
@app.delete('/pizzas/{pizza_id}', status_code=status.HTTP_204_NO_CONTENT)
async def delete_pizza(pizza: Pizza = Depends(get_pizza)):
await pizza.delete()
@app.get('/pizzas/{pizza_id}/ingredients')
async def read_pizza_ingredients(pizza: Pizza = Depends(get_pizza)):
return await PizzaIngredient.objects.select_related('ingredient') \
.filter(pizza=pizza).all()
@app.post('/pizza/{pizza_id}/ingredients', status_code=status.HTTP_201_CREATED)
async def create_pizza_ingredient(
response: Response,
pizza: Pizza = Depends(get_pizza),
ingredient: Ingredient = Depends(get_ingredient)):
pizza_ingredient = await PizzaIngredient.objects.create(
pizza=pizza,
ingredient=ingredient)
response.headers['Location'] = 'ingredients/%d' % pizza_ingredient.id
return pizza_ingredient
async def get_pizza_ingredient(
pizza_ingredient_id: int,
pizza: Pizza = Depends(get_pizza)):
try:
return await PizzaIngredient.objects.select_related('ingredient') \
.get(id=pizza_ingredient_id, pizza=pizza)
except NoMatch:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
@app.get('/pizzas/{pizza_id}/ingredients/{pizza_ingredient_id}')
async def read_pizza_ingredient(
pizza_ingredient: PizzaIngredient = Depends(get_pizza_ingredient)):
return pizza_ingredient
@app.put('/pizzas/{pizza_id}/ingredients/{pizza_ingredient_id}',
status_code=status.HTTP_204_NO_CONTENT)
async def update_pizza_ingredient(
pizza_ingredient: PizzaIngredient = Depends(get_pizza_ingredient),
ingredient: Ingredient = Depends(get_ingredient)):
await pizza_ingredient.update(ingredient=ingredient.id)
@app.delete('/pizzas/{pizza_id}/ingredients/{pizza_ingredient_id}',
status_code=status.HTTP_204_NO_CONTENT)
async def delete_pizza_ingredient(
pizza_ingredient: PizzaIngredient = Depends(get_pizza_ingredient)):
await pizza_ingredient.delete()

View File

@ -1,5 +1,5 @@
from databases import Database
from ormantic import Integer, Model, Text
from ormantic import Integer, ForeignKey, Model, Text
from sqlalchemy import create_engine, MetaData
@ -17,5 +17,26 @@ class Ingredient(Model):
database = database
class Pizza(Model):
id: Integer(primary_key=True) = None
name: Text()
class Mapping:
table_name = 'pizzas'
metadata = metadata
database = database
class PizzaIngredient(Model):
id: Integer(primary_key=True) = None
pizza: ForeignKey(Pizza)
ingredient: ForeignKey(Ingredient)
class Mapping:
table_name = 'pizzaingredients'
metadata = metadata
database = database
engine = create_engine(str(database.url), echo=True)
metadata.create_all(engine)