# Doc: README.md | Page: README.md | Section: README.md

    FastAPI framework, high performance, easy to learn, fast to code, ready for production

---

**Documentation**: [https://fastapi.tiangolo.com](https://fastapi.tiangolo.com)

**Source Code**: [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)

---

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints.

The key features are:

* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <dfn title="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (previously known as Swagger) and [JSON Schema](https://json-schema.org/).

* estimation based on tests conducted by an internal development team, building production applications.


# Doc: README.md | Page: README.md | Section: Sponsors
## Sponsors

### Keystone Sponsor

### Gold Sponsors

### Silver Sponsors

[Other sponsors](https://fastapi.tiangolo.com/fastapi-people/#sponsors)


# Doc: README.md | Page: README.md | Section: Opinions
## Opinions

"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"

Kabir Khan - Microsoft (ref)

---

"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"

Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)

---

"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"

Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)

---

"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"

Deon Pillsbury - Cisco (ref)

---


# Doc: README.md | Page: README.md | Section: FastAPI Conf
## FastAPI Conf

[**FastAPI Conf '26**](https://fastapiconf.com) is happening on **October 28, 2026** in **Amsterdam, NL**. All about FastAPI, right from the source. 🎤


# Doc: README.md | Page: README.md | Section: FastAPI mini documentary
## FastAPI mini documentary

There's a [FastAPI mini documentary](https://www.youtube.com/watch?v=mpR8ngthqiE) released at the end of 2025, you can watch it online:


README.md::**Typer**, the FastAPI of CLIs::L120

# Doc: README.md | Page: README.md | Section: **Typer**, the FastAPI of CLIs
## **Typer**, the FastAPI of CLIs

If you are building a CLI app to be used in the terminal instead of a web API, check out [**Typer**](https://typer.tiangolo.com/).

**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨ 🚀


# Doc: README.md | Page: README.md | Section: Requirements
## Requirements

FastAPI stands on the shoulders of giants:

* [Starlette](https://www.starlette.dev/) for the web parts.
* [Pydantic](https://docs.pydantic.dev/) for the data parts.


# Doc: README.md | Page: README.md | Section: Installation
## Installation

Create and activate a [virtual environment](https://fastapi.tiangolo.com/virtual-environments/) and then install FastAPI:

<div class="termy">

```console
$ pip install "fastapi[standard]"

---> 100%
```

</div>

**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.


# Doc: README.md | Page: README.md | Section: Example
## Example

### Create it

Create a file `main.py` with:

```Python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}
```

Or use async def...

If your code uses `async` / `await`, use `async def`:

```Python hl_lines="7  12"
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}
```

**Note**:

If you don't know, check the _"In a hurry?"_ section about [`async` and `await` in the docs](https://fastapi.tiangolo.com/async/#in-a-hurry).

### Run it

Run the server with:

```console
$ fastapi dev

 ╭────────── FastAPI CLI - Development mode ───────────╮
 │                                                     │
 │  Serving at: http://127.0.0.1:8000                  │
 │                                                     │
 │  API docs: http://127.0.0.1:8000/docs               │
 │                                                     │
 │  Running in development mode, for production use:   │
 │                                                     │
 │  fastapi run                                        │
 │                                                     │
 ╰─────────────────────────────────────────────────────╯

INFO:     Will watch for changes in these directories: ['/home/user/code/awesomeapp']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [2248755] using WatchFiles
INFO:     Started server process [2248757]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
```

About the command fastapi dev...

The command `fastapi dev` reads your `main.py` file automatically, detects the **FastAPI** app in it, and starts a server using [Uvicorn](https://www.uvicorn.dev).

By default, `fastapi dev` will start with auto-reload enabled for local development.

You can read more about it in the [FastAPI CLI docs](https://fastapi.tiangolo.com/fastapi-cli/).

### Check it

Open your browser at [http://127.0.0.1:8000/items/5?q=somequery](http://127.0.0.1:8000/items/5?q=somequery).

You will see the JSON response as:

```JSON
{"item_id": 5, "q": "somequery"}
```

You already created an API that:

* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
* Both _paths_ take `GET` operations (also known as HTTP _methods_).
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.

### Interactive API docs

Now go to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).

You will see the automatic interactive API documentation (provided by [Swagger UI](https://github.com/swagger-api/swagger-ui)):

![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)

### Alternative API docs

And now, go to [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).

You will see the alternative automatic documentation (provided by [ReDoc](https://github.com/Rebilly/ReDoc)):

![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)


# Doc: README.md | Page: README.md | Section: Example upgrade
## Example upgrade

Now modify the file `main.py` to receive a body from a `PUT` request.

Declare the body using standard Python types, thanks to Pydantic.

```Python hl_lines="2  7-10 23-25"
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    is_offer: bool | None = None

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "item_id": item_id}
```

The `fastapi dev` server should reload automatically.

### Interactive API docs upgrade

Now go to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).

* The interactive API documentation will be automatically updated, including the new body:

![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)

* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:

![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)

* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:

![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)

### Alternative API docs upgrade

And now, go to [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).

* The alternative documentation will also reflect the new query parameter and body:

![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)

### Recap

In summary, you declare **once** the types of parameters, body, etc. as function parameters.

You do that with standard modern Python types.

You don't have to learn a new syntax, the methods or classes of a specific library, etc.

Just standard **Python**.

For example, for an `int`:

```Python
item_id: int
```

or for a more complex `Item` model:

```Python
item: Item
```

...and with that single declaration you get:

* Editor support, including:
    * Completion.
    * Type checks.
* Validation of data:
    * Automatic and clear errors when the data is invalid.
    * Validation even for deeply nested JSON objects.
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
    * JSON.
    * Path parameters.
    * Query parameters.
    * Cookies.
    * Headers.
    * Forms.
    * Files.
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
    * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
    * `datetime` objects.
    * `UUID` objects.
    * Database models.
    * ...and many more.
* Automatic interactive API documentation, including 2 alternative user interfaces:
    * Swagger UI.
    * ReDoc.

---

Coming back to the previous code example, **FastAPI** will:

* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
    * If it is not, the client will see a useful, clear error.
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
    * As the `q` parameter is declared with `= None`, it is optional.
    * Without the `None` it would be required (as is the body in the case with `PUT`).
* For `PUT` requests to `/items/{item_id}`, read the body as JSON:
    * Check that it has a required attribute `name` that should be a `str`.
    * Check that it has a required attribute `price` that has to be a `float`.
    * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
    * All this would also work for deeply nested JSON objects.
* Convert from and to JSON automatically.
* Document everything with OpenAPI, that can be used by:
    * Interactive documentation systems.
    * Automatic client code generation systems, for many languages.
* Provide 2 interactive documentation web interfaces directly.

---

We just scratched the surface, but you already get the idea of how it all works.

Try changing the line with:

```Python
    return {"item_name": item.name, "item_id": item_id}
```

...from:

```Python
        ... "item_name": item.name ...
```

...to:

```Python
        ... "item_price": item.price ...
```

...and see how your editor will auto-complete the attributes and know their types:

![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)

For a more complete example including more features, see the Tutorial - User Guide.

**Spoiler alert**: the tutorial - user guide includes:

* Declaration of **parameters** from other different places such as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** such as `maximum_length` or `regex`.
* A very powerful and easy to use **<dfn title="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with [Strawberry](https://strawberry.rocks) and other libraries.
* Many extra features (thanks to Starlette) such as:
    * **WebSockets**
    * extremely easy tests based on HTTPX and `pytest`
    * **CORS**
    * **Cookie Sessions**
    * ...and more.

### Deploy your app (optional)

You can optionally deploy your FastAPI app to [FastAPI Cloud](https://fastapicloud.com) with a single command. 🚀

```console
$ fastapi deploy

Deploying to FastAPI Cloud...

✅ Deployment successful!

🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```

The CLI will automatically detect your FastAPI application and deploy it to the cloud. If you are not logged in, your browser will open to complete the authentication process.

That's it! Now you can access your app at that URL. ✨

#### About FastAPI Cloud

**[FastAPI Cloud](https://fastapicloud.com)** is built by the same author and team behind **FastAPI**.

It streamlines the process of **building**, **deploying**, and **accessing** an API with minimal effort.

It brings the same **developer experience** of building apps with FastAPI to **deploying** them to the cloud. 🎉

FastAPI Cloud is the primary sponsor and funding provider for the *FastAPI and friends* open source projects. ✨

#### Deploy to other cloud providers

FastAPI is open source and based on standards. You can deploy FastAPI apps to any cloud provider you choose.

Follow your cloud provider's guides to deploy FastAPI apps with them. 🤓


# Doc: README.md | Page: README.md | Section: Performance
## Performance

Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as [one of the fastest Python frameworks available](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)

To understand more about it, see the section [Benchmarks](https://fastapi.tiangolo.com/benchmarks/).


# Doc: README.md | Page: README.md | Section: Dependencies
## Dependencies

FastAPI depends on Pydantic and Starlette.

### `standard` Dependencies

When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies:

Used by Pydantic:

* [`email-validator`](https://github.com/JoshData/python-email-validator) - for email validation.

Used by Starlette:

* [`httpx`](https://www.python-httpx.org) - Required if you want to use the `TestClient`.
* [`jinja2`](https://jinja.palletsprojects.com) - Required if you want to use the default template configuration.
* [`python-multipart`](https://github.com/Kludex/python-multipart) - Required if you want to support form <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.

Used by FastAPI:

* [`uvicorn`](https://www.uvicorn.dev) - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving.
* `fastapi-cli[standard]` - to provide the `fastapi` command.
    * This includes `fastapi-cloud-cli`, which allows you to deploy your FastAPI application to [FastAPI Cloud](https://fastapicloud.com).

### Without `standard` Dependencies

If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.

### Without `fastapi-cloud-cli`

If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.

### Additional Optional Dependencies

There are some additional dependencies you might want to install.

Additional optional Pydantic dependencies:

* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) - for settings management.
* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) - for extra types to be used with Pydantic.

Additional optional FastAPI dependencies:

* [`orjson`](https://github.com/ijl/orjson) - Required if you want to use `ORJSONResponse`.
* [`ujson`](https://github.com/esnme/ultrajson) - Required if you want to use `UJSONResponse`.


# Doc: README.md | Page: README.md | Section: License
## License

This project is licensed under the terms of the MIT license.


docs/en/docs/_llm-test.md::LLM test file { #llm-test-file }::L1

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: LLM test file { #llm-test-file }
# LLM test file { #llm-test-file }

This document tests if the <abbr title="Large Language Model">LLM</abbr>, which translates the documentation, understands the `general_prompt` in `scripts/translate.py` and the language specific prompt in `docs/{language code}/llm-prompt.md`. The language specific prompt is appended to `general_prompt`.

Tests added here will be seen by all designers of language specific prompts.

Use as follows:

* Have a language specific prompt - `docs/{language code}/llm-prompt.md`.
* Do a fresh translation of this document into your desired target language (see e.g. the `translate-page` command of the `translate.py`). This will create the translation under `docs/{language code}/docs/_llm-test.md`.
* Check if things are okay in the translation.
* If necessary, improve your language specific prompt, the general prompt, or the English document.
* Then manually fix the remaining issues in the translation, so that it is a good translation.
* Retranslate, having the good translation in place. The ideal result would be that the LLM makes no changes anymore to the translation. That means that the general prompt and your language specific prompt are as good as they can be (It will sometimes make a few seemingly random changes, the reason is that [LLMs are not deterministic algorithms](https://doublespeak.chat/#/handbook#deterministic-output)).

The tests:


docs/en/docs/_llm-test.md::Code snippets { #code-snippets }::L18

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: Code snippets { #code-snippets }
## Code snippets { #code-snippets }

//// tab | Test

This is a code snippet: `foo`. And this is another code snippet: `bar`. And another one: `baz quux`.

////

//// tab | Info

Content of code snippets should be left as is.

See section `### Content of code snippets` in the general prompt in `scripts/translate.py`.

////


docs/en/docs/_llm-test.md::Quotes { #quotes }::L34

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: Quotes { #quotes }
## Quotes { #quotes }

//// tab | Test

Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'".

/// note

The LLM will probably translate this wrong. Interesting is only if it keeps the fixed translation when retranslating.

///

////

//// tab | Info

The prompt designer may choose if they want to convert neutral quotes to typographic quotes. It is okay to leave them as is.

See for example section `### Quotes` in `docs/de/llm-prompt.md`.

////


docs/en/docs/_llm-test.md::Quotes in code snippets { #quotes-in-code-snippets }::L56

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: Quotes in code snippets { #quotes-in-code-snippets }
## Quotes in code snippets { #quotes-in-code-snippets }

//// tab | Test

`pip install "foo[bar]"`

Examples for string literals in code snippets: `"this"`, `'that'`.

A difficult example for string literals in code snippets: `f"I like {'oranges' if orange else "apples"}"`

Hardcore: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"`

////

//// tab | Info

... However, quotes inside code snippets must stay as is.

////


docs/en/docs/_llm-test.md::code blocks { #code-blocks }::L76

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: code blocks { #code-blocks }
## code blocks { #code-blocks }

//// tab | Test

A Bash code example...

```bash
# Print a greeting to the universe
echo "Hello universe"
```

...and a console code example...

```console
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting server
        Searching for package file structure
```

...and another console code example...

```console
// Create a directory "Code"
$ mkdir code
// Switch into that directory
$ cd code
```

...and a Python code example...

```Python
wont_work()  # This won't work 😱
works(foo="bar")  # This works 🎉
```

...and that's it.

////

//// tab | Info

Code in code blocks should not be modified, with the exception of comments.

See section `### Content of code blocks` in the general prompt in `scripts/translate.py`.

////


docs/en/docs/_llm-test.md::Tabs and colored boxes { #tabs-and-colored-boxes }::L123

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: Tabs and colored boxes { #tabs-and-colored-boxes }
## Tabs and colored boxes { #tabs-and-colored-boxes }

//// tab | Test

/// note
Some text
///

/// note | Technical details
Some text
///

/// tip
Some text
///

/// warning
Some text
///

/// danger
Some text
///

////

//// tab | Info

Tabs and `Info`/`Note`/`Warning`/etc. blocks should have the translation of their title added after a vertical bar (`|`).

See sections `### Special blocks` and `### Tab blocks` in the general prompt in `scripts/translate.py`.

////


docs/en/docs/_llm-test.md::Web- and internal links { #web-and-internal-links }::L157

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: Web- and internal links { #web-and-internal-links }
## Web- and internal links { #web-and-internal-links }

//// tab | Test

The link text should get translated, the link address should remain unchanged:

* [Link to heading above](#code-snippets)
* [Internal link](index.md#installation)
* [External link](https://sqlmodel.tiangolo.com/)
* [Link to a style](https://fastapi.tiangolo.com/css/styles.css)
* [Link to a script](https://fastapi.tiangolo.com/js/logic.js)
* [Link to an image](https://fastapi.tiangolo.com/img/foo.jpg)

The link text should get translated, the link address should point to the translation:

* [FastAPI link](https://fastapi.tiangolo.com/)

////

//// tab | Info

Links should be translated, but their address shall remain unchanged. An exception are absolute links to pages of the FastAPI documentation. In that case it should link to the translation.

See section `### Links` in the general prompt in `scripts/translate.py`.

////


docs/en/docs/_llm-test.md::HTML "abbr" elements { #html-abbr-elements }::L184

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: HTML "abbr" elements { #html-abbr-elements }
## HTML "abbr" elements { #html-abbr-elements }

//// tab | Test

Here are some things wrapped in HTML "abbr" elements (Some are invented):

### The abbr gives a full phrase { #the-abbr-gives-a-full-phrase }

* GTD
* lt
* XWT
* PSGI

### The abbr gives a full phrase and an explanation { #the-abbr-gives-a-full-phrase-and-an-explanation }

* MDN
* I/O.

////

//// tab | Info

"title" attributes of "abbr" elements are translated following some specific instructions.

Translations can add their own "abbr" elements which the LLM should not remove. E.g. to explain English words.

See section `### HTML abbr elements` in the general prompt in `scripts/translate.py`.

////


docs/en/docs/_llm-test.md::HTML "dfn" elements { #html-dfn-elements }::L214

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: HTML "dfn" elements { #html-dfn-elements }
## HTML "dfn" elements { #html-dfn-elements }

* <dfn title="A group of machines that are configured to be connected and work together in some way.">cluster</dfn>
* <dfn title="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</dfn>


docs/en/docs/_llm-test.md::Headings { #headings }::L219

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: Headings { #headings }
## Headings { #headings }

//// tab | Test

### Develop a webapp - a tutorial { #develop-a-webapp-a-tutorial }

Hello.

### Type hints and -annotations { #type-hints-and-annotations }

Hello again.

### Super- and subclasses { #super-and-subclasses }

Hello again.

////

//// tab | Info

The only hard rule for headings is that the LLM leaves the hash part inside curly brackets unchanged, which ensures that links do not break.

See section `### Headings` in the general prompt in `scripts/translate.py`.

For some language specific instructions, see e.g. section `### Headings` in `docs/de/llm-prompt.md`.

////


docs/en/docs/_llm-test.md::Terms used in the docs { #terms-used-in-the-docs }::L247

# Doc: docs/en/docs/_llm-test.md | Page: LLM test file { #llm-test-file } | Section: Terms used in the docs { #terms-used-in-the-docs }
## Terms used in the docs { #terms-used-in-the-docs }

//// tab | Test

* you
* your

* e.g.
* etc.

* `foo` as an `int`
* `bar` as a `str`
* `baz` as a `list`

* the Tutorial - User guide
* the Advanced User Guide
* the SQLModel docs
* the API docs
* the automatic docs

* Data Science
* Deep Learning
* Machine Learning
* Dependency Injection
* HTTP Basic authentication
* HTTP Digest
* ISO format
* the JSON Schema standard
* the JSON schema
* the schema definition
* Password Flow
* Mobile

* deprecated
* designed
* invalid
* on the fly
* standard
* default
* case-sensitive
* case-insensitive

* to serve the application
* to serve the page

* the app
* the application

* the request
* the response
* the error response

* the path operation
* the path operation decorator
* the path operation function

* the body
* the request body
* the response body
* the JSON body
* the form body
* the file body
* the function body

* the parameter
* the body parameter
* the path parameter
* the query parameter
* the cookie parameter
* the header parameter
* the form parameter
* the function parameter

* the event
* the startup event
* the startup of the server
* the shutdown event
* the lifespan event

* the handler
* the event handler
* the exception handler
* to handle

* the model
* the Pydantic model
* the data model
* the database model
* the form model
* the model object

* the class
* the base class
* the parent class
* the subclass
* the child class
* the sibling class
* the class method

* the header
* the headers
* the authorization header
* the `Authorization` header
* the forwarded header

* the dependency injection system
* the dependency
* the dependable
* the dependant

* I/O bound
* CPU bound
* concurrency
* parallelism
* multiprocessing

* the env var
* the environment variable
* the `PATH`
* the `PATH` variable

* the authentication
* the authentication provider
* the authorization
* the authorization form
* the authorization provider
* the user authenticates
* the system authenticates the user

* the CLI
* the command line interface

* the server
* the client

* the cloud provider
* the cloud service

* the development
* the development stages

* the dict
* the dictionary
* the enumeration
* the enum
* the enum member

* the encoder
* the decoder
* to encode
* to decode

* the exception
* to raise

* the expression
* the statement

* the frontend
* the backend

* the GitHub discussion
* the GitHub issue

* the performance
* the performance optimization

* the return type
* the return value

* the security
* the security scheme

* the task
* the background task
* the task function

* the template
* the template engine

* the type annotation
* the type hint

* the server worker
* the Uvicorn worker
* the Gunicorn Worker
* the worker process
* the worker class
* the workload

* the deployment
* to deploy

* the SDK
* the software development kit

* the `APIRouter`
* the `requirements.txt`
* the Bearer Token
* the breaking change
* the bug
* the button
* the callable
* the code
* the commit
* the context manager
* the coroutine
* the database session
* the disk
* the domain
* the engine
* the fake X
* the HTTP GET method
* the item
* the library
* the lifespan
* the lock
* the middleware
* the mobile application
* the module
* the mounting
* the network
* the origin
* the override
* the payload
* the processor
* the property
* the proxy
* the pull request
* the query
* the RAM
* the remote machine
* the status code
* the string
* the tag
* the web framework
* the wildcard
* to return
* to validate

////

//// tab | Info

This is neither a complete nor a normative list of (mostly) technical terms seen in the docs. It may be helpful for the prompt designer to figure out for which terms the LLM needs a helping hand. For example when it keeps reverting a good translation to a suboptimal translation. Or when it has problems conjugating/declinating a term in your language.

See e.g. section `### List of English terms and their preferred German translations` in `docs/de/llm-prompt.md`.

////


docs/en/docs/about/index.md::About { #about }::L1

# Doc: docs/en/docs/about/index.md | Page: About { #about } | Section: About { #about }
# About { #about }

About FastAPI, its design, inspiration and more. 🤓


docs/en/docs/advanced/additional-responses.md::Additional Responses in OpenAPI { #additional-responses-in-openapi }::L1

# Doc: docs/en/docs/advanced/additional-responses.md | Page: Additional Responses in OpenAPI { #additional-responses-in-openapi } | Section: Additional Responses in OpenAPI { #additional-responses-in-openapi }
# Additional Responses in OpenAPI { #additional-responses-in-openapi }

/// warning

This is a rather advanced topic.

If you are starting with **FastAPI**, you might not need this.

///

You can declare additional responses, with additional status codes, media types, descriptions, etc.

Those additional responses will be included in the OpenAPI schema, so they will also appear in the API docs.

But for those additional responses you have to make sure you return a `Response` like `JSONResponse` directly, with your status code and content.


docs/en/docs/advanced/additional-responses.md::Additional Response with `model` { #additional-response-with-model }::L17

# Doc: docs/en/docs/advanced/additional-responses.md | Page: Additional Responses in OpenAPI { #additional-responses-in-openapi } | Section: Additional Response with `model` { #additional-response-with-model }
## Additional Response with `model` { #additional-response-with-model }

You can pass to your *path operation decorators* a parameter `responses`.

It receives a `dict`: the keys are status codes for each response (like `200`), and the values are other `dict`s with the information for each of them.

Each of those response `dict`s can have a key `model`, containing a Pydantic model, just like `response_model`.

**FastAPI** will take that model, generate its JSON Schema and include it in the correct place in OpenAPI.

For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write:

{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}

/// note

Keep in mind that you have to return the `JSONResponse` directly.

///

/// note

The `model` key is not part of OpenAPI.

**FastAPI** will take the Pydantic model from there, generate the JSON Schema, and put it in the correct place.

The correct place is:

* In the key `content`, that has as value another JSON object (`dict`) that contains:
    * A key with the media type, e.g. `application/json`, that contains as value another JSON object, that contains:
        * A key `schema`, that has as the value the JSON Schema from the model, here's the correct place.
            * **FastAPI** adds a reference here to the global JSON Schemas in another place in your OpenAPI instead of including it directly. This way, other applications and clients can use those JSON Schemas directly, provide better code generation tools, etc.

///

The generated responses in the OpenAPI for this *path operation* will be:

```JSON hl_lines="3-12"
{
    "responses": {
        "404": {
            "description": "Additional Response",
            "content": {
                "application/json": {
                    "schema": {
                        "$ref": "#/components/schemas/Message"
                    }
                }
            }
        },
        "200": {
            "description": "Successful Response",
            "content": {
                "application/json": {
                    "schema": {
                        "$ref": "#/components/schemas/Item"
                    }
                }
            }
        },
        "422": {
            "description": "Validation Error",
            "content": {
                "application/json": {
                    "schema": {
                        "$ref": "#/components/schemas/HTTPValidationError"
                    }
                }
            }
        }
    }
}
```

The schemas are referenced to another place inside the OpenAPI schema:

```JSON hl_lines="4-16"
{
    "components": {
        "schemas": {
            "Message": {
                "title": "Message",
                "required": [
                    "message"
                ],
                "type": "object",
                "properties": {
                    "message": {
                        "title": "Message",
                        "type": "string"
                    }
                }
            },
            "Item": {
                "title": "Item",
                "required": [
                    "id",
                    "value"
                ],
                "type": "object",
                "properties": {
                    "id": {
                        "title": "Id",
                        "type": "string"
                    },
                    "value": {
                        "title": "Value",
                        "type": "string"
                    }
                }
            },
            "ValidationError": {
                "title": "ValidationError",
                "required": [
                    "loc",
                    "msg",
                    "type"
                ],
                "type": "object",
                "properties": {
                    "loc": {
                        "title": "Location",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "msg": {
                        "title": "Message",
                        "type": "string"
                    },
                    "type": {
                        "title": "Error Type",
                        "type": "string"
                    }
                }
            },
            "HTTPValidationError": {
                "title": "HTTPValidationError",
                "type": "object",
                "properties": {
                    "detail": {
                        "title": "Detail",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ValidationError"
                        }
                    }
                }
            }
        }
    }
}
```


docs/en/docs/advanced/additional-responses.md::Additional media types for the main response { #additional-media-types-for-the-main-response }::L172

# Doc: docs/en/docs/advanced/additional-responses.md | Page: Additional Responses in OpenAPI { #additional-responses-in-openapi } | Section: Additional media types for the main response { #additional-media-types-for-the-main-response }
## Additional media types for the main response { #additional-media-types-for-the-main-response }

You can use this same `responses` parameter to add different media types for the same main response.

For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:

{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}

/// note

Notice that you have to return the image using a `FileResponse` directly.

///

/// 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`).

But if you have specified a custom response class with `None` as its media type, FastAPI will use `application/json` for any additional response that has an associated model.

///


docs/en/docs/advanced/additional-responses.md::Combining information { #combining-information }::L194

# Doc: docs/en/docs/advanced/additional-responses.md | Page: Additional Responses in OpenAPI { #additional-responses-in-openapi } | Section: Combining information { #combining-information }
## Combining information { #combining-information }

You can also combine response information from multiple places, including the `response_model`, `status_code`, and `responses` parameters.

You can declare a `response_model`, using the default status code `200` (or a custom one if you need), and then declare additional information for that same response in `responses`, directly in the OpenAPI schema.

**FastAPI** will keep the additional information from `responses`, and combine it with the JSON Schema from your model.

For example, you can declare a response with a status code `404` that uses a Pydantic model and has a custom `description`.

And a response with a status code `200` that uses your `response_model`, but includes a custom `example`:

{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}

It will all be combined and included in your OpenAPI, and shown in the API docs:

<img src="/img/tutorial/additional-responses/image01.png">


docs/en/docs/advanced/additional-responses.md::Combine predefined responses and custom ones { #combine-predefined-responses-and-custom-ones }::L212

# Doc: docs/en/docs/advanced/additional-responses.md | Page: Additional Responses in OpenAPI { #additional-responses-in-openapi } | Section: Combine predefined responses and custom ones { #combine-predefined-responses-and-custom-ones }
## Combine predefined responses and custom ones { #combine-predefined-responses-and-custom-ones }

You might want to have some predefined responses that apply to many *path operations*, but you want to combine them with custom responses needed by each *path operation*.

For those cases, you can use the Python technique of "unpacking" a `dict` with `**dict_to_unpack`:

```Python
old_dict = {
    "old key": "old value",
    "second old key": "second old value",
}
new_dict = {**old_dict, "new key": "new value"}
```

Here, `new_dict` will contain all the key-value pairs from `old_dict` plus the new key-value pair:

```Python
{
    "old key": "old value",
    "second old key": "second old value",
    "new key": "new value",
}
```

You can use that technique to reuse some predefined responses in your *path operations* and combine them with additional custom ones.

For example:

{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}


docs/en/docs/advanced/additional-responses.md::More information about OpenAPI responses { #more-information-about-openapi-responses }::L242

# Doc: docs/en/docs/advanced/additional-responses.md | Page: Additional Responses in OpenAPI { #additional-responses-in-openapi } | Section: More information about OpenAPI responses { #more-information-about-openapi-responses }
## More information about OpenAPI responses { #more-information-about-openapi-responses }

To see what exactly you can include in the responses, you can check these sections in the OpenAPI specification:

* [OpenAPI Responses Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object), it includes the `Response Object`.
* [OpenAPI Response Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object), you can include anything from this directly in each response inside your `responses` parameter. Including `description`, `headers`, `content` (inside of this is that you declare different media types and JSON Schemas), and `links`.


docs/en/docs/advanced/additional-status-codes.md::Additional Status Codes { #additional-status-codes }::L1

# Doc: docs/en/docs/advanced/additional-status-codes.md | Page: Additional Status Codes { #additional-status-codes } | Section: Additional Status Codes { #additional-status-codes }
# Additional Status Codes { #additional-status-codes }

By default, **FastAPI** will return the responses using a `JSONResponse`, putting the content you return from your *path operation* inside of that `JSONResponse`.

It will use the default status code or the one you set in your *path operation*.


docs/en/docs/advanced/additional-status-codes.md::Additional status codes { #additional-status-codes_1 }::L7

# Doc: docs/en/docs/advanced/additional-status-codes.md | Page: Additional Status Codes { #additional-status-codes } | Section: Additional status codes { #additional-status-codes_1 }
## Additional status codes { #additional-status-codes_1 }

If you want to return additional status codes apart from the main one, you can do that by returning a `Response` directly, like a `JSONResponse`, and set the additional status code directly.

For example, let's say that you want to have a *path operation* that allows updating items, and returns HTTP status codes of 200 "OK" when successful.

But you also want it to accept new items. And when the items didn't exist before, it creates them, and returns an HTTP status code of 201 "Created".

To achieve that, import `JSONResponse`, and return your content there directly, setting the `status_code` that you want:

{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}

/// warning

When you return a `Response` directly, like in the example above, it will be returned directly.

It won't be serialized with a model, etc.

Make sure it has the data you want it to have, and that the values are valid JSON (if you are using `JSONResponse`).

///

/// note | Technical Details

You could also use `from starlette.responses import JSONResponse`.

**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette. The same with `status`.

///


docs/en/docs/advanced/additional-status-codes.md::OpenAPI and API docs { #openapi-and-api-docs }::L37

# Doc: docs/en/docs/advanced/additional-status-codes.md | Page: Additional Status Codes { #additional-status-codes } | Section: OpenAPI and API docs { #openapi-and-api-docs }
## OpenAPI and API docs { #openapi-and-api-docs }

If you return additional status codes and responses directly, they won't be included in the OpenAPI schema (the API docs), because FastAPI doesn't have a way to know beforehand what you are going to return.

But you can document that in your code, using: [Additional Responses](additional-responses.md).


docs/en/docs/advanced/advanced-dependencies.md::Advanced Dependencies { #advanced-dependencies }::L1

# Doc: docs/en/docs/advanced/advanced-dependencies.md | Page: Advanced Dependencies { #advanced-dependencies } | Section: Advanced Dependencies { #advanced-dependencies }
# Advanced Dependencies { #advanced-dependencies }


docs/en/docs/advanced/advanced-dependencies.md::Parameterized dependencies { #parameterized-dependencies }::L3

# Doc: docs/en/docs/advanced/advanced-dependencies.md | Page: Advanced Dependencies { #advanced-dependencies } | Section: Parameterized dependencies { #parameterized-dependencies }
## Parameterized dependencies { #parameterized-dependencies }

All the dependencies we have seen are a fixed function or class.

But there could be cases where you want to be able to set parameters on the dependency, without having to declare many different functions or classes.

Let's imagine that we want to have a dependency that checks if the query parameter `q` contains some fixed content.

But we want to be able to parameterize that fixed content.


docs/en/docs/advanced/advanced-dependencies.md::A "callable" instance { #a-callable-instance }::L13

# Doc: docs/en/docs/advanced/advanced-dependencies.md | Page: Advanced Dependencies { #advanced-dependencies } | Section: A "callable" instance { #a-callable-instance }
## A "callable" instance { #a-callable-instance }

In Python there's a way to make an instance of a class a "callable".

Not the class itself (which is already a callable), but an instance of that class.

To do that, we declare a method `__call__`:

{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}

In this case, this `__call__` is what **FastAPI** will use to check for additional parameters and sub-dependencies, and this is what will be called to pass a value to the parameter in your *path operation function* later.


docs/en/docs/advanced/advanced-dependencies.md::Parameterize the instance { #parameterize-the-instance }::L25

# Doc: docs/en/docs/advanced/advanced-dependencies.md | Page: Advanced Dependencies { #advanced-dependencies } | Section: Parameterize the instance { #parameterize-the-instance }
## Parameterize the instance { #parameterize-the-instance }

And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:

{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}

In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code.


docs/en/docs/advanced/advanced-dependencies.md::Create an instance { #create-an-instance }::L33

# Doc: docs/en/docs/advanced/advanced-dependencies.md | Page: Advanced Dependencies { #advanced-dependencies } | Section: Create an instance { #create-an-instance }
## Create an instance { #create-an-instance }

We could create an instance of this class with:

{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}

And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`.


docs/en/docs/advanced/advanced-dependencies.md::Use the instance as a dependency { #use-the-instance-as-a-dependency }::L41

# Doc: docs/en/docs/advanced/advanced-dependencies.md | Page: Advanced Dependencies { #advanced-dependencies } | Section: Use the instance as a dependency { #use-the-instance-as-a-dependency }
## Use the instance as a dependency { #use-the-instance-as-a-dependency }

Then, we could use this `checker` in a `Depends(checker)`, instead of `Depends(FixedContentQueryChecker)`, because the dependency is the instance, `checker`, not the class itself.

And when solving the dependency, **FastAPI** will call this `checker` like:

```Python
checker(q="somequery")
```

...and pass whatever that returns as the value of the dependency in our *path operation function* as the parameter `fixed_content_included`:

{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}

/// tip

All this might seem contrived. And it might not be very clear how it is useful yet.

These examples are intentionally simple, but show how it all works.

In the chapters about security, there are utility functions that are implemented in this same way.

If you understood all this, you already know how those utility tools for security work underneath.

///


docs/en/docs/advanced/advanced-dependencies.md::Dependencies with `yield`, `HTTPException`, `except` and Background Tasks { #dependencies-with-yield-httpexception-except-and-background-tasks }::L67

# Doc: docs/en/docs/advanced/advanced-dependencies.md | Page: Advanced Dependencies { #advanced-dependencies } | Section: Dependencies with `yield`, `HTTPException`, `except` and Background Tasks { #dependencies-with-yield-httpexception-except-and-background-tasks }
## Dependencies with `yield`, `HTTPException`, `except` and Background Tasks { #dependencies-with-yield-httpexception-except-and-background-tasks }

/// warning

You most probably don't need these technical details.

These details are useful mainly if you had a FastAPI application older than 0.121.0 and you are facing issues with dependencies with `yield`.

///

Dependencies with `yield` have evolved over time to account for the different use cases and to fix some issues, here's a summary of what has changed.

### Dependencies with `yield` and `scope` { #dependencies-with-yield-and-scope }

In version 0.121.0, FastAPI added support for `Depends(scope="function")` for dependencies with `yield`.

Using `Depends(scope="function")`, the exit code after `yield` is executed right after the *path operation function* is finished, before the response is sent back to the client.

And when using `Depends(scope="request")` (the default), the exit code after `yield` is executed after the response is sent.

You can read more about it in the docs for [Dependencies with `yield` - Early exit and `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope).

### Dependencies with `yield` and `StreamingResponse`, Technical Details { #dependencies-with-yield-and-streamingresponse-technical-details }

Before FastAPI 0.118.0, if you used a dependency with `yield`, it would run the exit code after the *path operation function* returned but right before sending the response.

The intention was to avoid holding resources for longer than necessary, waiting for the response to travel through the network.

This change also meant that if you returned a `StreamingResponse`, the exit code of the dependency with `yield` would have been already run.

For example, if you had a database session in a dependency with `yield`, the `StreamingResponse` would not be able to use that session while streaming data because the session would have already been closed in the exit code after `yield`.

This behavior was reverted in 0.118.0, to make the exit code after `yield` be executed after the response is sent.

/// 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.

///

#### Use Cases with Early Exit Code { #use-cases-with-early-exit-code }

There are some use cases with specific conditions that could benefit from the old behavior of running the exit code of dependencies with `yield` before sending the response.

For example, imagine you have code that uses a database session in a dependency with `yield` only to verify a user, but the database session is never used again in the *path operation function*, only in the dependency, **and** the response takes a long time to be sent, like a `StreamingResponse` that sends data slowly, but for some reason doesn't use the database.

In this case, the database session would be held until the response is finished being sent, but if you don't use it, then it wouldn't be necessary to hold it.

Here's how it could look:

{* ../../docs_src/dependencies/tutorial013_an_py310.py *}

The exit code, the automatic closing of the `Session` in:

{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *}

...would be run after the response finishes sending the slow data:

{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *}

But as `generate_stream()` doesn't use the database session, it is not really necessary to keep the session open while sending the response.

If you have this specific use case using SQLModel (or SQLAlchemy), you could explicitly close the session after you don't need it anymore:

{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *}

That way the session would release the database connection, so other requests could use it.

If you have a different use case that needs to exit early from a dependency with `yield`, please create a [GitHub Discussion Question](https://github.com/fastapi/fastapi/discussions/new?category=questions) with your specific use case and why you would benefit from having early closing for dependencies with `yield`.

If there are compelling use cases for early closing in dependencies with `yield`, I would consider adding a new way to opt in to early closing.

### Dependencies with `yield` and `except`, Technical Details { #dependencies-with-yield-and-except-technical-details }

Before FastAPI 0.110.0, if you used a dependency with `yield`, and then you captured an exception with `except` in that dependency, and you didn't raise the exception again, the exception would be automatically raised/forwarded to any exception handlers or the internal server error handler.

This was changed in version 0.110.0 to fix unhandled memory consumption from forwarded exceptions without a handler (internal server errors), and to make it consistent with the behavior of regular Python code.

### Background Tasks and Dependencies with `yield`, Technical Details { #background-tasks-and-dependencies-with-yield-technical-details }

Before FastAPI 0.106.0, raising exceptions after `yield` was not possible, the exit code in dependencies with `yield` was executed *after* the response was sent, so [Exception Handlers](../tutorial/handling-errors.md#install-custom-exception-handlers) would have already run.

This was designed this way mainly to allow using the same objects "yielded" by dependencies inside of background tasks, because the exit code would be executed after the background tasks were finished.

This was changed in FastAPI 0.106.0 with the intention to not hold resources while waiting for the response to travel through the network.

/// tip

Additionally, a background task is normally an independent set of logic that should be handled separately, with its own resources (e.g. its own database connection).

So, this way you will probably have cleaner code.

///

If you used to rely on this behavior, now you should create the resources for background tasks inside the background task itself, and use internally only data that doesn't depend on the resources of dependencies with `yield`.

For example, instead of using the same database session, you would create a new database session inside of the background task, and you would obtain the objects from the database using this new session. And then instead of passing the object from the database as a parameter to the background task function, you would pass the ID of that object and then obtain the object again inside the background task function.


docs/en/docs/advanced/advanced-python-types.md::Advanced Python Types { #advanced-python-types }::L1

# Doc: docs/en/docs/advanced/advanced-python-types.md | Page: Advanced Python Types { #advanced-python-types } | Section: Advanced Python Types { #advanced-python-types }
# Advanced Python Types { #advanced-python-types }

Here are some additional ideas that might be useful when working with Python types.


docs/en/docs/advanced/advanced-python-types.md::Using `Union` or `Optional` { #using-union-or-optional }::L5

# Doc: docs/en/docs/advanced/advanced-python-types.md | Page: Advanced Python Types { #advanced-python-types } | Section: Using `Union` or `Optional` { #using-union-or-optional }
## Using `Union` or `Optional` { #using-union-or-optional }

If your code for some reason can't use `|`, for example if it's not in a type annotation but in something like `response_model=`, instead of using the vertical bar (`|`) you can use `Union` from `typing`.

For example, you could declare that something could be a `str` or `None`:

```python
from typing import Union

def say_hi(name: Union[str, None]):
        print(f"Hi {name}!")
```

`typing` also has a shortcut to declare that something could be `None`, with `Optional`.

Here's a tip from my very **subjective** point of view:

* 🚨 Avoid using `Optional[SomeType]`
* Instead ✨ **use `Union[SomeType, None]`** ✨.

Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.

I think `Union[SomeType, None]` is more explicit about what it means.

It's just about the words and names. But those words can affect how you and your teammates think about the code.

As an example, let's take this function:

```python
from typing import Optional

def say_hi(name: Optional[str]):
    print(f"Hey {name}!")
```

The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter:

```Python
say_hi()  # Oh, no, this throws an error! 😱
```

The `name` parameter is **still required** (not *optional*) because it doesn't have a default value. Still, `name` accepts `None` as the value:

```Python
say_hi(name=None)  # This works, None is valid 🎉
```

The good news is, in most cases, you will be able to simply use `|` to define unions of types:

```python
def say_hi(name: str | None):
    print(f"Hey {name}!")
```

So, normally you don't have to worry about names like `Optional` and `Union`. 😎


docs/en/docs/advanced/async-tests.md::Async Tests { #async-tests }::L1

# Doc: docs/en/docs/advanced/async-tests.md | Page: Async Tests { #async-tests } | Section: Async Tests { #async-tests }
# Async Tests { #async-tests }

You have already seen how to test your **FastAPI** applications using the provided `TestClient`. Up to now, you have only seen how to write synchronous tests, without using `async` functions.

Being able to use asynchronous functions in your tests could be useful, for example, when you're querying your database asynchronously. Imagine you want to test sending requests to your FastAPI application and then verify that your backend successfully wrote the correct data in the database, while using an async database library.

Let's look at how we can make that work.


docs/en/docs/advanced/async-tests.md::pytest.mark.anyio { #pytest-mark-anyio }::L9

# Doc: docs/en/docs/advanced/async-tests.md | Page: Async Tests { #async-tests } | Section: pytest.mark.anyio { #pytest-mark-anyio }
## pytest.mark.anyio { #pytest-mark-anyio }

If we want to call asynchronous functions in our tests, our test functions have to be asynchronous. AnyIO provides a neat plugin for this, that allows us to specify that some test functions are to be called asynchronously.


docs/en/docs/advanced/async-tests.md::HTTPX { #httpx }::L13

# Doc: docs/en/docs/advanced/async-tests.md | Page: Async Tests { #async-tests } | Section: HTTPX { #httpx }
## HTTPX { #httpx }

Even if your **FastAPI** application uses normal `def` functions instead of `async def`, it is still an `async` application underneath.

The `TestClient` does some magic inside to call the asynchronous FastAPI application in your normal `def` test functions, using standard pytest. But that magic doesn't work anymore when we're using it inside asynchronous functions. By running our tests asynchronously, we can no longer use the `TestClient` inside our test functions.

The `TestClient` is based on [HTTPX](https://www.python-httpx.org), and luckily, we can use it directly to test the API.


docs/en/docs/advanced/async-tests.md::Example { #example }::L21

# Doc: docs/en/docs/advanced/async-tests.md | Page: Async Tests { #async-tests } | Section: Example { #example }
## Example { #example }

For a simple example, let's consider a file structure similar to the one described in [Bigger Applications](../tutorial/bigger-applications.md) and [Testing](../tutorial/testing.md):

```
.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py
```

The file `main.py` would have:

{* ../../docs_src/async_tests/app_a_py310/main.py *}

The file `test_main.py` would have the tests for `main.py`, it could look like this now:

{* ../../docs_src/async_tests/app_a_py310/test_main.py *}


docs/en/docs/advanced/async-tests.md::Run it { #run-it }::L41

# Doc: docs/en/docs/advanced/async-tests.md | Page: Async Tests { #async-tests } | Section: Run it { #run-it }
## Run it { #run-it }

You can run your tests as usual via:

<div class="termy">

```console
$ pytest

---> 100%
```

</div>


docs/en/docs/advanced/async-tests.md::In Detail { #in-detail }::L55

# Doc: docs/en/docs/advanced/async-tests.md | Page: Async Tests { #async-tests } | Section: In Detail { #in-detail }
## In Detail { #in-detail }

The marker `@pytest.mark.anyio` tells pytest that this test function should be called asynchronously:

{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}

/// tip

Note that the test function is now `async def` instead of just `def` as before when using the `TestClient`.

///

Then we can create an `AsyncClient` with the app, and send async requests to it, using `await`.

{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}

This is the equivalent to:

```Python
response = client.get('/')
```

...that we used to make our requests with the `TestClient`.

/// tip

Note that we're using async/await with the new `AsyncClient` - the request is asynchronous.

///

/// warning

If your application relies on lifespan events, the `AsyncClient` won't trigger these events. To ensure they are triggered, use `LifespanManager` from [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage).

///


docs/en/docs/advanced/async-tests.md::Other Asynchronous Function Calls { #other-asynchronous-function-calls }::L91

# Doc: docs/en/docs/advanced/async-tests.md | Page: Async Tests { #async-tests } | Section: Other Asynchronous Function Calls { #other-asynchronous-function-calls }
## Other Asynchronous Function Calls { #other-asynchronous-function-calls }

As the testing function is now asynchronous, you can now also call (and `await`) other `async` functions apart from sending requests to your FastAPI application in your tests, exactly as you would call them anywhere else in your code.

/// tip

If you encounter a `RuntimeError: Task attached to a different loop` when integrating asynchronous function calls in your tests (e.g. when using [MongoDB's MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)), remember to instantiate objects that need an event loop only within async functions, e.g. an `@app.on_event("startup")` callback.

///


docs/en/docs/advanced/behind-a-proxy.md::Behind a Proxy { #behind-a-proxy }::L1

# Doc: docs/en/docs/advanced/behind-a-proxy.md | Page: Behind a Proxy { #behind-a-proxy } | Section: Behind a Proxy { #behind-a-proxy }
# Behind a Proxy { #behind-a-proxy }

In many situations, you would use a **proxy** like Traefik or Nginx in front of your FastAPI app.

These proxies could handle HTTPS certificates and other things.


docs/en/docs/advanced/behind-a-proxy.md::Proxy Forwarded Headers { #proxy-forwarded-headers }::L7

# Doc: docs/en/docs/advanced/behind-a-proxy.md | Page: Behind a Proxy { #behind-a-proxy } | Section: Proxy Forwarded Headers { #proxy-forwarded-headers }
## Proxy Forwarded Headers { #proxy-forwarded-headers }

A **proxy** in front of your application would normally set some headers on the fly before sending the requests to your **server** to let the server know that the request was **forwarded** by the proxy, letting it know the original (public) URL, including the domain, that it is using HTTPS, etc.

The **server** program (for example **Uvicorn** via **FastAPI CLI**) is capable of interpreting these headers, and then passing that information to your application.

But for security, as the server doesn't know it is behind a trusted proxy, it won't interpret those headers.

/// note | Technical Details

The proxy headers are:

* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)

///

### Enable Proxy Forwarded Headers { #enable-proxy-forwarded-headers }

You can start FastAPI CLI with the *CLI Option* `--forwarded-allow-ips` and pass the IP addresses that should be trusted to read those forwarded headers.

If you set it to `--forwarded-allow-ips="*"` it would trust all the incoming IPs.

If your **server** is behind a trusted **proxy** and only the proxy talks to it, this would make it accept whatever is the IP of that **proxy**.

<div class="termy">

```console
$ fastapi run --forwarded-allow-ips="*"

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```

</div>

### Redirects with HTTPS { #redirects-with-https }

For example, let's say you define a *path operation* `/items/`:

{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}

If the client tries to go to `/items`, by default, it would be redirected to `/items/`.

But before setting the *CLI Option* `--forwarded-allow-ips` it could redirect to `http://localhost:8000/items/`.

But maybe your application is hosted at `https://mysuperapp.com`, and the redirection should be to `https://mysuperapp.com/items/`.

By setting `--proxy-headers` now FastAPI would be able to redirect to the right location. 😎

```
https://mysuperapp.com/items/
```

/// tip

If you want to learn more about HTTPS, check the guide [About HTTPS](../deployment/https.md).

///

### How Proxy Forwarded Headers Work { #how-proxy-forwarded-headers-work }

Here's a visual representation of how the **proxy** adds forwarded headers between the client and the **application server**:

```mermaid
sequenceDiagram
    participant Client
    participant Proxy as Proxy/Load Balancer
    participant Server as FastAPI Server

    Client->>Proxy: HTTPS Request<br/>Host: mysuperapp.com<br/>Path: /items

    Note over Proxy: Proxy adds forwarded headers

    Proxy->>Server: HTTP Request<br/>X-Forwarded-For: [client IP]<br/>X-Forwarded-Proto: https<br/>X-Forwarded-Host: mysuperapp.com<br/>Path: /items

    Note over Server: Server interprets headers<br/>(if --forwarded-allow-ips is set)

    Server->>Proxy: HTTP Response<br/>with correct HTTPS URLs

    Proxy->>Client: HTTPS Response
```

The **proxy** intercepts the original client request and adds the special *forwarded* headers (`X-Forwarded-*`) before passing the request to the **application server**.

These headers preserve information about the original request that would otherwise be lost:

* **X-Forwarded-For**: The original client's IP address
* **X-Forwarded-Proto**: The original protocol (`https`)
* **X-Forwarded-Host**: The original host (`mysuperapp.com`)

When **FastAPI CLI** is configured with `--forwarded-allow-ips`, it trusts these headers and uses them, for example to generate the correct URLs in redirects.


docs/en/docs/advanced/behind-a-proxy.md::Proxy with a stripped path prefix { #proxy-with-a-stripped-path-prefix }::L100

# Doc: docs/en/docs/advanced/behind-a-proxy.md | Page: Behind a Proxy { #behind-a-proxy } | Section: Proxy with a stripped path prefix { #proxy-with-a-stripped-path-prefix }
## Proxy with a stripped path prefix { #proxy-with-a-stripped-path-prefix }

You could have a proxy that adds a path prefix to your application.

In these cases you can use `root_path` to configure your application.

The `root_path` is a mechanism provided by the ASGI specification (that FastAPI is built on, through Starlette).

The `root_path` is used to handle these specific cases.

And it's also used internally when mounting sub-applications.

Having a proxy with a stripped path prefix, in this case, means that you could declare a path at `/app` in your code, but then, you add a layer on top (the proxy) that would put your **FastAPI** application under a path like `/api/v1`.

In this case, the original path `/app` would actually be served at `/api/v1/app`.

Even though all your code is written assuming there's just `/app`.

{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}

And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to the app server (probably Uvicorn via FastAPI CLI), keeping your application convinced that it is being served at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`.

Up to here, everything would work as normally.

But then, when you open the integrated docs UI (the frontend), it would expect to get the OpenAPI schema at `/openapi.json`, instead of `/api/v1/openapi.json`.

So, the frontend (that runs in the browser) would try to reach `/openapi.json` and wouldn't be able to get the OpenAPI schema.

Because we have a proxy with a path prefix of `/api/v1` for our app, the frontend needs to fetch the OpenAPI schema at `/api/v1/openapi.json`.

```mermaid
graph LR

browser("Browser")
proxy["Proxy on http://0.0.0.0:9999/api/v1/app"]
server["Server on http://127.0.0.1:8000/app"]

browser --> proxy
proxy --> server
```

/// tip

The IP `0.0.0.0` is commonly used to mean that the program listens on all the IPs available in that machine/server.

///

The docs UI would also need the OpenAPI schema to declare that this API `server` is located at `/api/v1` (behind the proxy). For example:

```JSON hl_lines="4-8"
{
    "openapi": "3.1.0",
    // More stuff here
    "servers": [
        {
            "url": "/api/v1"
        }
    ],
    "paths": {
            // More stuff here
    }
}
```

In this example, the "Proxy" could be something like **Traefik**. And the server would be something like FastAPI CLI with **Uvicorn**, running your FastAPI application.

### Providing the `root_path` { #providing-the-root-path }

To achieve this, you can use the command line option `--root-path` like:

```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```

If you use Hypercorn, it also has the option `--root-path`.

/// note | Technical Details

The ASGI specification defines a `root_path` for this use case.

And the `--root-path` command line option provides that `root_path`.

///

### Checking the current `root_path` { #checking-the-current-root-path }

You can get the current `root_path` used by your application for each request, it is part of the `scope` dictionary (that's part of the ASGI spec).

Here we are including it in the message just for demonstration purposes.

{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}

Then, if you start Uvicorn with:

```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```

The response would be something like:

```JSON
{
    "message": "Hello World",
    "root_path": "/api/v1"
}
```

### Setting the `root_path` in the FastAPI app { #setting-the-root-path-in-the-fastapi-app }

Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app:

{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}

Passing the `root_path` to `FastAPI` would be the equivalent of passing the `--root-path` command line option to Uvicorn or Hypercorn.

### About `root_path` { #about-root-path }

Keep in mind that the server (Uvicorn) won't use that `root_path` for anything else than passing it to the app.

But if you go with your browser to [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app) you will see the normal response:

```JSON
{
    "message": "Hello World",
    "root_path": "/api/v1"
}
```

So, it won't expect to be accessed at `http://127.0.0.1:8000/api/v1/app`.

Uvicorn will expect the proxy to access Uvicorn at `http://127.0.0.1:8000/app`, and then it would be the proxy's responsibility to add the extra `/api/v1` prefix on top.


docs/en/docs/advanced/behind-a-proxy.md::About proxies with a stripped path prefix { #about-proxies-with-a-stripped-path-prefix }::L244

# Doc: docs/en/docs/advanced/behind-a-proxy.md | Page: Behind a Proxy { #behind-a-proxy } | Section: About proxies with a stripped path prefix { #about-proxies-with-a-stripped-path-prefix }
## About proxies with a stripped path prefix { #about-proxies-with-a-stripped-path-prefix }

Keep in mind that a proxy with stripped path prefix is only one of the ways to configure it.

Probably in many cases the default will be that the proxy doesn't have a stripped path prefix.

In a case like that (without a stripped path prefix), the proxy would listen on something like `https://myawesomeapp.com`, and then if the browser goes to `https://myawesomeapp.com/api/v1/app` and your server (e.g. Uvicorn) listens on `http://127.0.0.1:8000` the proxy (without a stripped path prefix) would access Uvicorn at the same path: `http://127.0.0.1:8000/api/v1/app`.


docs/en/docs/advanced/behind-a-proxy.md::Testing locally with Traefik { #testing-locally-with-traefik }::L252

# Doc: docs/en/docs/advanced/behind-a-proxy.md | Page: Behind a Proxy { #behind-a-proxy } | Section: Testing locally with Traefik { #testing-locally-with-traefik }
## Testing locally with Traefik { #testing-locally-with-traefik }

You can easily run the experiment locally with a stripped path prefix using [Traefik](https://docs.traefik.io/).

[Download Traefik](https://github.com/containous/traefik/releases), it's a single binary, you can extract the compressed file and run it directly from the terminal.

Then create a file `traefik.toml` with:

```TOML hl_lines="3"
[entryPoints]
  [entryPoints.http]
    address = ":9999"

[providers]
  [providers.file]
    filename = "routes.toml"
```

This tells Traefik to listen on port 9999 and to use another file `routes.toml`.

/// tip

We are using port 9999 instead of the standard HTTP port 80 so that you don't have to run it with admin (`sudo`) privileges.

///

Now create that other file `routes.toml`:

```TOML hl_lines="5  12  20"
[http]
  [http.middlewares]

    [http.middlewares.api-stripprefix.stripPrefix]
      prefixes = ["/api/v1"]

  [http.routers]

    [http.routers.app-http]
      entryPoints = ["http"]
      service = "app"
      rule = "PathPrefix(`/api/v1`)"
      middlewares = ["api-stripprefix"]

  [http.services]

    [http.services.app]
      [http.services.app.loadBalancer]
        [[http.services.app.loadBalancer.servers]]
          url = "http://127.0.0.1:8000"
```

This file configures Traefik to use the path prefix `/api/v1`.

And then Traefik will redirect its requests to your Uvicorn running on `http://127.0.0.1:8000`.

Now start Traefik:

```console
$ ./traefik --configFile=traefik.toml

INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
```

And now start your app, using the `--root-path` option:

```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```

### Check the responses { #check-the-responses }

Now, if you go to the URL with the port for Uvicorn: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), you will see the normal response:

```JSON
{
    "message": "Hello World",
    "root_path": "/api/v1"
}
```

/// tip

Notice that even though you are accessing it at `http://127.0.0.1:8000/app` it shows the `root_path` of `/api/v1`, taken from the option `--root-path`.

///

And now open the URL with the port for Traefik, including the path prefix: [http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app).

We get the same response:

```JSON
{
    "message": "Hello World",
    "root_path": "/api/v1"
}
```

but this time at the URL with the prefix path provided by the proxy: `/api/v1`.

Of course, the idea here is that everyone would access the app through the proxy, so the version with the path prefix `/api/v1` is the "correct" one.

And the version without the path prefix (`http://127.0.0.1:8000/app`), provided by Uvicorn directly, would be exclusively for the _proxy_ (Traefik) to access it.

That demonstrates how the Proxy (Traefik) uses the path prefix and how the server (Uvicorn) uses the `root_path` from the option `--root-path`.

### Check the docs UI { #check-the-docs-ui }

But here's the fun part. ✨

The "official" way to access the app would be through the proxy with the path prefix that we defined. So, as we would expect, if you try the docs UI served by Uvicorn directly, without the path prefix in the URL, it won't work, because it expects to be accessed through the proxy.

You can check it at [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs):

But if we access the docs UI at the "official" URL using the proxy with port `9999`, at `/api/v1/docs`, it works correctly! 🎉

You can check it at [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs):

Right as we wanted it. ✔

This is because FastAPI uses this `root_path` to create the default `server` in OpenAPI with the URL provided by `root_path`.


docs/en/docs/advanced/behind-a-proxy.md::Additional servers { #additional-servers }::L387

# Doc: docs/en/docs/advanced/behind-a-proxy.md | Page: Behind a Proxy { #behind-a-proxy } | Section: Additional servers { #additional-servers }
## Additional servers { #additional-servers }

/// warning

This is a more advanced use case. Feel free to skip it.

///

By default, **FastAPI** will create a `server` in the OpenAPI schema with the URL for the `root_path`.

But you can also provide other alternative `servers`, for example if you want *the same* docs UI to interact with both a staging and a production environment.

If you pass a custom list of `servers` and there's a `root_path` (because your API lives behind a proxy), **FastAPI** will insert a "server" with this `root_path` at the beginning of the list.

For example:

{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}

Will generate an OpenAPI schema like:

```JSON hl_lines="5-7"
{
    "openapi": "3.1.0",
    // More stuff here
    "servers": [
        {
            "url": "/api/v1"
        },
        {
            "url": "https://stag.example.com",
            "description": "Staging environment"
        },
        {
            "url": "https://prod.example.com",
            "description": "Production environment"
        }
    ],
    "paths": {
            // More stuff here
    }
}
```

/// tip

Notice the auto-generated server with a `url` value of `/api/v1`, taken from the `root_path`.

///

In the docs UI at [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) it would look like:

<img src="/img/tutorial/behind-a-proxy/image03.png">

/// tip

The docs UI will interact with the server that you select.

///

/// note | Technical Details

The `servers` property in the OpenAPI specification is optional.

If you don't specify the `servers` parameter and `root_path` is equal to `/`, the `servers` property in the generated OpenAPI schema will be omitted entirely by default, which is the equivalent of a single server with a `url` value of `/`.

///

### Disable automatic server from `root_path` { #disable-automatic-server-from-root-path }

If you don't want **FastAPI** to include an automatic server using the `root_path`, you can use the parameter `root_path_in_servers=False`:

{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}

and then it won't include it in the OpenAPI schema.


docs/en/docs/advanced/behind-a-proxy.md::Mounting a sub-application { #mounting-a-sub-application }::L462

# Doc: docs/en/docs/advanced/behind-a-proxy.md | Page: Behind a Proxy { #behind-a-proxy } | Section: Mounting a sub-application { #mounting-a-sub-application }
## Mounting a sub-application { #mounting-a-sub-application }

If you need to mount a sub-application (as described in [Sub Applications - Mounts](sub-applications.md)) while also using a proxy with `root_path`, you can do it normally, as you would expect.

FastAPI will internally use the `root_path` smartly, so it will just work. ✨


docs/en/docs/advanced/custom-response.md::Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others }::L1

# Doc: docs/en/docs/advanced/custom-response.md | Page: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } | Section: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others }
# Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others }

By default, **FastAPI** will return JSON responses.

You can override it by returning a `Response` directly as seen in [Return a Response directly](response-directly.md).

But if you return a `Response` directly (or any subclass, like `JSONResponse`), the data won't be automatically converted (even if you declare a `response_model`), and the documentation won't be automatically generated (for example, including the specific "media type", in the HTTP header `Content-Type` as part of the generated OpenAPI).

But you can also declare the `Response` that you want to be used (e.g. any `Response` subclass), in the *path operation decorator* using the `response_class` parameter.

The contents that you return from your *path operation function* will be put inside of that `Response`.

/// note

If you use a response class with no media type, FastAPI will expect your response to have no content, so it will not document the response format in its generated OpenAPI docs.

///


docs/en/docs/advanced/custom-response.md::JSON Responses { #json-responses }::L19

# Doc: docs/en/docs/advanced/custom-response.md | Page: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } | Section: JSON Responses { #json-responses }
## JSON Responses { #json-responses }

By default FastAPI returns JSON responses.

If you declare a [Response Model](../tutorial/response-model.md) FastAPI will use it to serialize the data to JSON, using Pydantic.

If you don't declare a response model, FastAPI will use the `jsonable_encoder` explained in [JSON Compatible Encoder](../tutorial/encoder.md) and put it in a `JSONResponse`.

If you declare a `response_class` with a JSON media type (`application/json`), like is the case with the `JSONResponse`, the data you return will be automatically converted (and filtered) with any Pydantic `response_model` that you declared in the *path operation decorator*. But the data won't be serialized to JSON bytes with Pydantic, instead it will be converted with the `jsonable_encoder` and then passed to the `JSONResponse` class, which will serialize it to bytes using the standard JSON library in Python.

### JSON Performance { #json-performance }

In short, if you want the maximum performance, use a [Response Model](../tutorial/response-model.md) and don't declare a `response_class` in the *path operation decorator*.

{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}


docs/en/docs/advanced/custom-response.md::HTML Response { #html-response }::L35

# Doc: docs/en/docs/advanced/custom-response.md | Page: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } | Section: HTML Response { #html-response }
## HTML Response { #html-response }

To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.

* Import `HTMLResponse`.
* Pass `HTMLResponse` as the parameter `response_class` of your *path operation decorator*.

{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}

/// note

The parameter `response_class` will also be used to define the "media type" of the response.

In this case, the HTTP header `Content-Type` will be set to `text/html`.

And it will be documented as such in OpenAPI.

///

### Return a `Response` { #return-a-response }

As seen in [Return a Response directly](response-directly.md), you can also override the response directly in your *path operation*, by returning it.

The same example from above, returning an `HTMLResponse`, could look like:

{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}

/// warning

A `Response` returned directly by your *path operation function* won't be documented in OpenAPI (for example, the `Content-Type` won't be documented) and won't be visible in the automatic interactive docs.

///

/// note

Of course, the actual `Content-Type` header, status code, etc, will come from the `Response` object you returned.

///

### Document in OpenAPI and override `Response` { #document-in-openapi-and-override-response }

If you want to override the response from inside of the function but at the same time document the "media type" in OpenAPI, you can use the `response_class` parameter AND return a `Response` object.

The `response_class` will then be used only to document the OpenAPI *path operation*, but your `Response` will be used as is.

#### Return an `HTMLResponse` directly { #return-an-htmlresponse-directly }

For example, it could be something like:

{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}

In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.

By returning the result of calling `generate_html_response()`, you are already returning a `Response` that will override the default **FastAPI** behavior.

But as you passed the `HTMLResponse` in the `response_class` too, **FastAPI** will know how to document it in OpenAPI and the interactive docs as HTML with `text/html`:

<img src="/img/tutorial/custom-response/image01.png">


docs/en/docs/advanced/custom-response.md::Available responses { #available-responses }::L94

# Doc: docs/en/docs/advanced/custom-response.md | Page: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } | Section: Available responses { #available-responses }
## Available responses { #available-responses }

Here are some of the available responses.

Keep in mind that you can use `Response` to return anything else, or even create a custom sub-class.

/// note | Technical Details

You could also use `from starlette.responses import HTMLResponse`.

**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette.

///

### `Response` { #response }

The main `Response` class, all the other responses inherit from it.

You can return it directly.

It accepts the following parameters:

* `content` - A `str` or `bytes`.
* `status_code` - An `int` HTTP status code.
* `headers` - A `dict` of strings.
* `media_type` - A `str` giving the media type. E.g. `"text/html"`.

FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the `media_type` and appending a charset for text types.

{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}

### `HTMLResponse` { #htmlresponse }

Takes some text or bytes and returns an HTML response, as you read above.

### `PlainTextResponse` { #plaintextresponse }

Takes some text or bytes and returns a plain text response.

{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}

### `JSONResponse` { #jsonresponse }

Takes some data and returns an `application/json` encoded response.

This is the default response used in **FastAPI**, as you read above.

/// note | Technical Details

But if you declare a response model or return type, that will be used directly to serialize the data to JSON, and a response with the right media type for JSON will be returned directly, without using the `JSONResponse` class.

This is the ideal way to get the best performance.

///

### `RedirectResponse` { #redirectresponse }

Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default.

You can return a `RedirectResponse` directly:

{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}

---

Or you can use it in the `response_class` parameter:

{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}

If you do that, then you can return the URL directly from your *path operation* function.

In this case, the `status_code` used will be the default one for the `RedirectResponse`, which is `307`.

---

You can also use the `status_code` parameter combined with the `response_class` parameter:

{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}

### `StreamingResponse` { #streamingresponse }

Takes an async generator or a normal generator/iterator (a function with `yield`) and streams the response body.

{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}

/// note | Technical Details

An `async` task can only be cancelled when it reaches an `await`. If there is no `await`, the generator (function with `yield`) can not be cancelled properly and may keep running even after cancellation is requested.

Since this small example does not need any `await` statements, we add an `await anyio.sleep(0)` to give the event loop a chance to handle cancellation.

This would be even more important with large or infinite streams.

///

/// tip

Instead of returning a `StreamingResponse` directly, you should probably follow the style in [Stream Data](./stream-data.md), it's much more convenient and handles cancellation behind the scenes for you.

If you are streaming JSON Lines, follow the [Stream JSON Lines](../tutorial/stream-json-lines.md) tutorial.

///

### `FileResponse` { #fileresponse }

Asynchronously streams a file as the response.

Takes a different set of arguments to instantiate than the other response types:

* `path` - The file path to the file to stream.
* `headers` - Any custom headers to include, as a dictionary.
* `media_type` - A string giving the media type. If unset, the filename or path will be used to infer a media type.
* `filename` - If set, this will be included in the response `Content-Disposition`.

File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.

{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}

You can also use the `response_class` parameter:

{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}

In this case, you can return the file path directly from your *path operation* function.


docs/en/docs/advanced/custom-response.md::Custom response class { #custom-response-class }::L219

# Doc: docs/en/docs/advanced/custom-response.md | Page: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } | Section: Custom response class { #custom-response-class }
## Custom response class { #custom-response-class }

You can create your own custom response class, inheriting from `Response` and using it.

For example, let's say that you want to use [`orjson`](https://github.com/ijl/orjson) with some settings.

Let's say you want it to return indented and formatted JSON, so you want to use the orjson option `orjson.OPT_INDENT_2`.

You could create a `CustomORJSONResponse`. The main thing you have to do is create a `Response.render(content)` method that returns the content as `bytes`:

{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}

Now instead of returning:

```json
{"message": "Hello World"}
```

...this response will return:

```json
{
  "message": "Hello World"
}
```

Of course, you will probably find much better ways to take advantage of this than formatting JSON. 😉

### `orjson` or Response Model { #orjson-or-response-model }

If what you are looking for is performance, you are probably better off using a [Response Model](../tutorial/response-model.md) than an `orjson` response.

With a response model, FastAPI will use Pydantic to serialize the data to JSON, without using intermediate steps, like converting it with `jsonable_encoder`, which would happen in any other case.

And under the hood, Pydantic uses the same underlying Rust mechanisms as `orjson` to serialize to JSON, so you will already get the best performance with a response model.


docs/en/docs/advanced/custom-response.md::Default response class { #default-response-class }::L255

# Doc: docs/en/docs/advanced/custom-response.md | Page: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } | Section: Default response class { #default-response-class }
## Default response class { #default-response-class }

When creating a **FastAPI** class instance or an `APIRouter` you can specify which response class to use by default.

The parameter that defines this is `default_response_class`.

In the example below, **FastAPI** will use `HTMLResponse` by default, in all *path operations*, instead of JSON.

{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}

/// tip

You can still override `response_class` in *path operations* as before.

///


docs/en/docs/advanced/custom-response.md::Additional documentation { #additional-documentation }::L271

# Doc: docs/en/docs/advanced/custom-response.md | Page: Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others } | Section: Additional documentation { #additional-documentation }
## Additional documentation { #additional-documentation }

You can also declare the media type and many other details in OpenAPI using `responses`: [Additional Responses in OpenAPI](additional-responses.md).


docs/en/docs/advanced/dataclasses.md::Using Dataclasses { #using-dataclasses }::L1

# Doc: docs/en/docs/advanced/dataclasses.md | Page: Using Dataclasses { #using-dataclasses } | Section: Using Dataclasses { #using-dataclasses }
# Using Dataclasses { #using-dataclasses }

FastAPI is built on top of **Pydantic**, and I have been showing you how to use Pydantic models to declare requests and responses.

But FastAPI also supports using [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) the same way:

{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}

This is still supported thanks to **Pydantic**, as it has [internal support for `dataclasses`](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel).

So, even with the code above that doesn't use Pydantic explicitly, FastAPI is using Pydantic to convert those standard dataclasses to Pydantic's own flavor of dataclasses.

And of course, it supports the same:

* data validation
* data serialization
* data documentation, etc.

This works the same way as with Pydantic models. And it is actually achieved in the same way underneath, using Pydantic.

/// note

Keep in mind that dataclasses can't do everything Pydantic models can do.

So, you might still need to use Pydantic models.

But if you have a bunch of dataclasses lying around, this is a nice trick to use them to power a web API using FastAPI. 🤓

///


docs/en/docs/advanced/dataclasses.md::Dataclasses in `response_model` { #dataclasses-in-response-model }::L31

# Doc: docs/en/docs/advanced/dataclasses.md | Page: Using Dataclasses { #using-dataclasses } | Section: Dataclasses in `response_model` { #dataclasses-in-response-model }
## Dataclasses in `response_model` { #dataclasses-in-response-model }

You can also use `dataclasses` in the `response_model` parameter:

{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}

The dataclass will be automatically converted to a Pydantic dataclass.

This way, its schema will show up in the API docs user interface:

<img src="/img/tutorial/dataclasses/image01.png">