forked from tiangolo/fastapi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
57f4088
commit 28f86a7
Showing
1 changed file
with
326 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,326 @@ | ||
# Beispiele für Request-Daten deklarieren | ||
|
||
Sie können für die Daten, welche Ihre Anwendung empfängt, Beispiele deklarieren. | ||
|
||
Es gibt mehrere Wege, das zu tun. | ||
|
||
## Zusätzliche JSON-Schema-Daten in Pydantic-Modellen | ||
|
||
In einem Pydantic-Modell können Sie <abbr title="Beispiele">`examples`</abbr> deklarieren, die zum generierten JSON-Schema hinzugefügt werden. | ||
|
||
=== "Python 3.10+ Pydantic v2" | ||
|
||
```Python hl_lines="13-24" | ||
{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!} | ||
``` | ||
|
||
=== "Python 3.10+ Pydantic v1" | ||
|
||
```Python hl_lines="13-23" | ||
{!> ../../../docs_src/schema_extra_example/tutorial001_py310_pv1.py!} | ||
``` | ||
|
||
=== "Python 3.8+ Pydantic v2" | ||
|
||
```Python hl_lines="15-26" | ||
{!> ../../../docs_src/schema_extra_example/tutorial001.py!} | ||
``` | ||
|
||
=== "Python 3.8+ Pydantic v1" | ||
|
||
```Python hl_lines="15-25" | ||
{!> ../../../docs_src/schema_extra_example/tutorial001_pv1.py!} | ||
``` | ||
|
||
Diese Extra-Information wird, so wie sie ist, zum für das Modell generierten **JSON-Schema** hinzugefügt und in der API-Dokumentation verwendet. | ||
|
||
=== "Pydantic v2" | ||
|
||
In Pydantic Version 2 setzen Sie das Attribut `model_config`, welches ein `dict` ist, wie beschrieben in <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantics Dokumentation: Configuration</a>. | ||
|
||
In dem Dict setzen Sie `"json_schema_extra"`, welches widerum ein `dict` ist, mit zusätzlichen Daten, die im generierten JSON-Schema enthalten sein sollen, hier `"examples"`. | ||
|
||
=== "Pydantic v1" | ||
|
||
In Pydantic Version 1 definieren Sie eine innere Klasse `Config` mit einem Attribut `schema_extra`, wie beschrieben in <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantics Dokumentation: Schema customization</a>. | ||
|
||
`schema_extra` ist ein `dict` welches zusätzlichen Daten enthält, die im generierten JSON-Schema enthalten sein sollen, inklusive `examples`. | ||
|
||
!!! tip "Tipp" | ||
Sie können dieselbe Technik verwenden, um das JSON-Schema zu erweitern und ihre eigenen zusätzlichen Informationen hinzuzufügen. | ||
|
||
Zum Beispiel Metadaten für eine Frontend-Benutzeroberfläche, usw. | ||
|
||
!!! info | ||
OpenAPI 3.1.0 (verwendet seit FastAPI 0.99.0) fügte Unterstützung für `examples` hinzu, welches Teil des **JSON-Schema**-Standards ist. | ||
|
||
Davor unterstützte es nur das Schlüsselwort `example`. Das wird immer noch von OpenAPI 3.1.0 unterstützt, ist aber <abbr title="deprecated – veraltet: Es soll nicht mehr verwendet werden">deprecated</abbr> und nicht mehr Teil des JSON-Schema-Standards. Darum empfehlen wir, von `example` zu `examples` zu migrieren. 🤓 | ||
|
||
Sie können darüber mehr am Ende dieses Kapitels lesen. | ||
|
||
## Zusätzliche Argumente für `Field` | ||
|
||
Wenn Sie `Field()` mit Pydantic-Modellen verwenden, können Sie hier ebenfalls zusätzliche `examples` deklarieren: | ||
|
||
=== "Python 3.10+" | ||
|
||
```Python hl_lines="2 8-11" | ||
{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!} | ||
``` | ||
|
||
=== "Python 3.8+" | ||
|
||
```Python hl_lines="4 10-13" | ||
{!> ../../../docs_src/schema_extra_example/tutorial002.py!} | ||
``` | ||
|
||
## `examples` in JSON-Schema - OpenAPI | ||
|
||
Wenn Sie: | ||
|
||
* `Path()` | ||
* `Query()` | ||
* `Header()` | ||
* `Cookie()` | ||
* `Body()` | ||
* `Form()` | ||
* `File()` | ||
|
||
verwenden, können Sie auch eine Gruppe von `examples` deklarieren mit weiteren Informationen, | ||
|
||
### `Body` with `examples` | ||
|
||
Here we pass `examples` containing one example of the data expected in `Body()`: | ||
|
||
=== "Python 3.10+" | ||
|
||
```Python hl_lines="22-29" | ||
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!} | ||
``` | ||
|
||
=== "Python 3.9+" | ||
|
||
```Python hl_lines="22-29" | ||
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!} | ||
``` | ||
|
||
=== "Python 3.8+" | ||
|
||
```Python hl_lines="23-30" | ||
{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!} | ||
``` | ||
|
||
=== "Python 3.10+ non-Annotated" | ||
|
||
!!! tip "Tipp" | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="18-25" | ||
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!} | ||
``` | ||
|
||
=== "Python 3.8+ non-Annotated" | ||
|
||
!!! tip "Tipp" | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="20-27" | ||
{!> ../../../docs_src/schema_extra_example/tutorial003.py!} | ||
``` | ||
|
||
### Example in the docs UI | ||
|
||
With any of the methods above it would look like this in the `/docs`: | ||
|
||
<img src="/img/tutorial/body-fields/image01.png"> | ||
|
||
### `Body` with multiple `examples` | ||
|
||
You can of course also pass multiple `examples`: | ||
|
||
=== "Python 3.10+" | ||
|
||
```Python hl_lines="23-38" | ||
{!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!} | ||
``` | ||
|
||
=== "Python 3.9+" | ||
|
||
```Python hl_lines="23-38" | ||
{!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!} | ||
``` | ||
|
||
=== "Python 3.8+" | ||
|
||
```Python hl_lines="24-39" | ||
{!> ../../../docs_src/schema_extra_example/tutorial004_an.py!} | ||
``` | ||
|
||
=== "Python 3.10+ non-Annotated" | ||
|
||
!!! tip "Tipp" | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="19-34" | ||
{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!} | ||
``` | ||
|
||
=== "Python 3.8+ non-Annotated" | ||
|
||
!!! tip "Tipp" | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="21-36" | ||
{!> ../../../docs_src/schema_extra_example/tutorial004.py!} | ||
``` | ||
|
||
When you do this, the examples will be part of the internal **JSON Schema** for that body data. | ||
|
||
Nevertheless, at the <abbr title="2023-08-26">time of writing this</abbr>, Swagger UI, the tool in charge of showing the docs UI, doesn't support showing multiple examples for the data in **JSON Schema**. But read below for a workaround. | ||
|
||
### OpenAPI-specific `examples` | ||
|
||
Since before **JSON Schema** supported `examples` OpenAPI had support for a different field also called `examples`. | ||
|
||
This **OpenAPI-specific** `examples` goes in another section in the OpenAPI specification. It goes in the **details for each *path operation***, not inside each JSON Schema. | ||
|
||
And Swagger UI has supported this particular `examples` field for a while. So, you can use it to **show** different **examples in the docs UI**. | ||
|
||
The shape of this OpenAPI-specific field `examples` is a `dict` with **multiple examples** (instead of a `list`), each with extra information that will be added to **OpenAPI** too. | ||
|
||
This doesn't go inside of each JSON Schema contained in OpenAPI, this goes outside, in the *path operation* directly. | ||
|
||
### Using the `openapi_examples` Parameter | ||
|
||
You can declare the OpenAPI-specific `examples` in FastAPI with the parameter `openapi_examples` for: | ||
|
||
* `Path()` | ||
* `Query()` | ||
* `Header()` | ||
* `Cookie()` | ||
* `Body()` | ||
* `Form()` | ||
* `File()` | ||
|
||
The keys of the `dict` identify each example, and each value is another `dict`. | ||
|
||
Each specific example `dict` in the `examples` can contain: | ||
|
||
* `summary`: Short description for the example. | ||
* `description`: A long description that can contain Markdown text. | ||
* `value`: This is the actual example shown, e.g. a `dict`. | ||
* `externalValue`: alternative to `value`, a URL pointing to the example. Although this might not be supported by as many tools as `value`. | ||
|
||
You can use it like this: | ||
|
||
=== "Python 3.10+" | ||
|
||
```Python hl_lines="23-49" | ||
{!> ../../../docs_src/schema_extra_example/tutorial005_an_py310.py!} | ||
``` | ||
|
||
=== "Python 3.9+" | ||
|
||
```Python hl_lines="23-49" | ||
{!> ../../../docs_src/schema_extra_example/tutorial005_an_py39.py!} | ||
``` | ||
|
||
=== "Python 3.8+" | ||
|
||
```Python hl_lines="24-50" | ||
{!> ../../../docs_src/schema_extra_example/tutorial005_an.py!} | ||
``` | ||
|
||
=== "Python 3.10+ non-Annotated" | ||
|
||
!!! tip "Tipp" | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="19-45" | ||
{!> ../../../docs_src/schema_extra_example/tutorial005_py310.py!} | ||
``` | ||
|
||
=== "Python 3.8+ non-Annotated" | ||
|
||
!!! tip "Tipp" | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="21-47" | ||
{!> ../../../docs_src/schema_extra_example/tutorial005.py!} | ||
``` | ||
|
||
### OpenAPI Examples in the Docs UI | ||
|
||
With `openapi_examples` added to `Body()` the `/docs` would look like: | ||
|
||
<img src="/img/tutorial/body-fields/image02.png"> | ||
|
||
## Technical Details | ||
|
||
!!! tip "Tipp" | ||
If you are already using **FastAPI** version **0.99.0 or above**, you can probably **skip** these details. | ||
|
||
They are more relevant for older versions, before OpenAPI 3.1.0 was available. | ||
|
||
You can consider this a brief OpenAPI and JSON Schema **history lesson**. 🤓 | ||
|
||
!!! warning | ||
These are very technical details about the standards **JSON Schema** and **OpenAPI**. | ||
|
||
If the ideas above already work for you, that might be enough, and you probably don't need these details, feel free to skip them. | ||
|
||
Before OpenAPI 3.1.0, OpenAPI used an older and modified version of **JSON Schema**. | ||
|
||
JSON Schema didn't have `examples`, so OpenAPI added it's own `example` field to its own modified version. | ||
|
||
OpenAPI also added `example` and `examples` fields to other parts of the specification: | ||
|
||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object" class="external-link" target="_blank">`Parameter Object` (in the specification)</a> that was used by FastAPI's: | ||
* `Path()` | ||
* `Query()` | ||
* `Header()` | ||
* `Cookie()` | ||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object" class="external-link" target="_blank">`Request Body Object`, in the field `content`, on the `Media Type Object` (in the specification)</a> that was used by FastAPI's: | ||
* `Body()` | ||
* `File()` | ||
* `Form()` | ||
|
||
!!! info | ||
This old OpenAPI-specific `examples` parameter is now `openapi_examples` since FastAPI `0.103.0`. | ||
|
||
### JSON Schema's `examples` field | ||
|
||
But then JSON Schema added an <a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a> field to a new version of the specification. | ||
|
||
And then the new OpenAPI 3.1.0 was based on the latest version (JSON Schema 2020-12) that included this new field `examples`. | ||
|
||
And now this new `examples` field takes precedence over the old single (and custom) `example` field, that is now deprecated. | ||
|
||
This new `examples` field in JSON Schema is **just a `list`** of examples, not a dict with extra metadata as in the other places in OpenAPI (described above). | ||
|
||
!!! info | ||
Even after OpenAPI 3.1.0 was released with this new simpler integration with JSON Schema, for a while, Swagger UI, the tool that provides the automatic docs, didn't support OpenAPI 3.1.0 (it does since version 5.0.0 🎉). | ||
|
||
Because of that, versions of FastAPI previous to 0.99.0 still used versions of OpenAPI lower than 3.1.0. | ||
|
||
### Pydantic and FastAPI `examples` | ||
|
||
When you add `examples` inside of a Pydantic model, using `schema_extra` or `Field(examples=["something"])` that example is added to the **JSON Schema** for that Pydantic model. | ||
|
||
And that **JSON Schema** of the Pydantic model is included in the **OpenAPI** of your API, and then it's used in the docs UI. | ||
|
||
In versions of FastAPI before 0.99.0 (0.99.0 and above use the newer OpenAPI 3.1.0) when you used `example` or `examples` with any of the other utilities (`Query()`, `Body()`, etc.) those examples were not added to the JSON Schema that describes that data (not even to OpenAPI's own version of JSON Schema), they were added directly to the *path operation* declaration in OpenAPI (outside the parts of OpenAPI that use JSON Schema). | ||
|
||
But now that FastAPI 0.99.0 and above uses OpenAPI 3.1.0, that uses JSON Schema 2020-12, and Swagger UI 5.0.0 and above, everything is more consistent and the examples are included in JSON Schema. | ||
|
||
### Swagger UI and OpenAPI-specific `examples` | ||
|
||
Now, as Swagger UI didn't support multiple JSON Schema examples (as of 2023-08-26), users didn't have a way to show multiple examples in the docs. | ||
|
||
To solve that, FastAPI `0.103.0` **added support** for declaring the same old **OpenAPI-specific** `examples` field with the new parameter `openapi_examples`. 🤓 | ||
|
||
### Summary | ||
|
||
I used to say I didn't like history that much... and look at me now giving "tech history" lessons. 😅 | ||
|
||
In short, **upgrade to FastAPI 0.99.0 or above**, and things are much **simpler, consistent, and intuitive**, and you don't have to know all these historic details. 😎 |