//// tab | Test
-/// info
-Some text
-///
-
/// note
Some text
///
Some text
///
-/// check
-Some text
-///
-
/// tip
Some text
///
///
-/// info
+/// note
The `model` key is not part of OpenAPI.
///
-/// info
+/// note
Unless you specify a different media type explicitly in your `responses` parameter, FastAPI will assume the response has the same media type as the main response class (default `application/json`).
This behavior was reverted in 0.118.0, to make the exit code after `yield` be executed after the response is sent.
-/// info
+/// note
As you will see below, this is very similar to the behavior before version 0.106.0, but with several improvements and bug fixes for corner cases.
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
-/// info
+/// note
The parameter `response_class` will also be used to define the "media type" of the response.
///
-/// info
+/// note
Of course, the actual `Content-Type` header, status code, etc, will come from the `Response` object you returned.
This works the same way as with Pydantic models. And it is actually achieved in the same way underneath, using Pydantic.
-/// info
+/// note
Keep in mind that dataclasses can't do everything Pydantic models can do.
Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.
-/// info
+/// note
In the `open()` function, the `mode="a"` means "append", so, the line will be added after whatever is on that file, without overwriting the previous contents.
Underneath, in the ASGI technical specification, this is part of the [Lifespan Protocol](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), and it defines events called `startup` and `shutdown`.
-/// info
+/// note
You can read more about the Starlette `lifespan` handlers in [Starlette's Lifespan' docs](https://www.starlette.dev/lifespan/).
This can make it a lot easier for your users to **implement their APIs** to receive your **webhook** requests, they might even be able to autogenerate some of their own API code.
-/// info
+/// note
Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0` and above.
The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**.
-/// info
+/// note
The `app.webhooks` object is actually just an `APIRouter`, the same type you would use when structuring your app with multiple files.
You can return a `Response` or any sub-class of it.
-/// info
+/// note
`JSONResponse` itself is a sub-class of `Response`.
* `instagram_basic` is used by Facebook / Instagram.
* `https://www.googleapis.com/auth/drive` is used by Google.
-/// info
+/// note
In OAuth2 a "scope" is just a string that declares a specific permission required.
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
-/// info | Technical Details
+/// note | Technical Details
`Security` is actually a subclass of `Depends`, and it has just one extra parameter that we'll see later.
But if you want to **stream pure binary data** or strings, here's how you can do it.
-/// info
+/// note
Added in FastAPI 0.134.0.
And in many cases, reading them would be a blocking operation (that could block the event loop), because they are read from disk or from the network.
-/// info
+/// note
The example above is actually an exception, because the `io.BytesIO` object is already in memory, so reading it won't block anything.
With this setting, requests without a `Content-Type` header will have their body parsed as JSON, which is the same behavior as older versions of FastAPI.
-/// info
+/// note
This behavior and configuration was added in FastAPI 0.132.0.
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *}
-/// info
+/// note
As this is a WebSocket it doesn't really make sense to raise an `HTTPException`, instead we raise a `WebSocketException`.
## Using `WSGIMiddleware` { #using-wsgimiddleware }
-/// info
+/// note
This requires installing `a2wsgi` for example with `pip install a2wsgi`.
///
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Have an automatic API documentation web user interface.
Given the simplicity of Flask, it seemed like a good match for building APIs. The next thing to find was a "Django REST Framework" for Flask.
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Be a micro-framework. Making it easy to mix and match the tools and parts needed.
See the similarities in `requests.get(...)` and `@app.get(...)`.
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
* Have a simple and intuitive API.
* Use HTTP method names (operations) directly, in a straightforward and intuitive way.
That's why when talking about version 2.0 it's common to say "Swagger", and for version 3+ "OpenAPI".
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Adopt and use an open standard for API specifications, instead of a custom schema.
But it was created before there existed Python type hints. So, to define every <dfn title="the definition of how data should be formed">schema</dfn> you need to use specific utils and classes provided by Marshmallow.
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Use code to define "schemas" that provide data types and validation, automatically.
It's a great tool and I have used it a lot too, before having **FastAPI**.
-/// info
+/// note
Webargs was created by the same Marshmallow developers.
///
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Have automatic validation of incoming request data.
The editor can't help much with that. And if we modify parameters or Marshmallow schemas and forget to also modify that YAML docstring, the generated schema would be obsolete.
-/// info
+/// note
APISpec was created by the same Marshmallow developers.
///
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Support the open standard for APIs, OpenAPI.
And these same full-stack generators were the base of the [**FastAPI** Project Generators](project-generation.md).
-/// info
+/// note
Flask-apispec was created by the same Marshmallow developers.
///
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Generate the OpenAPI schema automatically, from the same code that defines serialization and validation.
It can't handle nested models very well. So, if the JSON body in the request is a JSON object that has inner fields that in turn are nested JSON objects, it cannot be properly documented and validated.
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Use Python types to have great editor support.
///
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Find a way to have a crazy performance.
So, data validation, serialization, and documentation, have to be done in code, not automatically. Or they have to be implemented as a framework on top of Falcon, like Hug. This same distinction happens in other frameworks that are inspired by Falcon's design, of having one request object and one response object as parameters.
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Find ways to get great performance.
Routes are declared in a single place, using functions declared in other places (instead of using decorators that can be placed right on top of the function that handles the endpoint). This is closer to how Django does it than to how Flask (and Starlette) does it. It separates in the code things that are relatively tightly coupled.
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Define extra validations for data types using the "default" value of model attributes. This improves editor support, and it was not available in Pydantic before.
As it is based on the previous standard for synchronous Python web frameworks (WSGI), it can't handle Websockets and other things, although it still has high performance too.
-/// info
+/// note
Hug was created by Timothy Crosley, the same creator of [`isort`](https://github.com/timothycrosley/isort), a great tool to automatically sort imports in Python files.
///
-/// check | Ideas inspiring **FastAPI**
+/// tip | Ideas inspiring **FastAPI**
Hug inspired parts of APIStar, and was one of the tools I found most promising, alongside APIStar.
Now APIStar is a set of tools to validate OpenAPI specifications, not a web framework.
-/// info
+/// note
APIStar was created by Tom Christie. The same guy that created:
///
-/// check | Inspired **FastAPI** to
+/// tip | Inspired **FastAPI** to
Exist.
It is comparable to Marshmallow. Although it's faster than Marshmallow in benchmarks. And as it is based on the same Python type hints, the editor support is great.
-/// check | **FastAPI** uses it to
+/// tip | **FastAPI** uses it to
Handle all the data validation, data serialization and automatic model documentation (based on JSON Schema).
///
-/// check | **FastAPI** uses it to
+/// tip | **FastAPI** uses it to
Handle all the core web parts. Adding features on top.
It is the recommended server for Starlette and **FastAPI**.
-/// check | **FastAPI** recommends it as
+/// tip | **FastAPI** recommends it as
The main web server to run **FastAPI** applications.
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
-/// info
+/// note
Beautiful illustrations by [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
There was not much talk or flirting as most of the time was spent waiting 🕙 in front of the counter. 😞
-/// info
+/// note
Beautiful illustrations by [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
</div>
-/// info
+/// note
There are other formats and tools to define and install package dependencies.
If you have **multiple containers**, probably each one running a **single process** (for example, in a **Kubernetes** cluster), then you would probably want to have a **separate container** doing the work of the **previous steps** in a single container, running a single process, **before** running the replicated worker containers.
-/// info
+/// note
If you are using Kubernetes, this would probably be an [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
Here I'll show you how to use **Uvicorn** with **worker processes** using the `fastapi` command or the `uvicorn` command directly.
-/// info
+/// note
If you are using containers, for example with Docker or Kubernetes, I'll tell you more about that in the next chapter: [FastAPI in Containers - Docker](docker.md).
You could easily use a search engine or video platform to find many resources related to FastAPI.
-/// info
+/// note
Before, this page used to list links to external articles.
my_second_user: User = User(**second_user_data)
```
-/// info
+/// note
`**second_user_data` means:
* Then **comment** saying that you did that, that's how I will know you really checked it.
-/// info
+/// note
Unfortunately, I can't simply trust PRs that just have several approvals.
* `description`: The description of your API, this can include markdown and will be shown in the docs.
* `routes`: A list of routes, these are each of the registered *path operations*. They are taken from `app.routes`.
-/// info
+/// note
The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by FastAPI 0.99.0 and above.
In that case, you can disable this feature in **FastAPI**, with the parameter `separate_input_output_schemas=False`.
-/// info
+/// note
Support for `separate_input_output_schemas` was added in FastAPI `0.102.0`. 🤓
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
-/// info
+/// note
Those internal types in the square brackets are called "type parameters".
{* ../../docs_src/python_types/tutorial011_py310.py *}
-/// info
+/// note
To learn more about [Pydantic, check its docs](https://docs.pydantic.dev/).
The important thing is that by using standard Python types, in a single place (instead of adding more classes, decorators, etc), **FastAPI** will do a lot of the work for you.
-/// info
+/// note
If you already went through all the tutorial and came back to see more about types, a good resource is [the "cheat sheet" from `mypy`](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html).
**FastAPI** provides a convenience tool to structure your application while keeping all the flexibility.
-/// info
+/// note
If you come from Flask, this would be the equivalent of Flask's Blueprints.
///
-/// check
+/// tip
The `prefix`, `tags`, `responses`, and `dependencies` parameters are (as in many other cases) just a feature from **FastAPI** to help you avoid code duplication.
from app.routers import items, users
```
-/// info
+/// note
The first version is a "relative import":
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
-/// info
+/// note
`users.router` contains the `APIRouter` inside of the file `app/routers/users.py`.
///
-/// check
+/// tip
You don't have to worry about performance when including routers.
and it will work correctly, together with all the other *path operations* added with `app.include_router()`.
-/// info | Very Technical Details
+/// note | Very Technical Details
**Note**: this is a very technical detail that you probably can **just skip**.
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
-/// info
+/// note
`Body` also has all the same extra validation and metadata parameters as `Query`, `Path` and others you will see later.
}
```
-/// info
+/// note
Notice how the `images` key now has a list of image objects.
{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
-/// info
+/// note
Notice how `Offer` has a list of `Item`s, which in turn have an optional list of `Image`s
To declare a **request** body, you use [Pydantic](https://docs.pydantic.dev/) models with all their power and benefits.
-/// info
+/// note
To send data, you should use one of: `POST` (the more common), `PUT`, `DELETE` or `PATCH`.
<img src="/img/tutorial/cookie-param-models/image01.png">
</div>
-/// info
+/// note
Have in mind that, as **browsers handle cookies** in special ways and behind the scenes, they **don't** easily allow **JavaScript** to touch them.
///
-/// info
+/// note
To declare cookies, you need to use `Cookie`, because otherwise the parameters would be interpreted as query parameters.
///
-/// info
+/// note
Have in mind that, as **browsers handle cookies** in special ways and behind the scenes, they **don't** easily allow **JavaScript** to touch them.
will not be executed.
-/// info
+/// note
For more information, check [the official Python docs](https://docs.python.org/3/library/__main__.html).
///
-/// info
+/// note
In this example we use invented custom headers `X-Key` and `X-Token`.
end
```
-/// info
+/// note
Only **one response** will be sent to the client. It might be one of the error responses or it will be the response from the *path operation*.
And then it just returns a `dict` containing those values.
-/// info
+/// note
FastAPI added support for `Annotated` (and started recommending it) in version 0.95.0.
This way you write shared code once and **FastAPI** takes care of calling it for your *path operations*.
-/// check
+/// tip
Notice that you don't have to create a special class and pass it somewhere to **FastAPI** to "register" it or anything similar.
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
-/// info
+/// note
Notice that we are only declaring one dependency in the *path operation function*, the `query_or_cookie_extractor`.
/items/foo
```
-/// info
+/// note
A "path" is also commonly called an "endpoint" or a "route".
* the path `/`
* using a <dfn title="an HTTP GET method"><code>get</code> operation</dfn>
-/// info | `@decorator` Info
+/// note | `@decorator` Info
That `@something` syntax in Python is called a "decorator".
///
-/// info
+/// note
To declare headers, you need to use `Header`, because otherwise the parameters would be interpreted as query parameters.
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
-/// info
+/// note
Read more about tags in [Path Operation Configuration](path-operation-configuration.md#tags).
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
-/// info
+/// note
Notice that `response_description` refers specifically to the response, the `description` refers to the *path operation* in general.
///
-/// check
+/// tip
OpenAPI specifies that each *path operation* requires a response description.
{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
-/// info
+/// note
FastAPI added support for `Annotated` (and started recommending it) in version 0.95.0.
* `lt`: `l`ess `t`han
* `le`: `l`ess than or `e`qual
-/// info
+/// note
`Query`, `Path`, and other classes you will see later are subclasses of a common `Param` class.
In this case, `item_id` is declared to be an `int`.
-/// check
+/// tip
This will give you editor support inside of your function, with error checks, completion, etc.
{"item_id":3}
```
-/// check
+/// tip
Notice that the value your function received (and returned) is `3`, as a Python `int`, not a string `"3"`.
The same error would appear if you provided a `float` instead of an `int`, as in: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
-/// check
+/// tip
So, with the same Python type declaration, **FastAPI** gives you data validation.
<img src="/img/tutorial/path-params/image01.png">
-/// check
+/// tip
Again, just with that same Python type declaration, **FastAPI** gives you automatic, interactive documentation (integrating Swagger UI).
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
-/// info
+/// note
FastAPI added support for `Annotated` (and started recommending it) in version 0.95.0.
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
-/// info
+/// note
This is available with Pydantic version 2 or above. 😎
In this case, the function parameter `q` will be optional, and will be `None` by default.
-/// check
+/// tip
Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter.
You can define files to be uploaded by the client using `File`.
-/// info
+/// note
To receive uploaded files, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
-/// info
+/// note
`File` is a class that inherits directly from `Form`.
You can use **Pydantic models** to declare **form fields** in FastAPI.
-/// info
+/// note
To use forms, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
You can define files and form fields at the same time using `File` and `Form`.
-/// info
+/// note
To receive uploaded files and/or form data, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
When you need to receive form fields instead of JSON, you can use `Form`.
-/// info
+/// note
To use forms, first install [`python-multipart`](https://github.com/Kludex/python-multipart).
With `Form` you can declare the same configurations as with `Body` (and `Query`, `Path`, `Cookie`), including validation, examples, an alias (e.g. `user-name` instead of `username`), etc.
-/// info
+/// note
`Form` is a class that inherits directly from `Body`.
{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
-/// info
+/// note
To use `EmailStr`, first install [`email-validator`](https://github.com/JoshData/python-email-validator).
}
```
-/// info
+/// note
You can also use:
The `status_code` parameter receives a number with the HTTP status code.
-/// info
+/// note
`status_code` can alternatively also receive an `IntEnum`, such as Python's [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus).
///
-/// info
+/// note
OpenAPI 3.1.0 (used since FastAPI 0.99.0) added support for `examples`, which is part of the **JSON Schema** standard.
* `File()`
* `Form()`
-/// info
+/// note
This old OpenAPI-specific `examples` parameter is now `openapi_examples` since FastAPI `0.103.0`.
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
+/// note
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 🎉).
## Run it { #run-it }
-/// info
+/// note
The [`python-multipart`](https://github.com/Kludex/python-multipart) package is automatically installed with **FastAPI** when you run the `pip install "fastapi[standard]"` command.
<img src="/img/tutorial/security/image01.png">
-/// check | Authorize button!
+/// tip | Authorize button!
You already have a shiny new "Authorize" button.
In this example we are going to use **OAuth2**, with the **Password** flow, using a **Bearer** token. We do that using the `OAuth2PasswordBearer` class.
-/// info
+/// note
A "bearer" token is not the only option.
We will soon also create the actual path operation.
-/// info
+/// note
If you are a very strict "Pythonista" you might dislike the style of the parameter name `tokenUrl` instead of `token_url`.
**FastAPI** will know that it can use this dependency to define a "security scheme" in the OpenAPI schema (and the automatic API docs).
-/// info | Technical Details
+/// note | Technical Details
**FastAPI** will know that it can use the class `OAuth2PasswordBearer` (declared in a dependency) to define the security scheme in OpenAPI because it inherits from `fastapi.security.oauth2.OAuth2`, which in turn inherits from `fastapi.security.base.SecurityBase`.
///
-/// check
+/// tip
The way this dependency system is designed allows us to have different dependencies (different "dependables") that all return a `User` model.
</div>
-/// info
+/// note
If you are planning to use digital signature algorithms like RSA or ECDSA, you should install the cryptography library dependency `pyjwt[crypto]`.
Username: `johndoe`
Password: `secret`
-/// check
+/// tip
Notice that nowhere in the code is the plaintext password "`secret`", we only have the hashed version.
* `instagram_basic` is used by Facebook / Instagram.
* `https://www.googleapis.com/auth/drive` is used by Google.
-/// info
+/// note
In OAuth2 a "scope" is just a string that declares a specific permission required.
* An optional `client_id` (we don't need it for our example).
* An optional `client_secret` (we don't need it for our example).
-/// info
+/// note
The `OAuth2PasswordRequestForm` is not a special class for **FastAPI** as is `OAuth2PasswordBearer`.
)
```
-/// info
+/// note
For a more complete explanation of `**user_dict` check back in [the documentation for **Extra Models**](../extra-models.md#about-user-in-dict).
{* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *}
-/// info
+/// note
The additional header `WWW-Authenticate` with value `Bearer` we are returning here is also part of the spec.
This is similar to [Stream JSON Lines](stream-json-lines.md), but uses the `text/event-stream` format, which is supported natively by browsers with the [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
-/// info
+/// note
Added in FastAPI 0.135.0.
You could have a sequence of data that you would like to send in a "**stream**", you could do it with **JSON Lines**.
-/// info
+/// note
Added in FastAPI 0.134.0.
It's very similar to a JSON array (equivalent of a Python list), but instead of being wrapped in `[]` and having `,` between the items, it has **one JSON object per line**, they are separated by a new line character.
-/// info
+/// note
The important point is that your app will be able to produce each line in turn, while the client consumes the previous lines.
## Using `TestClient` { #using-testclient }
-/// info
+/// note
To use `TestClient`, first install [`httpx`](https://www.python-httpx.org).
For more information about how to pass data to the backend (using `httpx` or the `TestClient`) check the [HTTPX documentation](https://www.python-httpx.org).
-/// info
+/// note
Note that the `TestClient` receives data that can be converted to JSON, not Pydantic models.
When you work in Python projects you probably should use a **virtual environment** (or a similar mechanism) to isolate the packages you install for each project.
-/// info
+/// note
If you already know about virtual environments, how to create them and use them, you might want to skip this section. 🤓
///
-/// info
+/// note
This page will teach you how to use **virtual environments** and how they work.
format: !!python/name:pymdownx.superfences.fence_code_format ''
pymdownx.tilde: null
pymdownx.blocks.admonition:
+ # TODO: remove types section (with custom types) once translations are migrated to
+ # not use custom types too
types:
+ # Default types
- note
- attention
- caution
- tip
- hint
- warning
+ # Custom types
- info
- check
pymdownx.blocks.details: null