]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:memo: Add first tutorial src files
authorSebastián Ramírez <tiangolo@gmail.com>
Thu, 13 Dec 2018 17:05:15 +0000 (21:05 +0400)
committerSebastián Ramírez <tiangolo@gmail.com>
Thu, 13 Dec 2018 17:05:15 +0000 (21:05 +0400)
68 files changed:
docs/tutorial/src/tutorial01.py [new file with mode: 0644]
docs/tutorial/src/tutorial02.py [new file with mode: 0644]
docs/tutorial/src/tutorial03.py [new file with mode: 0644]
docs/tutorial/src/tutorial04.py [new file with mode: 0644]
docs/tutorial/src/tutorial05-01.py [new file with mode: 0644]
docs/tutorial/src/tutorial05-04.py [new file with mode: 0644]
docs/tutorial/src/tutorial06.py [new file with mode: 0644]
docs/tutorial/src/tutorial07.py [new file with mode: 0644]
docs/tutorial/src/tutorial08.py [new file with mode: 0644]
docs/tutorial/src/tutorial09.py [new file with mode: 0644]
docs/tutorial/src/tutorial10.py [new file with mode: 0644]
docs/tutorial/src/tutorial11.py [new file with mode: 0644]
docs/tutorial/src/tutorial12.py [new file with mode: 0644]
docs/tutorial/src/tutorial13.py [new file with mode: 0644]
docs/tutorial/src/tutorial14.py [new file with mode: 0644]
docs/tutorial/src/tutorial15.py [new file with mode: 0644]
docs/tutorial/src/tutorial16.py [new file with mode: 0644]
docs/tutorial/src/tutorial17.py [new file with mode: 0644]
docs/tutorial/src/tutorial18-01.py [new file with mode: 0644]
docs/tutorial/src/tutorial18-02.py [new file with mode: 0644]
docs/tutorial/src/tutorial18-03.py [new file with mode: 0644]
docs/tutorial/src/tutorial19.py [new file with mode: 0644]
docs/tutorial/src/tutorial20.py [new file with mode: 0644]
docs/tutorial/src/tutorial21.py [new file with mode: 0644]
docs/tutorial/src/tutorial22.py [new file with mode: 0644]
docs/tutorial/src/tutorial23.py [new file with mode: 0644]
docs/tutorial/src/tutorial24.py [new file with mode: 0644]
docs/tutorial/src/tutorial25.py [new file with mode: 0644]
docs/tutorial/src/tutorial26.py [new file with mode: 0644]
docs/tutorial/src/tutorial27.py [new file with mode: 0644]
docs/tutorial/src/tutorial28.py [new file with mode: 0644]
docs/tutorial/src/tutorial29.py [new file with mode: 0644]
docs/tutorial/src/tutorial30.py [new file with mode: 0644]
docs/tutorial/src/tutorial31.py [new file with mode: 0644]
docs/tutorial/src/tutorial32.py [new file with mode: 0644]
docs/tutorial/src/tutorial33.py [new file with mode: 0644]
docs/tutorial/src/tutorial34.py [new file with mode: 0644]
docs/tutorial/src/tutorial35.py [new file with mode: 0644]
docs/tutorial/src/tutorial36.py [new file with mode: 0644]
docs/tutorial/src/tutorial37.py [new file with mode: 0644]
docs/tutorial/src/tutorial38.py [new file with mode: 0644]
docs/tutorial/src/tutorial39.py [new file with mode: 0644]
docs/tutorial/src/tutorial40.py [new file with mode: 0644]
docs/tutorial/src/tutorial41.py [new file with mode: 0644]
docs/tutorial/src/tutorial42.py [new file with mode: 0644]
docs/tutorial/src/tutorial43.py [new file with mode: 0644]
docs/tutorial/src/tutorial44.py [new file with mode: 0644]
docs/tutorial/src/tutorial45.py [new file with mode: 0644]
docs/tutorial/src/tutorial46.py [new file with mode: 0644]
docs/tutorial/src/tutorial47-01.py [new file with mode: 0644]
docs/tutorial/src/tutorial47-02.py [new file with mode: 0644]
docs/tutorial/src/tutorial47-03.py [new file with mode: 0644]
docs/tutorial/src/tutorial47-04.py [new file with mode: 0644]
docs/tutorial/src/tutorial48.py [new file with mode: 0644]
docs/tutorial/src/tutorial49.py [new file with mode: 0644]
docs/tutorial/src/tutorial50.py [new file with mode: 0644]
docs/tutorial/src/tutorial51.py [new file with mode: 0644]
docs/tutorial/src/tutorial52.py [new file with mode: 0644]
docs/tutorial/src/tutorial53.py [new file with mode: 0644]
docs/tutorial/src/tutorial54.py [new file with mode: 0644]
docs/tutorial/src/tutorial55.py [new file with mode: 0644]
docs/tutorial/src/tutorial56.py [new file with mode: 0644]
docs/tutorial/src/tutorial57.py [new file with mode: 0644]
docs/tutorial/src/tutorial58-01.py [new file with mode: 0644]
docs/tutorial/src/tutorial58-02.py [new file with mode: 0644]
docs/tutorial/src/tutorial58-03.py [new file with mode: 0644]
docs/tutorial/src/tutorial59.py [new file with mode: 0644]
docs/tutorial/src/tutorial60.py [new file with mode: 0644]

diff --git a/docs/tutorial/src/tutorial01.py b/docs/tutorial/src/tutorial01.py
new file mode 100644 (file)
index 0000000..2a26878
--- /dev/null
@@ -0,0 +1,7 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+@app.get("/")
+async def root():
+    return {"message": "Hello World"}
diff --git a/docs/tutorial/src/tutorial02.py b/docs/tutorial/src/tutorial02.py
new file mode 100644 (file)
index 0000000..82de3e6
--- /dev/null
@@ -0,0 +1,7 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+@app.get("/items/{item_id}")
+async def read_item(item_id):
+    return {"item_id": item_id}
diff --git a/docs/tutorial/src/tutorial03.py b/docs/tutorial/src/tutorial03.py
new file mode 100644 (file)
index 0000000..9f76dd1
--- /dev/null
@@ -0,0 +1,7 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: int):
+    return {"item_id": item_id}
diff --git a/docs/tutorial/src/tutorial04.py b/docs/tutorial/src/tutorial04.py
new file mode 100644 (file)
index 0000000..3e81155
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+from uuid import UUID
+
+app = FastAPI()
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: UUID):
+    return {"item_id": item_id}
diff --git a/docs/tutorial/src/tutorial05-01.py b/docs/tutorial/src/tutorial05-01.py
new file mode 100644 (file)
index 0000000..b446ba4
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+fake_items_db = [
+    {"item_name": "Foo"},
+    {"item_name": "Bar"},
+    {"item_name": "Baz"},
+]
+
+@app.get("/items/")
+async def read_item(skip: int = 0, limit: int = 100):
+    return fake_items_db[skip:limit]
diff --git a/docs/tutorial/src/tutorial05-04.py b/docs/tutorial/src/tutorial05-04.py
new file mode 100644 (file)
index 0000000..54191b6
--- /dev/null
@@ -0,0 +1,10 @@
+from fastapi import FastAPI
+from fastapi import FastAPI
+
+app = FastAPI()
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: str, q: str = None):
+    if q:
+        return {"item_id": item_id, "q": q}
+    return {"item_id": item_id}
diff --git a/docs/tutorial/src/tutorial06.py b/docs/tutorial/src/tutorial06.py
new file mode 100644 (file)
index 0000000..30f0cd6
--- /dev/null
@@ -0,0 +1,12 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: str, q: str = None, short: bool = False):
+    item = {"item_id": item_id}
+    if q:
+        item.update({"q": q})
+    if not short:
+        item.update({"description": "This is an amazing item that has a long description"})
+    return item
diff --git a/docs/tutorial/src/tutorial07.py b/docs/tutorial/src/tutorial07.py
new file mode 100644 (file)
index 0000000..d45ebba
--- /dev/null
@@ -0,0 +1,12 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+@app.get("/users/{user_id}/items/{item_id}")
+async def read_user_item(user_id: int, item_id: str, q: str = None, short: bool = False):
+    item = {"item_id": item_id, "owner_id": user_id}
+    if q:
+        item.update({"q": q})
+    if not short:
+        item.update({"description": "This is an amazing item that has a long description"})
+    return item
diff --git a/docs/tutorial/src/tutorial08.py b/docs/tutorial/src/tutorial08.py
new file mode 100644 (file)
index 0000000..c0b1227
--- /dev/null
@@ -0,0 +1,12 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+@app.get("/users/{user_id}/items/{item_id}")
+async def read_user_item(user_id: int, item_id: str, needy: str, q: str = None, short: bool = False):
+    item = {"item_id": item_id, "owner_id": user_id, "needy": needy}
+    if q:
+        item.update({"q": q})
+    if not short:
+        item.update({"description": "This is an amazing item that has a long description"})
+    return item
diff --git a/docs/tutorial/src/tutorial09.py b/docs/tutorial/src/tutorial09.py
new file mode 100644 (file)
index 0000000..78b813f
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+app = FastAPI()
+
+@app.post("/items/")
+async def create_item(item: Item):
+    return item
diff --git a/docs/tutorial/src/tutorial10.py b/docs/tutorial/src/tutorial10.py
new file mode 100644 (file)
index 0000000..925f110
--- /dev/null
@@ -0,0 +1,19 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+app = FastAPI()
+
+@app.post("/items/")
+async def create_item(item: Item):
+    item_dict = item.dict()
+    if item.tax:
+        price_with_tax = item.price + item.tax
+        item_dict.update({"price_with_tax": price_with_tax})
+    return item_dict
diff --git a/docs/tutorial/src/tutorial11.py b/docs/tutorial/src/tutorial11.py
new file mode 100644 (file)
index 0000000..34e9849
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+app = FastAPI()
+
+@app.put("/items/{item_id}")
+async def create_item(item_id: int, item: Item):
+    return {"item_id": item_id, **item.dict()}
diff --git a/docs/tutorial/src/tutorial12.py b/docs/tutorial/src/tutorial12.py
new file mode 100644 (file)
index 0000000..be6239d
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+app = FastAPI()
+
+@app.put("/items/{item_id}")
+async def create_item(item_id: int, item: Item, q: str = None):
+    result = {"item_id": item_id, **item.dict()}
+    if q:
+        result.update({"q": q})
+    return result
diff --git a/docs/tutorial/src/tutorial13.py b/docs/tutorial/src/tutorial13.py
new file mode 100644 (file)
index 0000000..183180c
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(None, max_length=50)):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial14.py b/docs/tutorial/src/tutorial14.py
new file mode 100644 (file)
index 0000000..311ece8
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(None, min_length=3, max_length=50)):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial15.py b/docs/tutorial/src/tutorial15.py
new file mode 100644 (file)
index 0000000..bdaf5c1
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: str = Query(None, min_length=3, max_length=50, regex="^fixedquery$")):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial16.py b/docs/tutorial/src/tutorial16.py
new file mode 100644 (file)
index 0000000..116829b
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        None, title="Query string", min_length=3, max_length=50, regex="^fixedquery$"
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial17.py b/docs/tutorial/src/tutorial17.py
new file mode 100644 (file)
index 0000000..67d5fd6
--- /dev/null
@@ -0,0 +1,20 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        None,
+        title="Query string",
+        description="Query string for the items to search in the database that have a good match",
+        min_length=3,
+        max_length=50,
+        regex="^fixedquery$",
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial18-01.py b/docs/tutorial/src/tutorial18-01.py
new file mode 100644 (file)
index 0000000..a4e3b81
--- /dev/null
@@ -0,0 +1,21 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        "fixedquery",
+        alias="item-query",
+        title="Query string",
+        description="Query string for the items to search in the database that have a good match",
+        min_length=3,
+        max_length=50,
+        regex="^fixedquery$",
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial18-02.py b/docs/tutorial/src/tutorial18-02.py
new file mode 100644 (file)
index 0000000..f261c95
--- /dev/null
@@ -0,0 +1,21 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        None,
+        alias="item-query",
+        title="Query string",
+        description="Query string for the items to search in the database that have a good match",
+        min_length=3,
+        max_length=50,
+        regex="^fixedquery$",
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial18-03.py b/docs/tutorial/src/tutorial18-03.py
new file mode 100644 (file)
index 0000000..b9bffca
--- /dev/null
@@ -0,0 +1,21 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        ...,
+        alias="item-query",
+        title="Query string",
+        description="Query string for the items to search in the database that have a good match",
+        min_length=3,
+        max_length=50,
+        regex="^fixedquery$",
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial19.py b/docs/tutorial/src/tutorial19.py
new file mode 100644 (file)
index 0000000..051656c
--- /dev/null
@@ -0,0 +1,22 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(
+    q: str = Query(
+        None,
+        alias="item-query",
+        title="Query string",
+        description="Query string for the items to search in the database that have a good match",
+        min_length=3,
+        max_length=50,
+        regex="^fixedquery$",
+        deprecated=True,
+    )
+):
+    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial20.py b/docs/tutorial/src/tutorial20.py
new file mode 100644 (file)
index 0000000..0600c7f
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI, Query, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    item_id: int = Path(..., title="The ID of the item to get"),
+    q: str = Query(None, alias="item-query"),
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial21.py b/docs/tutorial/src/tutorial21.py
new file mode 100644 (file)
index 0000000..c149507
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI, Query, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    q: str,
+    item_id: int = Path(..., title="The ID of the item to get"),
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial22.py b/docs/tutorial/src/tutorial22.py
new file mode 100644 (file)
index 0000000..4ac37c4
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, Query, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    *,
+    item_id: int = Path(..., title="The ID of the item to get"),
+    q: str,
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial23.py b/docs/tutorial/src/tutorial23.py
new file mode 100644 (file)
index 0000000..97611c2
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, Query, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    *,
+    item_id: int = Path(..., title="The ID of the item to get", ge=1),
+    q: str,
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial24.py b/docs/tutorial/src/tutorial24.py
new file mode 100644 (file)
index 0000000..4dabe35
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, Query, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    *,
+    item_id: int = Path(..., title="The ID of the item to get", gt=0, le=1000),
+    q: str,
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial25.py b/docs/tutorial/src/tutorial25.py
new file mode 100644 (file)
index 0000000..72b2bba
--- /dev/null
@@ -0,0 +1,16 @@
+from fastapi import FastAPI, Query, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    *,
+    item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
+    q: str,
+    size: float = Query(..., gt=0, lt=10.5)
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial26.py b/docs/tutorial/src/tutorial26.py
new file mode 100644 (file)
index 0000000..0083600
--- /dev/null
@@ -0,0 +1,26 @@
+from fastapi import FastAPI, Query, Path
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
+    q: str,
+    item: Item = None,
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    if item:
+        results.update({"item": item})
+    return results
diff --git a/docs/tutorial/src/tutorial27.py b/docs/tutorial/src/tutorial27.py
new file mode 100644 (file)
index 0000000..31dbb82
--- /dev/null
@@ -0,0 +1,27 @@
+from fastapi import FastAPI, Query, Path
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+class User(BaseModel):
+    username: str
+    full_name: str = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+    user: User,
+):
+    results = {"item_id": item_id, "item": item, "user": user}
+    return results
diff --git a/docs/tutorial/src/tutorial28.py b/docs/tutorial/src/tutorial28.py
new file mode 100644 (file)
index 0000000..a130222
--- /dev/null
@@ -0,0 +1,28 @@
+from fastapi import FastAPI, Query, Path, Body
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+class User(BaseModel):
+    username: str
+    full_name: str = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+    user: User,
+    access_token: str = Body(...),
+):
+    results = {"item_id": item_id, "item": item, "user": user, "access_token": access_token}
+    return results
diff --git a/docs/tutorial/src/tutorial29.py b/docs/tutorial/src/tutorial29.py
new file mode 100644 (file)
index 0000000..584451e
--- /dev/null
@@ -0,0 +1,31 @@
+from fastapi import FastAPI, Query, Path, Body
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+class User(BaseModel):
+    username: str
+    full_name: str = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+    user: User,
+    access_token: str = Body(...),
+    q: str = None,
+):
+    results = {"item_id": item_id, "item": item, "user": user, "access_token": access_token}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs/tutorial/src/tutorial30.py b/docs/tutorial/src/tutorial30.py
new file mode 100644 (file)
index 0000000..559356f
--- /dev/null
@@ -0,0 +1,21 @@
+from fastapi import FastAPI, Query, Path, Body
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item = Body(..., embed=True),
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial31.py b/docs/tutorial/src/tutorial31.py
new file mode 100644 (file)
index 0000000..89b97e8
--- /dev/null
@@ -0,0 +1,21 @@
+from fastapi import FastAPI, Query, Path, Body
+from pydantic import BaseModel, Schema
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = Schema(None, title="The description of the item", max_length=300)
+    price: float = Schema(..., gt=0, description="The price must be greater than zero")
+    tax: float = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item = Body(..., embed=True),
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial32.py b/docs/tutorial/src/tutorial32.py
new file mode 100644 (file)
index 0000000..e6fa584
--- /dev/null
@@ -0,0 +1,22 @@
+from fastapi import FastAPI, Query, Path, Body
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: list = []
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial33.py b/docs/tutorial/src/tutorial33.py
new file mode 100644 (file)
index 0000000..652ec7c
--- /dev/null
@@ -0,0 +1,23 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from typing import List
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: List[str] = []
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial34.py b/docs/tutorial/src/tutorial34.py
new file mode 100644 (file)
index 0000000..444f73a
--- /dev/null
@@ -0,0 +1,23 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from typing import Set
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial35.py b/docs/tutorial/src/tutorial35.py
new file mode 100644 (file)
index 0000000..6cfbeff
--- /dev/null
@@ -0,0 +1,29 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from typing import Set
+
+app = FastAPI()
+
+
+class Image(BaseModel):
+    url: str
+    name: str
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+    image: Image = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial36.py b/docs/tutorial/src/tutorial36.py
new file mode 100644 (file)
index 0000000..d04e72d
--- /dev/null
@@ -0,0 +1,30 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set
+
+app = FastAPI()
+
+
+class Image(BaseModel):
+    url: UrlStr
+    name: str
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+    image: Image = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial37.py b/docs/tutorial/src/tutorial37.py
new file mode 100644 (file)
index 0000000..e5c25e4
--- /dev/null
@@ -0,0 +1,30 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Image(BaseModel):
+    url: UrlStr
+    name: str
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+    image: List[Image] = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+    *,
+    item_id: int,
+    item: Item,
+):
+    results = {"item_id": item_id, "item": item}
+    return results
diff --git a/docs/tutorial/src/tutorial38.py b/docs/tutorial/src/tutorial38.py
new file mode 100644 (file)
index 0000000..3dd1a05
--- /dev/null
@@ -0,0 +1,32 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Image(BaseModel):
+    url: UrlStr
+    name: str
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+    image: List[Image] = None
+
+
+class Offer(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    items: List[Item]
+
+
+@app.post("/offers/")
+async def create_offer(*, offer: Offer):
+    return offer
diff --git a/docs/tutorial/src/tutorial39.py b/docs/tutorial/src/tutorial39.py
new file mode 100644 (file)
index 0000000..b57a243
--- /dev/null
@@ -0,0 +1,16 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Image(BaseModel):
+    url: UrlStr
+    name: str
+
+
+@app.post("/images/multiple/")
+async def create_multiple_images(*, images: List[Image]):
+    return images
diff --git a/docs/tutorial/src/tutorial40.py b/docs/tutorial/src/tutorial40.py
new file mode 100644 (file)
index 0000000..f1cc8b2
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Cookie
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(*, ads_id: str = Cookie(None)):
+    return {"ads_id": ads_id}
diff --git a/docs/tutorial/src/tutorial41.py b/docs/tutorial/src/tutorial41.py
new file mode 100644 (file)
index 0000000..9dbb991
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Header
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(*, accept_encoding: str = Header(None)):
+    return {"Accept-Encoding": accept_encoding}
diff --git a/docs/tutorial/src/tutorial42.py b/docs/tutorial/src/tutorial42.py
new file mode 100644 (file)
index 0000000..070c7fe
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Header
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(*, strange_header: str = Header(None, convert_underscores=False)):
+    return {"strange_header": strange_header}
diff --git a/docs/tutorial/src/tutorial43.py b/docs/tutorial/src/tutorial43.py
new file mode 100644 (file)
index 0000000..e892782
--- /dev/null
@@ -0,0 +1,19 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.post("/items/", response_model=Item)
+async def create_item(*, item: Item):
+    return item
diff --git a/docs/tutorial/src/tutorial44.py b/docs/tutorial/src/tutorial44.py
new file mode 100644 (file)
index 0000000..5ec7fa4
--- /dev/null
@@ -0,0 +1,20 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import EmailStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class UserIn(BaseModel):
+    username: str
+    password: str
+    email: EmailStr
+    full_name: str = None
+    
+
+
+# Don't do this in production!
+@app.post("/user/", response_model=UserIn)
+async def create_user(*, user: UserIn):
+    return user
diff --git a/docs/tutorial/src/tutorial45.py b/docs/tutorial/src/tutorial45.py
new file mode 100644 (file)
index 0000000..d9cdd86
--- /dev/null
@@ -0,0 +1,24 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import EmailStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class UserIn(BaseModel):
+    username: str
+    password: str
+    email: EmailStr
+    full_name: str = None
+
+
+class UserOut(BaseModel):
+    username: str
+    email: EmailStr
+    full_name: str = None
+
+
+@app.post("/user/", response_model=UserOut)
+async def create_user(*, user: UserIn):
+    return user
diff --git a/docs/tutorial/src/tutorial46.py b/docs/tutorial/src/tutorial46.py
new file mode 100644 (file)
index 0000000..c2811eb
--- /dev/null
@@ -0,0 +1,43 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import EmailStr
+from typing import Set, List
+from uuid import UUID, uuid4
+
+app = FastAPI()
+
+
+class UserIn(BaseModel):
+    username: str
+    password: str
+    email: EmailStr
+    full_name: str = None
+
+
+class UserOut(BaseModel):
+    username: str
+    email: EmailStr
+    full_name: str = None
+
+
+class UserInDB(BaseModel):
+    username: str
+    hashed_password: str
+    email: EmailStr
+    full_name: str = None
+
+
+def fake_password_hasher(raw_password: str):
+    return "supersecret" + raw_password
+
+
+def fake_save_user(user_in: UserIn):
+    hashed_password = fake_password_hasher(user_in.password)
+    user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
+    print("User saved! ..not really")
+    return user_in_db
+
+@app.post("/user/", response_model=UserOut)
+async def create_user(*, user_in: UserIn):
+    user_saved = fake_save_user(user_in)
+    return user_saved
diff --git a/docs/tutorial/src/tutorial47-01.py b/docs/tutorial/src/tutorial47-01.py
new file mode 100644 (file)
index 0000000..b61e62b
--- /dev/null
@@ -0,0 +1,37 @@
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import EmailStr
+from typing import Set, List
+
+app = FastAPI()
+
+class UserBase(BaseModel):
+    username: str
+    email: EmailStr
+    full_name: str = None
+
+class UserIn(UserBase):
+    password: str
+
+
+class UserOut(UserBase):
+    pass
+
+class UserInDB(UserBase):
+    hashed_password: str
+    
+
+def fake_password_hasher(raw_password: str):
+    return "supersecret" + raw_password
+
+
+def fake_save_user(user_in: UserIn):
+    hashed_password = fake_password_hasher(user_in.password)
+    user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
+    print("User saved! ..not really")
+    return user_in_db
+
+@app.post("/user/", response_model=UserOut)
+async def create_user(*, user_in: UserIn):
+    user_saved = fake_save_user(user_in)
+    return user_saved
diff --git a/docs/tutorial/src/tutorial47-02.py b/docs/tutorial/src/tutorial47-02.py
new file mode 100644 (file)
index 0000000..52a93d7
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import Body, FastAPI, Path, Query, Form
+from pydantic import BaseModel
+from pydantic.types import EmailStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+@app.post("/login/")
+async def login(*, username: str = Form(...), password: str = Form(...)):
+    return {"username": username}
diff --git a/docs/tutorial/src/tutorial47-03.py b/docs/tutorial/src/tutorial47-03.py
new file mode 100644 (file)
index 0000000..3a517f7
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import Body, FastAPI, Path, Query, File
+from pydantic import BaseModel
+from pydantic.types import EmailStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(*, file: bytes = File(...)):
+    return {"file_size": len(file)}
diff --git a/docs/tutorial/src/tutorial47-04.py b/docs/tutorial/src/tutorial47-04.py
new file mode 100644 (file)
index 0000000..19382b8
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import Body, FastAPI, Path, Query, File, Form
+from pydantic import BaseModel
+from pydantic.types import EmailStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(*, file: bytes = File(...), token: str = Form(...)):
+    return {"file_size": len(file), "token": token}
diff --git a/docs/tutorial/src/tutorial48.py b/docs/tutorial/src/tutorial48.py
new file mode 100644 (file)
index 0000000..fb32535
--- /dev/null
@@ -0,0 +1,20 @@
+from fastapi import Body, FastAPI, Path, Query
+from starlette.status import HTTP_201_CREATED
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.post("/items/", response_model=Item, status_code=HTTP_201_CREATED)
+async def create_item(*, item: Item):
+    return item
diff --git a/docs/tutorial/src/tutorial49.py b/docs/tutorial/src/tutorial49.py
new file mode 100644 (file)
index 0000000..bd0bef7
--- /dev/null
@@ -0,0 +1,20 @@
+from fastapi import Body, FastAPI, Path, Query
+from starlette.status import HTTP_201_CREATED
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.post("/items/", response_model=Item, tags=["items"])
+async def create_item(*, item: Item):
+    return item
diff --git a/docs/tutorial/src/tutorial50.py b/docs/tutorial/src/tutorial50.py
new file mode 100644 (file)
index 0000000..8a16338
--- /dev/null
@@ -0,0 +1,25 @@
+from fastapi import Body, FastAPI, Path, Query
+from starlette.status import HTTP_201_CREATED
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.post(
+    "/items/",
+    response_model=Item,
+    summary="Create an item",
+    description="Create an item with all the information, name, description, price, tax and a set of unique tags",
+)
+async def create_item(*, item: Item):
+    return item
diff --git a/docs/tutorial/src/tutorial51.py b/docs/tutorial/src/tutorial51.py
new file mode 100644 (file)
index 0000000..479ac7d
--- /dev/null
@@ -0,0 +1,29 @@
+from fastapi import Body, FastAPI, Path, Query
+from starlette.status import HTTP_201_CREATED
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.post("/items/", response_model=Item, summary="Create an item")
+async def create_item(*, item: Item):
+    """
+    Create an item with all the information:
+    
+    * name: each item must have a name
+    * description: a long description
+    * price: required
+    * tax: if the item doesn't have tax, you can omit this
+    * tags: a set of unique tag strings for this item
+    """
+    return item
diff --git a/docs/tutorial/src/tutorial52.py b/docs/tutorial/src/tutorial52.py
new file mode 100644 (file)
index 0000000..bec8a6a
--- /dev/null
@@ -0,0 +1,29 @@
+from fastapi import Body, FastAPI, Path, Query
+from starlette.status import HTTP_201_CREATED
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from typing import Set, List
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.post("/items/", response_model=Item, summary="Create an item", response_description="The created item")
+async def create_item(*, item: Item):
+    """
+    Create an item with all the information:
+    
+    * name: each item must have a name
+    * description: a long description
+    * price: required
+    * tax: if the item doesn't have tax, you can omit this
+    * tags: a set of unique tag strings for this item
+    """
+    return item
diff --git a/docs/tutorial/src/tutorial53.py b/docs/tutorial/src/tutorial53.py
new file mode 100644 (file)
index 0000000..1a77be0
--- /dev/null
@@ -0,0 +1,13 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+
+app = FastAPI()
+
+
+@app.get("/items/", deprecated=True)
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs/tutorial/src/tutorial54.py b/docs/tutorial/src/tutorial54.py
new file mode 100644 (file)
index 0000000..31793c9
--- /dev/null
@@ -0,0 +1,13 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+
+app = FastAPI()
+
+
+@app.get("/items/", operation_id="some_specific_id_you_define")
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs/tutorial/src/tutorial55.py b/docs/tutorial/src/tutorial55.py
new file mode 100644 (file)
index 0000000..34f9e85
--- /dev/null
@@ -0,0 +1,13 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+
+app = FastAPI()
+
+
+@app.get("/items/", include_in_schema=False)
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs/tutorial/src/tutorial56.py b/docs/tutorial/src/tutorial56.py
new file mode 100644 (file)
index 0000000..dec2f53
--- /dev/null
@@ -0,0 +1,14 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+from starlette.responses import UJSONResponse
+
+app = FastAPI()
+
+
+@app.get("/items/", content_type=UJSONResponse)
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs/tutorial/src/tutorial57.py b/docs/tutorial/src/tutorial57.py
new file mode 100644 (file)
index 0000000..f2300f8
--- /dev/null
@@ -0,0 +1,23 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+from starlette.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.get("/items/", content_type=HTMLResponse)
+async def read_items():
+    return """
+    <html>
+        <head>
+            <title>Some HTML in here</title>
+        </head>
+        <body>
+            <h1>Look ma! HTML!</h1>
+        </body>
+    </html>
+    """
diff --git a/docs/tutorial/src/tutorial58-01.py b/docs/tutorial/src/tutorial58-01.py
new file mode 100644 (file)
index 0000000..9fe0da7
--- /dev/null
@@ -0,0 +1,32 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query, Depends
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+from starlette.responses import HTMLResponse
+
+app = FastAPI()
+
+
+fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
+
+
+class CommonQueryParams(BaseModel):
+    q: str = None
+    skip: int = None
+    limit: int = None
+
+
+async def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
+    return CommonQueryParams(q=q, skip=skip, limit=limit)
+
+
+@app.get("/items/")
+async def read_items(commons: CommonQueryParams = Depends(common_parameters)):
+    response = {}
+    if commons.q:
+        response.update({"q": commons.q})
+    items = fake_items_db[commons.skip:commons.limit]
+    response.update({"items": items})
+    return response
diff --git a/docs/tutorial/src/tutorial58-02.py b/docs/tutorial/src/tutorial58-02.py
new file mode 100644 (file)
index 0000000..41a63c4
--- /dev/null
@@ -0,0 +1,35 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query, Depends, Cookie
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+from starlette.responses import HTMLResponse
+
+app = FastAPI()
+
+
+class InterestsTracker(BaseModel):
+    track_code: str
+    interests: List[str]
+
+
+fake_tracked_users_db = {
+    "Foo": {"track_code": "Foo", "interests": ["sports", "movies"]},
+    "Bar": {"track_code": "Bar", "interests": ["food", "shows"]},
+    "Baz": {"track_code": "Baz", "interests": ["gaming", "virtual reality"]},
+}
+
+
+async def get_tracked_interests(track_code: str = Cookie(None)):
+    if track_code in fake_tracked_users_db:
+        track_dict = fake_tracked_users_db[track_code]
+        track = InterestsTracker(**track_dict)
+        return track
+    return None
+
+
+@app.get("/interests/")
+async def read_interests(tracked_interests: InterestsTracker = Depends(get_tracked_interests)):
+    response = {"interests": tracked_interests.interests}
+    return response
diff --git a/docs/tutorial/src/tutorial58-03.py b/docs/tutorial/src/tutorial58-03.py
new file mode 100644 (file)
index 0000000..3104206
--- /dev/null
@@ -0,0 +1,48 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query, Depends, Cookie
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+from starlette.responses import HTMLResponse
+from random import choice
+
+app = FastAPI()
+
+
+class InterestsTracker(BaseModel):
+    track_code: str
+    interests: List[str]
+
+
+fake_tracked_users_db = {
+    "Foo": {"track_code": "Foo", "interests": ["sports", "movies"]},
+    "Bar": {"track_code": "Bar", "interests": ["food", "shows"]},
+    "Baz": {"track_code": "Baz", "interests": ["gaming", "virtual reality"]},
+}
+
+async def get_tracked_interests(track_code: str = Cookie(None)):
+    if track_code in fake_tracked_users_db:
+        track_dict = fake_tracked_users_db[track_code]
+        track = InterestsTracker(**track_dict)
+        return track
+    return None
+
+class ComplexTracker:
+    def __init__(self, tracker: InterestsTracker = Depends(get_tracked_interests)):
+        self.tracker = tracker
+    
+    def random_interest(self):
+        """
+        Get a random interest from the tracked ones for the current user.
+        If the user doesn't have tracked interests, return a random one from the ones available.
+        """
+        if self.tracker.interests:
+            return choice(self.tracker.interests)
+        return choice(["sports", "movies", "food", "shows", "gaming", "virtual reality"])
+
+
+@app.get("/suggested-category")
+async def read_suggested_category(tracker: ComplexTracker = Depends(None)):
+    response = {"category": tracker.random_interest()}
+    return response
diff --git a/docs/tutorial/src/tutorial59.py b/docs/tutorial/src/tutorial59.py
new file mode 100644 (file)
index 0000000..442a93d
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query, Depends, Cookie
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+from starlette.responses import HTMLResponse
+from random import choice
+
+from sqlalchemy import create_engine
+from sqlalchemy.orm import scoped_session, sessionmaker
+from sqlalchemy import Column, Integer, DateTime, String, Boolean, ForeignKey
+from sqlalchemy.ext.declarative import declarative_base, declared_attr
+
+
+# SQLAlchemy specific code, as with any other app
+
+
+SQLALCHEMY_DATABASE_URI = "postgresql://user:password@postgresserver/db"
+
+# By creating this a CustomBase class and inheriting from it, your models will have
+# automatic __tablename__ attributes. So you don't have to declare them.
+# So, your models will behave very similarly to, for example, Flask-SQLAlchemy
+
+class CustomBase:
+    # Generate __tablename__ automatically
+    @declared_attr
+    def __tablename__(cls):
+        return cls.__name__.lower()
+
+
+Base = declarative_base(cls=CustomBase)
+
+
+class User(Base):
+    # Own properties
+    id = Column(Integer, primary_key=True, index=True)
+    email = Column(String, unique=True, index=True)
+    hashed_password = Column(String)
+    is_active = Column(Boolean(), default=True)
+
+
+engine = create_engine(SQLALCHEMY_DATABASE_URI, convert_unicode=True)
+db_session = scoped_session(
+    sessionmaker(autocommit=False, autoflush=False, bind=engine)
+)
+
+
+def get_user(username, db_session):
+    return db_session.query(User).filter(User.id == username).first()
+
+# FastAPI specific code
+app = FastAPI()
+
+
+@app.get("/users/{username}")
+def read_user(username: str):
+    user = get_user(username, db_session)
+    return user
diff --git a/docs/tutorial/src/tutorial60.py b/docs/tutorial/src/tutorial60.py
new file mode 100644 (file)
index 0000000..9725142
--- /dev/null
@@ -0,0 +1,66 @@
+from typing import List, Set
+
+from fastapi import Body, FastAPI, Path, Query, Depends, Cookie
+from pydantic import BaseModel
+from pydantic.types import UrlStr
+from starlette.status import HTTP_201_CREATED
+from starlette.responses import HTMLResponse
+from random import choice
+
+from typing import List, Optional, Union
+
+from pydantic import BaseModel
+
+from app.models.config import USERPROFILE_DOC_TYPE
+from app.models.role import RoleEnum
+from couchbase.bucket import Bucket
+from couchbase.cluster import Cluster, PasswordAuthenticator
+from couchbase import LOCKMODE_WAIT
+
+
+def get_bucket():
+    cluster = Cluster("couchbase://couchbasehost:8091")
+    authenticator = PasswordAuthenticator("username", "password")
+    cluster.authenticate(authenticator)
+    bucket: Bucket = cluster.open_bucket("bucket_name", lockmode=LOCKMODE_WAIT)
+    return bucket
+
+
+class User(BaseModel):
+    username: str
+    email: Optional[str] = None
+    full_name: Optional[str] = None
+    disabled: Optional[bool] = None
+
+
+class UserInDB(User):
+    type: str = USERPROFILE_DOC_TYPE
+    hashed_password: str
+
+    class Meta:
+        key: Optional[str] = None
+
+
+def get_user_doc_id(username):
+    return f"userprofile::{username}"
+
+
+def get_user(bucket: Bucket, username: str):
+    doc_id = get_user_doc_id(username)
+    result = bucket.get(doc_id, quiet=True)
+    if not result.value:
+        return None
+    user = UserInDB(**result.value)
+    user.Meta.key = result.key
+    return user
+
+
+# FastAPI specific code
+app = FastAPI()
+
+
+@app.get("/users/{username}")
+def read_user(username: str):
+    bucket = get_bucket()
+    user = get_user(bucket=bucket, username=username)
+    return user