REST API to manage pizzas with ingredients
parent
5f61728536
commit
74ebf1a546
101
pizzatool/api.py
101
pizzatool/api.py
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue