diff --git a/docs/img/tutorial/path-operation-configuration/image01.png b/docs/img/tutorial/path-operation-configuration/image01.png new file mode 100644 index 000000000..2fe93810e Binary files /dev/null and b/docs/img/tutorial/path-operation-configuration/image01.png differ diff --git a/docs/img/tutorial/path-operation-configuration/image02.png b/docs/img/tutorial/path-operation-configuration/image02.png new file mode 100644 index 000000000..6315a2e0f Binary files /dev/null and b/docs/img/tutorial/path-operation-configuration/image02.png differ diff --git a/docs/img/tutorial/path-operation-configuration/image03.png b/docs/img/tutorial/path-operation-configuration/image03.png new file mode 100644 index 000000000..cba5ad467 Binary files /dev/null and b/docs/img/tutorial/path-operation-configuration/image03.png differ diff --git a/docs/img/tutorial/path-operation-configuration/image04.png b/docs/img/tutorial/path-operation-configuration/image04.png new file mode 100644 index 000000000..9e7240869 Binary files /dev/null and b/docs/img/tutorial/path-operation-configuration/image04.png differ diff --git a/docs/img/tutorial/path-operation-configuration/image05.png b/docs/img/tutorial/path-operation-configuration/image05.png new file mode 100644 index 000000000..daaea0edd Binary files /dev/null and b/docs/img/tutorial/path-operation-configuration/image05.png differ diff --git a/docs/tutorial/path-operation-configuration.md b/docs/tutorial/path-operation-configuration.md new file mode 100644 index 000000000..53b33359e --- /dev/null +++ b/docs/tutorial/path-operation-configuration.md @@ -0,0 +1,93 @@ +There are several parameters that you can pass to your path operation decorator to configure it. + +!!! warning + Notice that these parameters are passed directly to the path operation decorator, not to your path operation function. + +## Response Status Code + +You can define the (HTTP) `status_code` to be used in the response of your path operation. + +You can pass directly the `int` code, like `404`. + +But if you don't remember what each number code is for, you can use the shortcut constants from `starlette`: + +```Python hl_lines="5 18" +{!./tutorial/src/path-operation-configuration/tutorial001.py!} +``` + +That status code will be used in the response and will be added to the OpenAPI schema. + + +## Tags + +You can add tags to your path operation, pass the parameter `tags` with a `list` of `str` (commonly just one `str`): + +```Python hl_lines="17 22 27" +{!./tutorial/src/path-operation-configuration/tutorial002.py!} +``` + +They will be added to the OpenAPI schema and used by the automatic documentation interfaces: + + + +## Summary and description + +You can add a `summary` and `description`: + +```Python hl_lines="20 21" +{!./tutorial/src/path-operation-configuration/tutorial003.py!} +``` + +## Description from docstring + +As descriptions tend to be long and cover multiple lines, you can declare the path operation description in the function docstring and **FastAPI** will read it from there. + +```Python hl_lines="19 20 21 22 23 24 25 26 27" +{!./tutorial/src/path-operation-configuration/tutorial004.py!} +``` + +It will be used in the interactive docs: + + + +!!! info + OpenAPI specifies that descriptions can be written in Markdown syntax, but the interactive documentation systems included still don't support it at the time of writing this, although they have it in their plans. + +## Response description + +You can specify the response description with the parameter `response_description`: + +```Python hl_lines="21" +{!./tutorial/src/path-operation-configuration/tutorial005.py!} +``` + +!!! info + Notice that `response_description` refers specifically to the response, the `description` refers to the path operation in general. + +!!! info + OpenAPI specifies that each path operation requires a response description. + + So, if you don't provide one, **FastAPI** will automatically generate one of "Successful response". + + + +## Deprecate a path operation + +If you need to mark a path operation as deprecated, but without removing it, pass the parameter `deprecated`: + + +```Python hl_lines="16" +{!./tutorial/src/path-operation-configuration/tutorial006.py!} +``` + +It will be clearly marked as deprecated in the interactive docs: + + + +Check how deprecated and non-deprecated path operations look like: + + + +## Recap + +You can configure and add metadata for your path operations easily by passing parameters to the path operation decorators. \ No newline at end of file diff --git a/docs/tutorial/src/path-operation-configuration/tutorial001.py b/docs/tutorial/src/path-operation-configuration/tutorial001.py new file mode 100644 index 000000000..b48601867 --- /dev/null +++ b/docs/tutorial/src/path-operation-configuration/tutorial001.py @@ -0,0 +1,20 @@ +from typing import Set + +from fastapi import FastAPI +from pydantic import BaseModel +from starlette.status import HTTP_201_CREATED + +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/path-operation-configuration/tutorial002.py b/docs/tutorial/src/path-operation-configuration/tutorial002.py new file mode 100644 index 000000000..b5d0f12ca --- /dev/null +++ b/docs/tutorial/src/path-operation-configuration/tutorial002.py @@ -0,0 +1,29 @@ +from typing import Set + +from fastapi import FastAPI +from pydantic import BaseModel + +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 + + +@app.get("/items/", tags=["items"]) +async def read_items(): + return [{"name": "Foo", "price": 42}] + + +@app.get("/users/", tags=["users"]) +async def read_users(): + return [{"username": "johndoe"}] diff --git a/docs/tutorial/src/path-operation-configuration/tutorial003.py b/docs/tutorial/src/path-operation-configuration/tutorial003.py new file mode 100644 index 000000000..106607fd2 --- /dev/null +++ b/docs/tutorial/src/path-operation-configuration/tutorial003.py @@ -0,0 +1,24 @@ +from typing import Set + +from fastapi import FastAPI +from pydantic import BaseModel + +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/path-operation-configuration/tutorial004.py b/docs/tutorial/src/path-operation-configuration/tutorial004.py new file mode 100644 index 000000000..a4151a8cd --- /dev/null +++ b/docs/tutorial/src/path-operation-configuration/tutorial004.py @@ -0,0 +1,28 @@ +from typing import Set + +from fastapi import FastAPI +from pydantic import BaseModel + +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/path-operation-configuration/tutorial005.py b/docs/tutorial/src/path-operation-configuration/tutorial005.py new file mode 100644 index 000000000..f710e6c66 --- /dev/null +++ b/docs/tutorial/src/path-operation-configuration/tutorial005.py @@ -0,0 +1,33 @@ +from typing import Set + +from fastapi import FastAPI +from pydantic import BaseModel + +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/path-operation-configuration/tutorial006.py b/docs/tutorial/src/path-operation-configuration/tutorial006.py new file mode 100644 index 000000000..7c1aa9b20 --- /dev/null +++ b/docs/tutorial/src/path-operation-configuration/tutorial006.py @@ -0,0 +1,18 @@ +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/items/", tags=["items"]) +async def read_items(): + return [{"name": "Foo", "price": 42}] + + +@app.get("/users/", tags=["users"]) +async def read_users(): + return [{"username": "johndoe"}] + + +@app.get("/elements/", tags=["items"], deprecated=True) +async def read_elements(): + return [{"item_id": "Foo"}] diff --git a/mkdocs.yml b/mkdocs.yml index 961a2161c..9ec1dbbef 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -34,6 +34,7 @@ nav: - Form Data: 'tutorial/request-forms.md' - Request Files: 'tutorial/request-files.md' - Request Forms and Files: 'tutorial/request-forms-and-files.md' + - Path Operation Configuration: 'tutorial/path-operation-configuration.md' - Concurrency and async / await: 'async.md' - Deployment: 'deployment.md'