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 fastapi import Depends, FastAPI, HTTPException, Response, status
from logging import getLogger from logging import getLogger
from ormantic.exceptions import NoMatch from ormantic.exceptions import NoMatch
from pizzatool.model import Ingredient from pizzatool.model import Ingredient, Pizza, PizzaIngredient
logger = getLogger(__name__) logger = getLogger(__name__)
@ -20,23 +20,110 @@ async def create_ingredient(name: str, response: Response):
return ingredient return ingredient
async def get_ingredient(id: int): async def get_ingredient(ingredient_id: int):
try: try:
return await Ingredient.objects.get(id=id) return await Ingredient.objects.get(id=ingredient_id)
except NoMatch: except NoMatch:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) 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)): async def read_ingredient(ingredient: Ingredient = Depends(get_ingredient)):
return ingredient return ingredient
@app.put('/ingredients/{id}', status_code=status.HTTP_204_NO_CONTENT) @app.put('/ingredients/{ingredient_id}',
async def update_ingredient(name: str, ingredient: Ingredient = Depends(get_ingredient)): status_code=status.HTTP_204_NO_CONTENT)
async def update_ingredient(
name: str,
ingredient: Ingredient = Depends(get_ingredient)):
await ingredient.update(name=name) 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)): async def delete_ingredient(ingredient: Ingredient = Depends(get_ingredient)):
await ingredient.delete() 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 databases import Database
from ormantic import Integer, Model, Text from ormantic import Integer, ForeignKey, Model, Text
from sqlalchemy import create_engine, MetaData from sqlalchemy import create_engine, MetaData
@ -17,5 +17,26 @@ class Ingredient(Model):
database = database 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) engine = create_engine(str(database.url), echo=True)
metadata.create_all(engine) metadata.create_all(engine)