docs/en/docs/advanced/dataclasses.md::Dataclasses in Nested Data Structures { #dataclasses-in-nested-data-structures }::L43

# Doc: docs/en/docs/advanced/dataclasses.md | Page: Using Dataclasses { #using-dataclasses } | Section: Dataclasses in Nested Data Structures { #dataclasses-in-nested-data-structures }
## Dataclasses in Nested Data Structures { #dataclasses-in-nested-data-structures }

You can also combine `dataclasses` with other type annotations to make nested data structures.

In some cases, you might still have to use Pydantic's version of `dataclasses`. For example, if you have errors with the automatically generated API documentation.

In that case, you can simply swap the standard `dataclasses` with `pydantic.dataclasses`, which is a drop-in replacement:

{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}

1. We still import `field` from standard `dataclasses`.

2. `pydantic.dataclasses` is a drop-in replacement for `dataclasses`.

3. The `Author` dataclass includes a list of `Item` dataclasses.

4. The `Author` dataclass is used as the `response_model` parameter.

5. You can use other standard type annotations with dataclasses as the request body.

    In this case, it's a list of `Item` dataclasses.

6. Here we are returning a dictionary that contains `items` which is a list of dataclasses.

    FastAPI is still capable of <dfn title="converting the data to a format that can be transmitted">serializing</dfn> the data to JSON.

7. Here the `response_model` is using a type annotation of a list of `Author` dataclasses.

    Again, you can combine `dataclasses` with standard type annotations.

8. Notice that this *path operation function* uses regular `def` instead of `async def`.

    As always, in FastAPI you can combine `def` and `async def` as needed.

    If you need a refresher about when to use which, check out the section _"In a hurry?"_ in the docs about [`async` and `await`](../async.md#in-a-hurry).

9. This *path operation function* is not returning dataclasses (although it could), but a list of dictionaries with internal data.

    FastAPI will use the `response_model` parameter (that includes dataclasses) to convert the response.

You can combine `dataclasses` with other type annotations in many different combinations to form complex data structures.

Check the in-code annotation tips above to see more specific details.


docs/en/docs/advanced/dataclasses.md::Learn More { #learn-more }::L87

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

You can also combine `dataclasses` with other Pydantic models, inherit from them, include them in your own models, etc.

To learn more, check the [Pydantic docs about dataclasses](https://docs.pydantic.dev/latest/concepts/dataclasses/).


docs/en/docs/advanced/dataclasses.md::Version { #version }::L93

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

This is available since FastAPI version `0.67.0`. 🔖


docs/en/docs/advanced/events.md::Lifespan Events { #lifespan-events }::L1

# Doc: docs/en/docs/advanced/events.md | Page: Lifespan Events { #lifespan-events } | Section: Lifespan Events { #lifespan-events }
# Lifespan Events { #lifespan-events }

You can define logic (code) that should be executed before the application **starts up**. This means that this code will be executed **once**, **before** the application **starts receiving requests**.

The same way, you can define logic (code) that should be executed when the application is **shutting down**. In this case, this code will be executed **once**, **after** having handled possibly **many requests**.

Because this code is executed before the application **starts** taking requests, and right after it **finishes** handling requests, it covers the whole application **lifespan** (the word "lifespan" will be important in a second 😉).

This can be very useful for setting up **resources** that you need to use for the whole app, and that are **shared** among requests, and/or that you need to **clean up** afterwards. For example, a database connection pool, or loading a shared machine learning model.


docs/en/docs/advanced/events.md::Use Case { #use-case }::L11

# Doc: docs/en/docs/advanced/events.md | Page: Lifespan Events { #lifespan-events } | Section: Use Case { #use-case }
## Use Case { #use-case }

Let's start with an example **use case** and then see how to solve it with this.

Let's imagine that you have some **machine learning models** that you want to use to handle requests. 🤖

The same models are shared among requests, so, it's not one model per request, or one per user or something similar.

Let's imagine that loading the model can **take quite some time**, because it has to read a lot of **data from disk**. So you don't want to do it for every request.

You could load it at the top level of the module/file, but that would also mean that it would **load the model** even if you are just running a simple automated test, then that test would be **slow** because it would have to wait for the model to load before being able to run an independent part of the code.

That's what we'll solve, let's load the model before the requests are handled, but only right before the application starts receiving requests, not while  the code is being loaded.


docs/en/docs/advanced/events.md::Lifespan { #lifespan }::L25

# Doc: docs/en/docs/advanced/events.md | Page: Lifespan Events { #lifespan-events } | Section: Lifespan { #lifespan }
## Lifespan { #lifespan }

You can define this *startup* and *shutdown* logic using the `lifespan` parameter of the `FastAPI` app, and a "context manager" (I'll show you what that is in a second).

Let's start with an example and then see it in detail.

We create an async function `lifespan()` with `yield` like this:

{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}

Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*.

And then, right after the `yield`, we unload the model. This code will be executed **after** the application **finishes handling requests**, right before the *shutdown*. This could, for example, release resources like memory or a GPU.

/// tip

The `shutdown` would happen when you are **stopping** the application.

Maybe you need to start a new version, or you just got tired of running it. 🤷

///

### Lifespan function { #lifespan-function }

The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.

{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}

The first part of the function, before the `yield`, will be executed **before** the application starts.

And the part after the `yield` will be executed **after** the application has finished.

### Async Context Manager { #async-context-manager }

If you check, the function is decorated with an `@asynccontextmanager`.

That converts the function into something called an "**async context manager**".

{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}

A **context manager** in Python is something that you can use in a `with` statement, for example, `open()` can be used as a context manager:

```Python
with open("file.txt") as file:
    file.read()
```

In recent versions of Python, there's also an **async context manager**. You would use it with `async with`:

```Python
async with lifespan(app):
    await do_stuff()
```

When you create a context manager or an async context manager like above, what it does is that, before entering the `with` block, it will execute the code before the `yield`, and after exiting the `with` block, it will execute the code after the `yield`.

In our code example above, we don't use it directly, but we pass it to FastAPI for it to use it.

The `lifespan` parameter of the `FastAPI` app takes an **async context manager**, so we can pass our new `lifespan` async context manager to it.

{* ../../docs_src/events/tutorial003_py310.py hl[22] *}


docs/en/docs/advanced/events.md::Alternative Events (deprecated) { #alternative-events-deprecated }::L87

# Doc: docs/en/docs/advanced/events.md | Page: Lifespan Events { #lifespan-events } | Section: Alternative Events (deprecated) { #alternative-events-deprecated }
## Alternative Events (deprecated) { #alternative-events-deprecated }

/// warning

The recommended way to handle the *startup* and *shutdown* is using the `lifespan` parameter of the `FastAPI` app as described above. If you provide a `lifespan` parameter, `startup` and `shutdown` event handlers will no longer be called. It's all `lifespan` or all events, not both.

You can probably skip this part.

///

There's an alternative way to define this logic to be executed during *startup* and during *shutdown*.

You can define event handlers (functions) that need to be executed before the application starts up, or when the application is shutting down.

These functions can be declared with `async def` or normal `def`.

### `startup` event { #startup-event }

To add a function that should be run before the application starts, declare it with the event `"startup"`:

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

In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.

You can add more than one event handler function.

And your application won't start receiving requests until all the `startup` event handlers have completed.

### `shutdown` event { #shutdown-event }

To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:

{* ../../docs_src/events/tutorial002_py310.py hl[6] *}

Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.

/// note

In the `open()` function, the `mode="a"` means "append", so, the line will be added after whatever is on that file, without overwriting the previous contents.

///

/// tip

Notice that in this case we are using a standard Python `open()` function that interacts with a file.

So, it involves I/O (input/output), that requires "waiting" for things to be written to disk.

But `open()` doesn't use `async` and `await`.

So, we declare the event handler function with standard `def` instead of `async def`.

///

### `startup` and `shutdown` together { #startup-and-shutdown-together }

There's a high chance that the logic for your *startup* and *shutdown* is connected, you might want to start something and then finish it, acquire a resource and then release it, etc.

Doing that in separate functions that don't share logic or variables together is more difficult as you would need to store values in global variables or similar tricks.

Because of that, it's now recommended to instead use the `lifespan` as explained above.


docs/en/docs/advanced/events.md::Technical Details { #technical-details }::L149

# Doc: docs/en/docs/advanced/events.md | Page: Lifespan Events { #lifespan-events } | Section: Technical Details { #technical-details }
## Technical Details { #technical-details }

Just a technical detail for the curious nerds. 🤓

Underneath, in the ASGI technical specification, this is part of the [Lifespan Protocol](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), and it defines events called `startup` and `shutdown`.

/// note

You can read more about the Starlette `lifespan` handlers in [Starlette's  Lifespan' docs](https://www.starlette.dev/lifespan/).

Including how to handle lifespan state that can be used in other areas of your code.

///


docs/en/docs/advanced/events.md::Sub Applications { #sub-applications }::L163

# Doc: docs/en/docs/advanced/events.md | Page: Lifespan Events { #lifespan-events } | Section: Sub Applications { #sub-applications }
## Sub Applications { #sub-applications }

🚨 Keep in mind that these lifespan events (startup and shutdown) will only be executed for the main application, not for [Sub Applications - Mounts](sub-applications.md).


docs/en/docs/advanced/generate-clients.md::Generating SDKs { #generating-sdks }::L1

# Doc: docs/en/docs/advanced/generate-clients.md | Page: Generating SDKs { #generating-sdks } | Section: Generating SDKs { #generating-sdks }
# Generating SDKs { #generating-sdks }

Because **FastAPI** is based on the **OpenAPI** specification, its APIs can be described in a standard format that many tools understand.

This makes it easy to generate up-to-date **documentation**, client libraries (<abbr title="Software Development Kits">**SDKs**</abbr>) in multiple languages, and **testing** or **automation workflows** that stay in sync with your code.

In this guide, you'll learn how to generate a **TypeScript SDK** for your FastAPI backend.


docs/en/docs/advanced/generate-clients.md::Open Source SDK Generators { #open-source-sdk-generators }::L9

# Doc: docs/en/docs/advanced/generate-clients.md | Page: Generating SDKs { #generating-sdks } | Section: Open Source SDK Generators { #open-source-sdk-generators }
## Open Source SDK Generators { #open-source-sdk-generators }

A versatile option is the [OpenAPI Generator](https://openapi-generator.tech/), which supports **many programming languages** and can generate SDKs from your OpenAPI specification.

For **TypeScript clients**, [Hey API](https://heyapi.dev/) is a purpose-built solution, providing an optimized experience for the TypeScript ecosystem.

You can discover more SDK generators on [OpenAPI.Tools](https://openapi.tools/#sdk).

/// tip

FastAPI automatically generates **OpenAPI 3.1** specifications, so any tool you use must support this version.

///


docs/en/docs/advanced/generate-clients.md::Create a TypeScript SDK { #create-a-typescript-sdk }::L23

# Doc: docs/en/docs/advanced/generate-clients.md | Page: Generating SDKs { #generating-sdks } | Section: Create a TypeScript SDK { #create-a-typescript-sdk }
## Create a TypeScript SDK { #create-a-typescript-sdk }

Let's start with a simple FastAPI application:

{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}

Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`.

### API Docs { #api-docs }

If you go to `/docs`, you will see that it has the **schemas** for the data to be sent in requests and received in responses:

You can see those schemas because they were declared with the models in the app.

That information is available in the app's **OpenAPI schema**, and then shown in the API docs.

That same information from the models that is included in OpenAPI is what can be used to **generate the client code**.

### Hey API { #hey-api }

Once we have a FastAPI app with the models, we can use Hey API to generate a TypeScript client. The fastest way to do that is via npx.

```sh
npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
```

This will generate a TypeScript SDK in `./src/client`.

You can learn how to [install `@hey-api/openapi-ts`](https://heyapi.dev/openapi-ts/get-started) and read about the [generated output](https://heyapi.dev/openapi-ts/output) on their website.

### Using the SDK { #using-the-sdk }

Now you can import and use the client code. It could look like this, notice that you get autocompletion for the methods:

You will also get autocompletion for the payload to send:

/// tip

Notice the autocompletion for `name` and `price`, that was defined in the FastAPI application, in the `Item` model.

///

You will have inline errors for the data that you send:

The response object will also have autocompletion:


docs/en/docs/advanced/generate-clients.md::FastAPI App with Tags { #fastapi-app-with-tags }::L79

# Doc: docs/en/docs/advanced/generate-clients.md | Page: Generating SDKs { #generating-sdks } | Section: FastAPI App with Tags { #fastapi-app-with-tags }
## FastAPI App with Tags { #fastapi-app-with-tags }

In many cases, your FastAPI app will be bigger, and you will probably use tags to separate different groups of *path operations*.

For example, you could have a section for **items** and another section for **users**, and they could be separated by tags:

{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}

### Generate a TypeScript Client with Tags { #generate-a-typescript-client-with-tags }

If you generate a client for a FastAPI app using tags, it will normally also separate the client code based on the tags.

This way, you will be able to have things ordered and grouped correctly for the client code:

<img src="/img/tutorial/generate-clients/image06.png">

In this case, you have:

* `ItemsService`
* `UsersService`

### Client Method Names { #client-method-names }

Right now, the generated method names like `createItemItemsPost` don't look very clean:

```TypeScript
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
```

...that's because the client generator uses the OpenAPI internal **operation ID** for each *path operation*.

OpenAPI requires that each operation ID is unique across all the *path operations*, so FastAPI uses the **function name**, the **path**, and the **HTTP method/operation** to generate that operation ID, because that way it can make sure that the operation IDs are unique.

But I'll show you how to improve that next. 🤓


docs/en/docs/advanced/generate-clients.md::Custom Operation IDs and Better Method Names { #custom-operation-ids-and-better-method-names }::L114

# Doc: docs/en/docs/advanced/generate-clients.md | Page: Generating SDKs { #generating-sdks } | Section: Custom Operation IDs and Better Method Names { #custom-operation-ids-and-better-method-names }
## Custom Operation IDs and Better Method Names { #custom-operation-ids-and-better-method-names }

You can **modify** the way these operation IDs are **generated** to make them simpler and have **simpler method names** in the clients.

In this case, you will have to ensure that each operation ID is **unique** in some other way.

For example, you could make sure that each *path operation* has a tag, and then generate the operation ID based on the **tag** and the *path operation* **name** (the function name).

### Custom Generate Unique ID Function { #custom-generate-unique-id-function }

FastAPI uses a **unique ID** for each *path operation*, which is used for the **operation ID** and also for the names of any needed custom models, for requests or responses.

You can customize that function. It takes an `APIRoute` and outputs a string.

For example, here it is using the first tag (you will probably have only one tag) and the *path operation* name (the function name).

You can then pass that custom function to **FastAPI** as the `generate_unique_id_function` parameter:

{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}

### Generate a TypeScript Client with Custom Operation IDs { #generate-a-typescript-client-with-custom-operation-ids }

Now, if you generate the client again, you will see that it has the improved method names:

As you see, the method names now have the tag and then the function name, now they don't include information from the URL path and the HTTP operation.

### Preprocess the OpenAPI Specification for the Client Generator { #preprocess-the-openapi-specification-for-the-client-generator }

The generated code still has some **duplicated information**.

We already know that this method is related to the **items** because that word is in the `ItemsService` (taken from the tag), but we still have the tag name prefixed in the method name too. 😕

We will probably still want to keep it for OpenAPI in general, as that will ensure that the operation IDs are **unique**.

But for the generated client, we could **modify** the OpenAPI operation IDs right before generating the clients, just to make those method names nicer and **cleaner**.

We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this:

{* ../../docs_src/generate_clients/tutorial004_py310.py *}

//// tab | Node.js

```Javascript
{!> ../../docs_src/generate_clients/tutorial004.js!}
```

////

With that, the operation IDs would be renamed from things like `items-get_items` to just `get_items`, that way the client generator can generate simpler method names.

### Generate a TypeScript Client with the Preprocessed OpenAPI { #generate-a-typescript-client-with-the-preprocessed-openapi }

Since the end result is now in an `openapi.json` file, you need to update your input location:

```sh
npx @hey-api/openapi-ts -i ./openapi.json -o src/client
```

After generating the new client, you would now have **clean method names**, with all the **autocompletion**, **inline errors**, etc:


docs/en/docs/advanced/generate-clients.md::Benefits { #benefits }::L178

# Doc: docs/en/docs/advanced/generate-clients.md | Page: Generating SDKs { #generating-sdks } | Section: Benefits { #benefits }
## Benefits { #benefits }

When using the automatically generated clients, you would get **autocompletion** for:

* Methods.
* Request payloads in the body, query parameters, etc.
* Response payloads.

You would also have **inline errors** for everything.

And whenever you update the backend code, and **regenerate** the frontend, it would have any new *path operations* available as methods, the old ones removed, and any other change would be reflected on the generated code. 🤓

This also means that if something changed, it will be **reflected** on the client code automatically. And if you **build** the client, it will error out if you have any **mismatch** in the data used.

So, you would **detect many errors** very early in the development cycle instead of having to wait for the errors to show up to your final users in production and then trying to debug where the problem is. ✨


docs/en/docs/advanced/index.md::Additional Features { #additional-features }::L3

# Doc: docs/en/docs/advanced/index.md | Page: Advanced User Guide { #advanced-user-guide } | Section: Additional Features { #additional-features }
## Additional Features { #additional-features }

The main [Tutorial - User Guide](../tutorial/index.md) should be enough to give you a tour through all the main features of **FastAPI**.

In the next sections you will see other options, configurations, and additional features.

/// tip

The next sections are **not necessarily "advanced"**.

And it's possible that for your use case, the solution is in one of them.

///


docs/en/docs/advanced/index.md::Read the Tutorial first { #read-the-tutorial-first }::L17

# Doc: docs/en/docs/advanced/index.md | Page: Advanced User Guide { #advanced-user-guide } | Section: Read the Tutorial first { #read-the-tutorial-first }
## Read the Tutorial first { #read-the-tutorial-first }

You could still use most of the features in **FastAPI** with the knowledge from the main [Tutorial - User Guide](../tutorial/index.md).

And the next sections assume you already read it, and assume that you know those main ideas.


docs/en/docs/advanced/json-base64-bytes.md::JSON with Bytes as Base64 { #json-with-bytes-as-base64 }::L1

# Doc: docs/en/docs/advanced/json-base64-bytes.md | Page: JSON with Bytes as Base64 { #json-with-bytes-as-base64 } | Section: JSON with Bytes as Base64 { #json-with-bytes-as-base64 }
# JSON with Bytes as Base64 { #json-with-bytes-as-base64 }

If your app needs to receive and send JSON data, but you need to include binary data in it, you can encode it as base64.


docs/en/docs/advanced/json-base64-bytes.md::Base64 vs Files { #base64-vs-files }::L5

# Doc: docs/en/docs/advanced/json-base64-bytes.md | Page: JSON with Bytes as Base64 { #json-with-bytes-as-base64 } | Section: Base64 vs Files { #base64-vs-files }
## Base64 vs Files { #base64-vs-files }

Consider first if you can use [Request Files](../tutorial/request-files.md) for uploading binary data and [Custom Response - FileResponse](./custom-response.md#fileresponse) for sending binary data, instead of encoding it in JSON.

JSON can only contain UTF-8 encoded strings, so it can't contain raw bytes.

Base64 can encode binary data in strings, but to do it, it needs to use more characters than the original binary data, so it would normally be less efficient than regular files.

Use base64 only if you definitely need to include binary data in JSON, and you can't use files for that.


docs/en/docs/advanced/json-base64-bytes.md::Pydantic `bytes` { #pydantic-bytes }::L15

# Doc: docs/en/docs/advanced/json-base64-bytes.md | Page: JSON with Bytes as Base64 { #json-with-bytes-as-base64 } | Section: Pydantic `bytes` { #pydantic-bytes }
## Pydantic `bytes` { #pydantic-bytes }

You can declare a Pydantic model with `bytes` fields, and then use `val_json_bytes` in the model config to tell it to use base64 to *validate* input JSON data, as part of that validation it will decode the base64 string into bytes.

{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}

If you check the `/docs`, they will show that the field `data` expects base64 encoded bytes:

You could send a request like:

```json
{
    "description": "Some data",
    "data": "aGVsbG8="
}
```

/// tip

`aGVsbG8=` is the base64 encoding of `hello`.

///

And then Pydantic will decode the base64 string and give you the original bytes in the `data` field of the model.

You will receive a response like:

```json
{
  "description": "Some data",
  "content": "hello"
}
```


docs/en/docs/advanced/json-base64-bytes.md::Pydantic `bytes` for Output Data { #pydantic-bytes-for-output-data }::L53

# Doc: docs/en/docs/advanced/json-base64-bytes.md | Page: JSON with Bytes as Base64 { #json-with-bytes-as-base64 } | Section: Pydantic `bytes` for Output Data { #pydantic-bytes-for-output-data }
## Pydantic `bytes` for Output Data { #pydantic-bytes-for-output-data }

You can also use `bytes` fields with `ser_json_bytes` in the model config for output data, and Pydantic will *serialize* the bytes as base64 when generating the JSON response.

{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}


docs/en/docs/advanced/json-base64-bytes.md::Pydantic `bytes` for Input and Output Data { #pydantic-bytes-for-input-and-output-data }::L59

# Doc: docs/en/docs/advanced/json-base64-bytes.md | Page: JSON with Bytes as Base64 { #json-with-bytes-as-base64 } | Section: Pydantic `bytes` for Input and Output Data { #pydantic-bytes-for-input-and-output-data }
## Pydantic `bytes` for Input and Output Data { #pydantic-bytes-for-input-and-output-data }

And of course, you can use the same model configured to use base64 to handle both input (*validate*) with `val_json_bytes` and output (*serialize*) with `ser_json_bytes` when receiving and sending JSON data.

{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}


docs/en/docs/advanced/middleware.md::Advanced Middleware { #advanced-middleware }::L1

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

In the main tutorial you read how to add [Custom Middleware](../tutorial/middleware.md) to your application.

And then you also read how to handle [CORS with the `CORSMiddleware`](../tutorial/cors.md).

In this section we'll see how to use other middlewares.


docs/en/docs/advanced/middleware.md::Adding ASGI middlewares { #adding-asgi-middlewares }::L9

# Doc: docs/en/docs/advanced/middleware.md | Page: Advanced Middleware { #advanced-middleware } | Section: Adding ASGI middlewares { #adding-asgi-middlewares }
## Adding ASGI middlewares { #adding-asgi-middlewares }

As **FastAPI** is based on Starlette and implements the <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr> specification, you can use any ASGI middleware.

A middleware doesn't have to be made for FastAPI or Starlette to work, as long as it follows the ASGI spec.

In general, ASGI middlewares are classes that expect to receive an ASGI app as the first argument.

So, in the documentation for third-party ASGI middlewares they will probably tell you to do something like:

```Python
from unicorn import UnicornMiddleware

app = SomeASGIApp()

new_app = UnicornMiddleware(app, some_config="rainbow")
```

But FastAPI (actually Starlette) provides a simpler way to do it that makes sure that the internal middlewares handle server errors and custom exception handlers work properly.

For that, you use `app.add_middleware()` (as in the example for CORS).

```Python
from fastapi import FastAPI
from unicorn import UnicornMiddleware

app = FastAPI()

app.add_middleware(UnicornMiddleware, some_config="rainbow")
```

`app.add_middleware()` receives a middleware class as the first argument and any additional arguments to be passed to the middleware.


docs/en/docs/advanced/middleware.md::Integrated middlewares { #integrated-middlewares }::L42

# Doc: docs/en/docs/advanced/middleware.md | Page: Advanced Middleware { #advanced-middleware } | Section: Integrated middlewares { #integrated-middlewares }
## Integrated middlewares { #integrated-middlewares }

**FastAPI** includes several middlewares for common use cases, we'll see next how to use them.

/// note | Technical Details

For the next examples, you could also use `from starlette.middleware.something import SomethingMiddleware`.

**FastAPI** provides several middlewares in `fastapi.middleware` just as a convenience for you, the developer. But most of the available middlewares come directly from Starlette.

///


docs/en/docs/advanced/middleware.md::`HTTPSRedirectMiddleware` { #httpsredirectmiddleware }::L54

# Doc: docs/en/docs/advanced/middleware.md | Page: Advanced Middleware { #advanced-middleware } | Section: `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }
## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }

Enforces that all incoming requests must either be `https` or `wss`.

Any incoming request to `http` or `ws` will be redirected to the secure scheme instead.

{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}


docs/en/docs/advanced/middleware.md::`TrustedHostMiddleware` { #trustedhostmiddleware }::L62

# Doc: docs/en/docs/advanced/middleware.md | Page: Advanced Middleware { #advanced-middleware } | Section: `TrustedHostMiddleware` { #trustedhostmiddleware }
## `TrustedHostMiddleware` { #trustedhostmiddleware }

Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks.

{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}

The following arguments are supported:

* `allowed_hosts` - A list of domain names that should be allowed as hostnames. Wildcard domains such as `*.example.com` are supported for matching subdomains. To allow any hostname either use `allowed_hosts=["*"]` or omit the middleware.
* `www_redirect` - If set to True, requests to non-www versions of the allowed hosts will be redirected to their www counterparts. Defaults to `True`.

If an incoming request does not validate correctly then a `400` response will be sent.


docs/en/docs/advanced/middleware.md::`GZipMiddleware` { #gzipmiddleware }::L75

# Doc: docs/en/docs/advanced/middleware.md | Page: Advanced Middleware { #advanced-middleware } | Section: `GZipMiddleware` { #gzipmiddleware }
## `GZipMiddleware` { #gzipmiddleware }

Handles GZip responses for any request that includes `"gzip"` in the `Accept-Encoding` header.

The middleware will handle both standard and streaming responses.

{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}

The following arguments are supported:

* `minimum_size` - Do not GZip responses that are smaller than this minimum size in bytes. Defaults to `500`.
* `compresslevel` - Used during GZip compression. It is an integer ranging from 1 to 9. Defaults to `9`. Lower value results in faster compression but larger file sizes, while higher value results in slower compression but smaller file sizes.


docs/en/docs/advanced/middleware.md::Other middlewares { #other-middlewares }::L88

# Doc: docs/en/docs/advanced/middleware.md | Page: Advanced Middleware { #advanced-middleware } | Section: Other middlewares { #other-middlewares }
## Other middlewares { #other-middlewares }

There are many other ASGI middlewares.

For example:

* [Uvicorn's `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)

To see other available middlewares check [Starlette's Middleware docs](https://www.starlette.dev/middleware/) and the [ASGI Awesome List](https://github.com/florimondmanca/awesome-asgi).


docs/en/docs/advanced/openapi-callbacks.md::OpenAPI Callbacks { #openapi-callbacks }::L1

# Doc: docs/en/docs/advanced/openapi-callbacks.md | Page: OpenAPI Callbacks { #openapi-callbacks } | Section: OpenAPI Callbacks { #openapi-callbacks }
# OpenAPI Callbacks { #openapi-callbacks }

You could create an API with a *path operation* that could trigger a request to an *external API* created by someone else (probably the same developer that would be *using* your API).

The process that happens when your API app calls the *external API* is named a "callback". Because the software that the external developer wrote sends a request to your API and then your API *calls back*, sending a request to an *external API* (that was probably created by the same developer).

In this case, you could want to document how that external API *should* look. What *path operation* it should have, what body it should expect, what response it should return, etc.


docs/en/docs/advanced/openapi-callbacks.md::An app with callbacks { #an-app-with-callbacks }::L9

# Doc: docs/en/docs/advanced/openapi-callbacks.md | Page: OpenAPI Callbacks { #openapi-callbacks } | Section: An app with callbacks { #an-app-with-callbacks }
## An app with callbacks { #an-app-with-callbacks }

Let's see all this with an example.

Imagine you develop an app that allows creating invoices.

These invoices will have an `id`, `title` (optional), `customer`, and `total`.

The user of your API (an external developer) will create an invoice in your API with a POST request.

Then your API will (let's imagine):

* Send the invoice to some customer of the external developer.
* Collect the money.
* Send a notification back to the API user (the external developer).
    * This will be done by sending a POST request (from *your API*) to some *external API* provided by that external developer (this is the "callback").


docs/en/docs/advanced/openapi-callbacks.md::The normal **FastAPI** app { #the-normal-fastapi-app }::L26

# Doc: docs/en/docs/advanced/openapi-callbacks.md | Page: OpenAPI Callbacks { #openapi-callbacks } | Section: The normal **FastAPI** app { #the-normal-fastapi-app }
## The normal **FastAPI** app { #the-normal-fastapi-app }

Let's first see how the normal API app would look before adding the callback.

It will have a *path operation* that will receive an `Invoice` body, and a query parameter `callback_url` that will contain the URL for the callback.

This part is pretty normal, most of the code is probably already familiar to you:

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}

/// tip

The `callback_url` query parameter uses a Pydantic [Url](https://docs.pydantic.dev/latest/api/networks/) type.

///

The only new thing is the `callbacks=invoices_callback_router.routes` as an argument to the *path operation decorator*. We'll see what that is next.


docs/en/docs/advanced/openapi-callbacks.md::Documenting the callback { #documenting-the-callback }::L44

# Doc: docs/en/docs/advanced/openapi-callbacks.md | Page: OpenAPI Callbacks { #openapi-callbacks } | Section: Documenting the callback { #documenting-the-callback }
## Documenting the callback { #documenting-the-callback }

The actual callback code will depend heavily on your own API app.

And it will probably vary a lot from one app to the next.

It could be just one or two lines of code, like:

```Python
callback_url = "https://example.com/api/v1/invoices/events/"
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
```

But possibly the most important part of the callback is making sure that your API user (the external developer) implements the *external API* correctly, according to the data that *your API* is going to send in the request body of the callback, etc.

So, what we will do next is add the code to document how that *external API* should look to receive the callback from *your API*.

That documentation will show up in the Swagger UI at `/docs` in your API, and it will let external developers know how to build the *external API*.

This example doesn't implement the callback itself (that could be just a line of code), only the documentation part.

/// tip

The actual callback is just an HTTP request.

When implementing the callback yourself, you could use something like [HTTPX](https://www.python-httpx.org) or [Requests](https://requests.readthedocs.io/).

///


docs/en/docs/advanced/openapi-callbacks.md::Write the callback documentation code { #write-the-callback-documentation-code }::L73

# Doc: docs/en/docs/advanced/openapi-callbacks.md | Page: OpenAPI Callbacks { #openapi-callbacks } | Section: Write the callback documentation code { #write-the-callback-documentation-code }
## Write the callback documentation code { #write-the-callback-documentation-code }

This code won't be executed in your app, we only need it to *document* how that *external API* should look.

But, you already know how to easily create automatic documentation for an API with **FastAPI**.

So we are going to use that same knowledge to document how the *external API* should look... by creating the *path operation(s)* that the external API should implement (the ones your API will call).

/// tip

When writing the code to document a callback, it might be useful to imagine that you are that *external developer*. And that you are currently implementing the *external API*, not *your API*.

Temporarily adopting this point of view (of the *external developer*) can help you feel like it's more obvious where to put the parameters, the Pydantic model for the body, for the response, etc. for that *external API*.

///

### Create a callback `APIRouter` { #create-a-callback-apirouter }

First create a new `APIRouter` that will contain one or more callbacks.

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}

### Create the callback *path operation* { #create-the-callback-path-operation }

To create the callback *path operation* use the same `APIRouter` you created above.

It should look just like a normal FastAPI *path operation*:

* It should probably have a declaration of the body it should receive, e.g. `body: InvoiceEvent`.
* And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`.

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}

There are 2 main differences from a normal *path operation*:

* It doesn't need to have any actual code, because your app will never call this code. It's only used to document the *external API*. So, the function could just have `pass`.
* The *path* can contain an [OpenAPI 3 expression](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) (see more below) where it can use variables with parameters and parts of the original request sent to *your API*.

### The callback path expression { #the-callback-path-expression }

The callback *path* can have an [OpenAPI 3 expression](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) that can contain parts of the original request sent to *your API*.

In this case, it's the `str`:

```Python
"{$callback_url}/invoices/{$request.body.id}"
```

So, if your API user (the external developer) sends a request to *your API* to:

```
https://yourapi.com/invoices/?callback_url=https://www.external.org/events
```

with a JSON body of:

```JSON
{
    "id": "2expen51ve",
    "customer": "Mr. Richie Rich",
    "total": "9999"
}
```

then *your API* will process the invoice, and at some point later, send a callback request to the `callback_url` (the *external API*):

```
https://www.external.org/events/invoices/2expen51ve
```

with a JSON body containing something like:

```JSON
{
    "description": "Payment celebration",
    "paid": true
}
```

and it would expect a response from that *external API* with a JSON body like:

```JSON
{
    "ok": true
}
```

/// tip

Notice how the callback URL used contains the URL received as a query parameter in `callback_url` (`https://www.external.org/events`) and also the invoice `id` from inside of the JSON body (`2expen51ve`).

///

### Add the callback router { #add-the-callback-router }

At this point you have the *callback path operation(s)* needed (the one(s) that the *external developer*  should implement in the *external API*) in the callback router you created above.

Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` from that callback router:

{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}

/// tip

Notice that you are not passing the router itself (`invoices_callback_router`) to `callbacks=`, but its `.routes`, as in `invoices_callback_router.routes`. FastAPI will use those routes to generate the callback OpenAPI documentation.

///

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

Now you can start your app and go to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).

You will see your docs including a "Callbacks" section for your *path operation* that shows how the *external API* should look:

<img src="/img/tutorial/openapi-callbacks/image01.png">


docs/en/docs/advanced/openapi-webhooks.md::OpenAPI Webhooks { #openapi-webhooks }::L1

# Doc: docs/en/docs/advanced/openapi-webhooks.md | Page: OpenAPI Webhooks { #openapi-webhooks } | Section: OpenAPI Webhooks { #openapi-webhooks }
# OpenAPI Webhooks { #openapi-webhooks }

There are cases where you want to tell your API **users** that your app could call *their* app (sending a request) with some data, normally to **notify** of some type of **event**.

This means that instead of the normal process of your users sending requests to your API, it's **your API** (or your app) that could **send requests to their system** (to their API, their app).

This is normally called a **webhook**.


docs/en/docs/advanced/openapi-webhooks.md::Webhooks steps { #webhooks-steps }::L9

# Doc: docs/en/docs/advanced/openapi-webhooks.md | Page: OpenAPI Webhooks { #openapi-webhooks } | Section: Webhooks steps { #webhooks-steps }
## Webhooks steps { #webhooks-steps }

The process normally is that **you define** in your code what is the message that you will send, the **body of the request**.

You also define in some way at which **moments** your app will send those requests or events.

And **your users** define in some way (for example in a web dashboard somewhere) the **URL** where your app should send those requests.

All the **logic** about how to register the URLs for webhooks and the code to actually send those requests is up to you. You write it however you want to in **your own code**.


docs/en/docs/advanced/openapi-webhooks.md::Documenting webhooks with **FastAPI** and OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }::L19

# Doc: docs/en/docs/advanced/openapi-webhooks.md | Page: OpenAPI Webhooks { #openapi-webhooks } | Section: Documenting webhooks with **FastAPI** and OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
## Documenting webhooks with **FastAPI** and OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }

With **FastAPI**, using OpenAPI, you can define the names of these webhooks, the types of HTTP operations that your app can send (e.g. `POST`, `PUT`, etc.) and the request **bodies** that your app would send.

This can make it a lot easier for your users to **implement their APIs** to receive your **webhook** requests, they might even be able to autogenerate some of their own API code.

/// note

Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0` and above.

///


docs/en/docs/advanced/openapi-webhooks.md::An app with webhooks { #an-app-with-webhooks }::L31

# Doc: docs/en/docs/advanced/openapi-webhooks.md | Page: OpenAPI Webhooks { #openapi-webhooks } | Section: An app with webhooks { #an-app-with-webhooks }
## An app with webhooks { #an-app-with-webhooks }

When you create a **FastAPI** application, there is a `webhooks` attribute that you can use to define *webhooks*, the same way you would define *path operations*, for example with `@app.webhooks.post()`.

{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}

The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**.

/// note

The `app.webhooks` object is actually just an `APIRouter`, the same type you would use when structuring your app with multiple files.

///

Notice that with webhooks you are actually not declaring a *path* (like `/items/`), the text you pass there is just an **identifier** of the webhook (the name of the event), for example in `@app.webhooks.post("new-subscription")`, the webhook name is `new-subscription`.

This is because it is expected that **your users** would define the actual **URL path** where they want to receive the webhook request in some other way (e.g. a web dashboard).

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

Now you can start your app and go to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).

You will see your docs have the normal *path operations* and now also some **webhooks**:

<img src="/img/tutorial/openapi-webhooks/image01.png">


docs/en/docs/advanced/path-operation-advanced-configuration.md::Path Operation Advanced Configuration { #path-operation-advanced-configuration }::L1

# Doc: docs/en/docs/advanced/path-operation-advanced-configuration.md | Page: Path Operation Advanced Configuration { #path-operation-advanced-configuration } | Section: Path Operation Advanced Configuration { #path-operation-advanced-configuration }
# Path Operation Advanced Configuration { #path-operation-advanced-configuration }


docs/en/docs/advanced/path-operation-advanced-configuration.md::OpenAPI operationId { #openapi-operationid }::L3

# Doc: docs/en/docs/advanced/path-operation-advanced-configuration.md | Page: Path Operation Advanced Configuration { #path-operation-advanced-configuration } | Section: OpenAPI operationId { #openapi-operationid }
## OpenAPI operationId { #openapi-operationid }

/// warning

If you are not an "expert" in OpenAPI, you probably don't need this.

///

You can set the OpenAPI `operationId` to be used in your *path operation* with the parameter `operation_id`.

You would have to make sure that it is unique for each operation.

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

### Using the *path operation function* name as the operationId { #using-the-path-operation-function-name-as-the-operationid }

If you want to use your APIs' function names as `operationId`s, you can pass a custom `generate_unique_id_function` to `FastAPI`.

The function receives each `APIRoute` and returns the `operationId` to use for that path operation.

{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2,5:6,9] *}

/// warning

If you do this, you have to make sure each one of your *path operation functions* has a unique name.

Even if they are in different modules (Python files).

///


docs/en/docs/advanced/path-operation-advanced-configuration.md::Exclude from OpenAPI { #exclude-from-openapi }::L33

# Doc: docs/en/docs/advanced/path-operation-advanced-configuration.md | Page: Path Operation Advanced Configuration { #path-operation-advanced-configuration } | Section: Exclude from OpenAPI { #exclude-from-openapi }
## Exclude from OpenAPI { #exclude-from-openapi }

To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`:

{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}


docs/en/docs/advanced/path-operation-advanced-configuration.md::Advanced description from docstring { #advanced-description-from-docstring }::L39

# Doc: docs/en/docs/advanced/path-operation-advanced-configuration.md | Page: Path Operation Advanced Configuration { #path-operation-advanced-configuration } | Section: Advanced description from docstring { #advanced-description-from-docstring }
## Advanced description from docstring { #advanced-description-from-docstring }

You can limit the lines used from the docstring of a *path operation function* for OpenAPI.

Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate the output used for OpenAPI at this point.

It won't show up in the documentation, but other tools (such as Sphinx) will be able to use the rest.

{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}


docs/en/docs/advanced/path-operation-advanced-configuration.md::Additional Responses { #additional-responses }::L49

# Doc: docs/en/docs/advanced/path-operation-advanced-configuration.md | Page: Path Operation Advanced Configuration { #path-operation-advanced-configuration } | Section: Additional Responses { #additional-responses }
## Additional Responses { #additional-responses }

You probably have seen how to declare the `response_model` and `status_code` for a *path operation*.

That defines the metadata about the main response of a *path operation*.

You can also declare additional responses with their models, status codes, etc.

There's a whole chapter here in the documentation about it, you can read it at [Additional Responses in OpenAPI](additional-responses.md).


docs/en/docs/advanced/path-operation-advanced-configuration.md::OpenAPI Extra { #openapi-extra }::L59

# Doc: docs/en/docs/advanced/path-operation-advanced-configuration.md | Page: Path Operation Advanced Configuration { #path-operation-advanced-configuration } | Section: OpenAPI Extra { #openapi-extra }
## OpenAPI Extra { #openapi-extra }

When you declare a *path operation* in your application, **FastAPI** automatically generates the relevant metadata about that *path operation* to be included in the OpenAPI schema.

/// note | Technical details

In the OpenAPI specification it is called the [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object).

///

It has all the information about the *path operation* and is used to generate the automatic documentation.

It includes the `tags`, `parameters`, `requestBody`, `responses`, etc.

This *path operation*-specific OpenAPI schema is normally generated automatically by **FastAPI**, but you can also extend it.

/// tip

This is a low level extension point.

If you only need to declare additional responses, a more convenient way to do it is with [Additional Responses in OpenAPI](additional-responses.md).

///

You can extend the OpenAPI schema for a *path operation* using the parameter `openapi_extra`.

### OpenAPI Extensions { #openapi-extensions }

This `openapi_extra` can be helpful, for example, to declare [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):

{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}

If you open the automatic API docs, your extension will show up at the bottom of the specific *path operation*.

<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">

And if you see the resulting OpenAPI (at `/openapi.json` in your API), you will see your extension as part of the specific *path operation* too:

```JSON hl_lines="22"
{
    "openapi": "3.1.0",
    "info": {
        "title": "FastAPI",
        "version": "0.1.0"
    },
    "paths": {
        "/items/": {
            "get": {
                "summary": "Read Items",
                "operationId": "read_items_items__get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {}
                            }
                        }
                    }
                },
                "x-aperture-labs-portal": "blue"
            }
        }
    }
}
```

### Custom OpenAPI *path operation* schema { #custom-openapi-path-operation-schema }

The dictionary in `openapi_extra` will be deeply merged with the automatically generated OpenAPI schema for the *path operation*.

So, you could add additional data to the automatically generated schema.

For example, you could decide to read and validate the request with your own code, without using the automatic features of FastAPI with Pydantic, but you could still want to define the request in the OpenAPI schema.

You could do that with `openapi_extra`:

{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}

In this example, we didn't declare any Pydantic model. In fact, the request body is not even <dfn title="converted from some plain format, like bytes, into Python objects">parsed</dfn> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.

Nevertheless, we can declare the expected schema for the request body.

### Custom OpenAPI content type { #custom-openapi-content-type }

Using this same trick, you could use a Pydantic model to define the JSON Schema that is then included in the custom OpenAPI schema section for the *path operation*.

And you could do this even if the data type in the request is not JSON.

For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:

{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}

Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.

Then we use the request directly, and extract the body as `bytes`. This means that FastAPI won't even try to parse the request payload as JSON.

And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:

{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}

/// tip

Here we reuse the same Pydantic model.

But the same way, we could have validated it in some other way.

///


docs/en/docs/advanced/response-change-status-code.md::Response - Change Status Code { #response-change-status-code }::L1

# Doc: docs/en/docs/advanced/response-change-status-code.md | Page: Response - Change Status Code { #response-change-status-code } | Section: Response - Change Status Code { #response-change-status-code }
# Response - Change Status Code { #response-change-status-code }

You probably read before that you can set a default [Response Status Code](../tutorial/response-status-code.md).

But in some cases you need to return a different status code than the default.


docs/en/docs/advanced/response-change-status-code.md::Use case { #use-case }::L7

# Doc: docs/en/docs/advanced/response-change-status-code.md | Page: Response - Change Status Code { #response-change-status-code } | Section: Use case { #use-case }
## Use case { #use-case }

For example, imagine that you want to return an HTTP status code of "OK" `200` by default.

But if the data didn't exist, you want to create it, and return an HTTP status code of "CREATED" `201`.

But you still want to be able to filter and convert the data you return with a `response_model`.

For those cases, you can use a `Response` parameter.


docs/en/docs/advanced/response-change-status-code.md::Use a `Response` parameter { #use-a-response-parameter }::L17

# Doc: docs/en/docs/advanced/response-change-status-code.md | Page: Response - Change Status Code { #response-change-status-code } | Section: Use a `Response` parameter { #use-a-response-parameter }
## Use a `Response` parameter { #use-a-response-parameter }

You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies and headers).

And then you can set the `status_code` in that *temporary* response object.

{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}

And then you can return any object you need, as you normally would (a `dict`, a database model, etc).

And if you declared a `response_model`, it will still be used to filter and convert the object you returned.

**FastAPI** will use that *temporary* response to extract the status code (also cookies and headers), and will put them in the final response that contains the value you returned, filtered by any `response_model`.

You can also declare the `Response` parameter in dependencies, and set the status code in them. But keep in mind that the last one to be set will win.


docs/en/docs/advanced/response-cookies.md::Use a `Response` parameter { #use-a-response-parameter }::L3

# Doc: docs/en/docs/advanced/response-cookies.md | Page: Response Cookies { #response-cookies } | Section: Use a `Response` parameter { #use-a-response-parameter }
## Use a `Response` parameter { #use-a-response-parameter }

You can declare a parameter of type `Response` in your *path operation function*.

And then you can set cookies in that *temporary* response object.

{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}

And then you can return any object you need, as you normally would (a `dict`, a database model, etc).

And if you declared a `response_model`, it will still be used to filter and convert the object you returned.

**FastAPI** will use that *temporary* response to extract the cookies (also headers and status code), and will put them in the final response that contains the value you returned, filtered by any `response_model`.

You can also declare the `Response` parameter in dependencies, and set cookies (and headers) in them.


docs/en/docs/advanced/response-cookies.md::Return a `Response` directly { #return-a-response-directly }::L19

# Doc: docs/en/docs/advanced/response-cookies.md | Page: Response Cookies { #response-cookies } | Section: Return a `Response` directly { #return-a-response-directly }
## Return a `Response` directly { #return-a-response-directly }

You can also create cookies when returning a `Response` directly in your code.

To do that, you can create a response as described in [Return a Response Directly](response-directly.md).

Then set Cookies in it, and then return it:

{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}

/// tip

Keep in mind that if you return a response directly instead of using the `Response` parameter, FastAPI will return it directly.

So, you will have to make sure your data is of the correct type. E.g. it is compatible with JSON, if you are returning a `JSONResponse`.

And also that you are not sending any data that should have been filtered by a `response_model`.

///

### More info { #more-info }

/// note | Technical Details

You could also use `from starlette.responses import Response` or `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.

And as the `Response` can be used frequently to set headers and cookies, **FastAPI** also provides it at `fastapi.Response`.

///

To see all the available parameters and options, check the [documentation in Starlette](https://www.starlette.dev/responses/#set-cookie).


docs/en/docs/advanced/response-directly.md::Return a Response Directly { #return-a-response-directly }::L1

# Doc: docs/en/docs/advanced/response-directly.md | Page: Return a Response Directly { #return-a-response-directly } | Section: Return a Response Directly { #return-a-response-directly }
# Return a Response Directly { #return-a-response-directly }

When you create a **FastAPI** *path operation* you can normally return any data from it: a `dict`, a `list`, a Pydantic model, a database model, etc.

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

You could also create a `JSONResponse` directly and return it.

/// tip

You will normally have much better performance using a [Response Model](../tutorial/response-model.md) than returning a `JSONResponse` directly, as that way it serializes the data using Pydantic, in Rust.

///


docs/en/docs/advanced/response-directly.md::Return a `Response` { #return-a-response }::L17

# Doc: docs/en/docs/advanced/response-directly.md | Page: Return a Response Directly { #return-a-response-directly } | Section: Return a `Response` { #return-a-response }
## Return a `Response` { #return-a-response }

You can return a `Response` or any sub-class of it.

/// note

`JSONResponse` itself is a sub-class of `Response`.

///

And when you return a `Response`, **FastAPI** will pass it directly.

It won't do any data conversion with Pydantic models, it won't convert the contents to any type, etc.

This gives you a lot of **flexibility**. You can return any data type, override any data declaration or validation, etc.

It also gives you a lot of **responsibility**. You have to make sure that the data you return is correct, in the correct format, that it can be serialized, etc.


docs/en/docs/advanced/response-directly.md::Using the `jsonable_encoder` in a `Response` { #using-the-jsonable-encoder-in-a-response }::L35

# Doc: docs/en/docs/advanced/response-directly.md | Page: Return a Response Directly { #return-a-response-directly } | Section: Using the `jsonable_encoder` in a `Response` { #using-the-jsonable-encoder-in-a-response }
## Using the `jsonable_encoder` in a `Response` { #using-the-jsonable-encoder-in-a-response }

Because **FastAPI** doesn't make any changes to a `Response` you return, you have to make sure its contents are ready for it.

For example, you cannot put a Pydantic model in a `JSONResponse` without first converting it to a `dict` with all the data types (like `datetime`, `UUID`, etc) converted to JSON-compatible types.

For those cases, you can use the `jsonable_encoder` to convert your data before passing it to a response:

{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}

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

///


docs/en/docs/advanced/response-directly.md::Returning a custom `Response` { #returning-a-custom-response }::L53

# Doc: docs/en/docs/advanced/response-directly.md | Page: Return a Response Directly { #return-a-response-directly } | Section: Returning a custom `Response` { #returning-a-custom-response }
## Returning a custom `Response` { #returning-a-custom-response }

The example above shows all the parts you need, but it's not very useful yet, as you could have just returned the `item` directly, and **FastAPI** would put it in a `JSONResponse` for you, converting it to a `dict`, etc. All that by default.

Now, let's see how you could use that to return a custom response.

Let's say that you want to return an [XML](https://en.wikipedia.org/wiki/XML) response.

You could put your XML content in a string, put that in a `Response`, and return it:

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


docs/en/docs/advanced/response-directly.md::How a Response Model Works { #how-a-response-model-works }::L65

# Doc: docs/en/docs/advanced/response-directly.md | Page: Return a Response Directly { #return-a-response-directly } | Section: How a Response Model Works { #how-a-response-model-works }
## How a Response Model Works { #how-a-response-model-works }

When you declare a [Response Model - Return Type](../tutorial/response-model.md) in a path operation, **FastAPI** will use it to serialize the data to JSON, using Pydantic.

{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}

As that will happen on the Rust side, the performance will be much better than if it was done with regular Python and the `JSONResponse` class.

When using a `response_model` or return type, FastAPI won't use the `jsonable_encoder` to convert the data (which would be slower) nor the `JSONResponse` class.

Instead it takes the JSON bytes generated with Pydantic using the response model (or return type) and returns a `Response` with the right media type for JSON directly (`application/json`).


docs/en/docs/advanced/response-directly.md::Notes { #notes }::L77

# Doc: docs/en/docs/advanced/response-directly.md | Page: Return a Response Directly { #return-a-response-directly } | Section: Notes { #notes }
## Notes { #notes }

When you return a `Response` directly its data is not validated, converted (serialized), or documented automatically.

But you can still document it as described in [Additional Responses in OpenAPI](additional-responses.md).

You can see in later sections how to use/declare these custom `Response`s while still having automatic data conversion, documentation, etc.


docs/en/docs/advanced/response-headers.md::Use a `Response` parameter { #use-a-response-parameter }::L3

# Doc: docs/en/docs/advanced/response-headers.md | Page: Response Headers { #response-headers } | Section: Use a `Response` parameter { #use-a-response-parameter }
## Use a `Response` parameter { #use-a-response-parameter }

You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies).

And then you can set headers in that *temporary* response object.

{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}

And then you can return any object you need, as you normally would (a `dict`, a database model, etc).

And if you declared a `response_model`, it will still be used to filter and convert the object you returned.

**FastAPI** will use that *temporary* response to extract the headers (also cookies and status code), and will put them in the final response that contains the value you returned, filtered by any `response_model`.

You can also declare the `Response` parameter in dependencies, and set headers (and cookies) in them.


docs/en/docs/advanced/response-headers.md::Return a `Response` directly { #return-a-response-directly }::L19

# Doc: docs/en/docs/advanced/response-headers.md | Page: Response Headers { #response-headers } | Section: Return a `Response` directly { #return-a-response-directly }
## Return a `Response` directly { #return-a-response-directly }

You can also add headers when you return a `Response` directly.

Create a response as described in [Return a Response Directly](response-directly.md) and pass the headers as an additional parameter:

{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}

/// note | Technical Details

You could also use `from starlette.responses import Response` or `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.

And as the `Response` can be used frequently to set headers and cookies, **FastAPI** also provides it at `fastapi.Response`.

///


docs/en/docs/advanced/response-headers.md::Custom Headers { #custom-headers }::L37

# Doc: docs/en/docs/advanced/response-headers.md | Page: Response Headers { #response-headers } | Section: Custom Headers { #custom-headers }
## Custom Headers { #custom-headers }

Keep in mind that custom proprietary headers can be added [using the `X-` prefix](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).

But if you have custom headers that you want a client in a browser to be able to see, you need to add them to your CORS configurations (read more in [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), using the parameter `expose_headers` documented in [Starlette's CORS docs](https://www.starlette.dev/middleware/#corsmiddleware).


docs/en/docs/advanced/security/http-basic-auth.md::HTTP Basic Auth { #http-basic-auth }::L1

# Doc: docs/en/docs/advanced/security/http-basic-auth.md | Page: HTTP Basic Auth { #http-basic-auth } | Section: HTTP Basic Auth { #http-basic-auth }
# HTTP Basic Auth { #http-basic-auth }

For the simplest cases, you can use HTTP Basic Auth.

In HTTP Basic Auth, the application expects a header that contains a username and a password.

If it doesn't receive it, it returns an HTTP 401 "Unauthorized" error.

And returns a header `WWW-Authenticate` with a value of `Basic`, and an optional `realm` parameter.

That tells the browser to show the integrated prompt for a username and password.

Then, when you type that username and password, the browser sends them in the header automatically.


docs/en/docs/advanced/security/http-basic-auth.md::Simple HTTP Basic Auth { #simple-http-basic-auth }::L15

# Doc: docs/en/docs/advanced/security/http-basic-auth.md | Page: HTTP Basic Auth { #http-basic-auth } | Section: Simple HTTP Basic Auth { #simple-http-basic-auth }
## Simple HTTP Basic Auth { #simple-http-basic-auth }

* Import `HTTPBasic` and `HTTPBasicCredentials`.
* Create a "`security` scheme" using `HTTPBasic`.
* Use that `security` with a dependency in your *path operation*.
* It returns an object of type `HTTPBasicCredentials`:
    * It contains the `username` and `password` sent.

{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}

When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:

<img src="/img/tutorial/security/image12.png">


docs/en/docs/advanced/security/http-basic-auth.md::Check the username { #check-the-username }::L29

# Doc: docs/en/docs/advanced/security/http-basic-auth.md | Page: HTTP Basic Auth { #http-basic-auth } | Section: Check the username { #check-the-username }
## Check the username { #check-the-username }

Here's a more complete example.

Use a dependency to check if the username and password are correct.

For this, use the Python standard module [`secrets`](https://docs.python.org/3/library/secrets.html) to check the username and password.

`secrets.compare_digest()` needs to take `bytes` or a `str` that only contains ASCII characters (the ones in English), this means it wouldn't work with characters like `á`, as in `Sebastián`.

To handle that, we first convert the `username` and `password` to `bytes` encoding them with UTF-8.

Then we can use `secrets.compare_digest()` to ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`.

{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}

This would be similar to:

```Python
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
    # Return some error
    ...
```

But by using the `secrets.compare_digest()` it will be secure against a type of attacks called "timing attacks".

### Timing Attacks { #timing-attacks }

But what's a "timing attack"?

Let's imagine some attackers are trying to guess the username and password.

And they send a request with a username `johndoe` and a password `love123`.

Then the Python code in your application would be equivalent to something like:

```Python
if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
    ...
```

But right at the moment Python compares the first `j` in `johndoe` to the first `s` in `stanleyjobson`, it will return `False`, because it already knows that those two strings are not the same, thinking that "there's no need to waste more computation comparing the rest of the letters". And your application will say "Incorrect username or password".

But then the attackers try with username `stanleyjobsox` and password `love123`.

And your application code does something like:

```Python
if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
    ...
```

Python will have to compare the whole `stanleyjobso` in both `stanleyjobsox` and `stanleyjobson` before realizing that both strings are not the same. So it will take some extra microseconds to reply back "Incorrect username or password".

#### The time to answer helps the attackers { #the-time-to-answer-helps-the-attackers }

At that point, by noticing that the server took some microseconds longer to send the "Incorrect username or password" response, the attackers will know that they got _something_ right, some of the initial letters were right.

And then they can try again knowing that it's probably something more similar to `stanleyjobsox` than to `johndoe`.

#### A "professional" attack { #a-professional-attack }

Of course, the attackers would not try all this by hand, they would write a program to do it, possibly with thousands or millions of tests per second. And they would get just one extra correct letter at a time.

But doing that, in some minutes or hours the attackers would have guessed the correct username and password, with the "help" of our application, just using the time taken to answer.

#### Fix it with `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest }

But in our code we are actually using `secrets.compare_digest()`.

In short, it will take the same time to compare `stanleyjobsox` to `stanleyjobson` than it takes to compare `johndoe` to `stanleyjobson`. And the same for the password.

That way, using `secrets.compare_digest()` in your application code, it will be safe against this whole range of security attacks.

### Return the error { #return-the-error }

After detecting that the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again:

{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}


docs/en/docs/advanced/security/index.md::Additional Features { #additional-features }::L3

# Doc: docs/en/docs/advanced/security/index.md | Page: Advanced Security { #advanced-security } | Section: Additional Features { #additional-features }
## Additional Features { #additional-features }

There are some extra features to handle security apart from the ones covered in the [Tutorial - User Guide: Security](../../tutorial/security/index.md).

/// tip

The next sections are **not necessarily "advanced"**.

And it's possible that for your use case, the solution is in one of them.

///


docs/en/docs/advanced/security/index.md::Read the Tutorial first { #read-the-tutorial-first }::L15

# Doc: docs/en/docs/advanced/security/index.md | Page: Advanced Security { #advanced-security } | Section: Read the Tutorial first { #read-the-tutorial-first }
## Read the Tutorial first { #read-the-tutorial-first }

The next sections assume you already read the main [Tutorial - User Guide: Security](../../tutorial/security/index.md).

They are all based on the same concepts, but allow some extra functionalities.


docs/en/docs/advanced/security/oauth2-scopes.md::OAuth2 scopes { #oauth2-scopes }::L1

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: OAuth2 scopes { #oauth2-scopes }
# OAuth2 scopes { #oauth2-scopes }

You can use OAuth2 scopes directly with **FastAPI**, they are integrated to work seamlessly.

This would allow you to have a more fine-grained permission system, following the OAuth2 standard, integrated into your OpenAPI application (and the API docs).

OAuth2 with scopes is the mechanism used by many big authentication providers, like Facebook, Google, GitHub, Microsoft, X (Twitter), etc. They use it to provide specific permissions to users and applications.

Every time you "log in with" Facebook, Google, GitHub, Microsoft, X (Twitter), that application is using OAuth2 with scopes.

In this section you will see how to manage authentication and authorization with the same OAuth2 with scopes in your **FastAPI** application.

/// warning

This is a more or less advanced section. If you are just starting, you can skip it.

You don't necessarily need OAuth2 scopes, and you can handle authentication and authorization however you want.

But OAuth2 with scopes can be nicely integrated into your API (with OpenAPI) and your API docs.

Nevertheless, you still enforce those scopes, or any other security/authorization requirement, however you need, in your code.

In many cases, OAuth2 with scopes can be an overkill.

But if you know you need it, or you are curious, keep reading.

///


docs/en/docs/advanced/security/oauth2-scopes.md::OAuth2 scopes and OpenAPI { #oauth2-scopes-and-openapi }::L29

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: OAuth2 scopes and OpenAPI { #oauth2-scopes-and-openapi }
## OAuth2 scopes and OpenAPI { #oauth2-scopes-and-openapi }

The OAuth2 specification defines "scopes" as a list of strings separated by spaces.

The content of each of these strings can have any format, but should not contain spaces.

These scopes represent "permissions".

In OpenAPI (e.g. the API docs), you can define "security schemes".

When one of these security schemes uses OAuth2, you can also declare and use scopes.

Each "scope" is just a string (without spaces).

They are normally used to declare specific security permissions, for example:

* `users:read` or `users:write` are common examples.
* `instagram_basic` is used by Facebook / Instagram.
* `https://www.googleapis.com/auth/drive` is used by Google.

/// note

In OAuth2 a "scope" is just a string that declares a specific permission required.

It doesn't matter if it has other characters like `:` or if it is a URL.

Those details are implementation specific.

For OAuth2 they are just strings.

///


docs/en/docs/advanced/security/oauth2-scopes.md::Global view { #global-view }::L61

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Global view { #global-view }
## Global view { #global-view }

First, let's quickly see the parts that change from the examples in the main **Tutorial - User Guide** for [OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md). Now using OAuth2 scopes:

{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}

Now let's review those changes step by step.


docs/en/docs/advanced/security/oauth2-scopes.md::OAuth2 Security scheme { #oauth2-security-scheme }::L69

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: OAuth2 Security scheme { #oauth2-security-scheme }
## OAuth2 Security scheme { #oauth2-security-scheme }

The first change is that now we are declaring the OAuth2 security scheme with two available scopes, `me` and `items`.

The `scopes` parameter receives a `dict` with each scope as a key and the description as the value:

{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *}

Because we are now declaring those scopes, they will show up in the API docs when you log-in/authorize.

And you will be able to select which scopes you want to give access to: `me` and `items`.

This is the same mechanism used when you give permissions while logging in with Facebook, Google, GitHub, etc:

<img src="/img/tutorial/security/image11.png">


docs/en/docs/advanced/security/oauth2-scopes.md::JWT token with scopes { #jwt-token-with-scopes }::L85

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: JWT token with scopes { #jwt-token-with-scopes }
## JWT token with scopes { #jwt-token-with-scopes }

Now, modify the token *path operation* to return the scopes requested.

We are still using the same `OAuth2PasswordRequestForm`. It includes a property `scopes` with a `list` of `str`, with each scope it received in the request.

And we return the scopes as part of the JWT token.

/// danger

For simplicity, here we are just adding the scopes received directly to the token.

But in your application, for security, you should make sure you only add the scopes that the user is actually able to have, or the ones you have predefined.

///

{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *}


docs/en/docs/advanced/security/oauth2-scopes.md::Declare scopes in *path operations* and dependencies { #declare-scopes-in-path-operations-and-dependencies }::L103

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Declare scopes in *path operations* and dependencies { #declare-scopes-in-path-operations-and-dependencies }
## Declare scopes in *path operations* and dependencies { #declare-scopes-in-path-operations-and-dependencies }

Now we declare that the *path operation* for `/users/me/items/` requires the scope `items`.

For this, we import and use `Security` from `fastapi`.

You can use `Security` to declare dependencies (just like `Depends`), but `Security` also receives a parameter `scopes` with a list of scopes (strings).

In this case, we pass a dependency function `get_current_active_user` to `Security` (the same way we would do with `Depends`).

But we also pass a `list` of scopes, in this case with just one scope: `items` (it could have more).

And the dependency function `get_current_active_user` can also declare sub-dependencies, not only with `Depends` but also with `Security`. Declaring its own sub-dependency function (`get_current_user`), and more scope requirements.

In this case, it requires the scope `me` (it could require more than one scope).

/// note

You don't necessarily need to add different scopes in different places.

We are doing it here to demonstrate how **FastAPI** handles scopes declared at different levels.

///

{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}

/// note | Technical Details

`Security` is actually a subclass of `Depends`, and it has just one extra parameter that we'll see later.

But by using `Security` instead of `Depends`, **FastAPI** will know that it can declare security scopes, use them internally, and document the API with OpenAPI.

But when you import `Query`, `Path`, `Depends`, `Security` and others from `fastapi`, those are actually functions that return special classes.

///


docs/en/docs/advanced/security/oauth2-scopes.md::Use `SecurityScopes` { #use-securityscopes }::L139

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Use `SecurityScopes` { #use-securityscopes }
## Use `SecurityScopes` { #use-securityscopes }

Now update the dependency `get_current_user`.

This is the one used by the dependencies above.

Here's where we are using the same OAuth2 scheme we created before, declaring it as a dependency: `oauth2_scheme`.

Because this dependency function doesn't have any scope requirements itself, we can use `Depends` with `oauth2_scheme`, we don't have to use `Security` when we don't need to specify security scopes.

We also declare a special parameter of type `SecurityScopes`, imported from `fastapi.security`.

This `SecurityScopes` class is similar to `Request` (`Request` was used to get the request object directly).

{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}


docs/en/docs/advanced/security/oauth2-scopes.md::Use the `scopes` { #use-the-scopes }::L155

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Use the `scopes` { #use-the-scopes }
## Use the `scopes` { #use-the-scopes }

The parameter `security_scopes` will be of type `SecurityScopes`.

It will have a property `scopes` with a list containing all the scopes required by itself and all the dependencies that use this as a sub-dependency. That means, all the "dependants"... this might sound confusing, it is explained again later below.

The `security_scopes` object (of class `SecurityScopes`) also provides a `scope_str` attribute with a single string, containing those scopes separated by spaces (we are going to use it).

We create an `HTTPException` that we can reuse (`raise`) later at several points.

In this exception, we include the scopes required (if any) as a string separated by spaces (using `scope_str`). We put that string containing the scopes in the `WWW-Authenticate` header (this is part of the spec).

{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *}


docs/en/docs/advanced/security/oauth2-scopes.md::Verify the `username` and data shape { #verify-the-username-and-data-shape }::L169

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Verify the `username` and data shape { #verify-the-username-and-data-shape }
## Verify the `username` and data shape { #verify-the-username-and-data-shape }

We verify that we get a `username`, and extract the scopes.

And then we validate that data with the Pydantic model (catching the `ValidationError` exception), and if we get an error reading the JWT token or validating the data with Pydantic, we raise the `HTTPException` we created before.

For that, we update the Pydantic model `TokenData` with a new property `scopes`.

By validating the data with Pydantic we can make sure that we have, for example, exactly a `list` of `str` with the scopes and a `str` with the `username`.

Instead of, for example, a `dict`, or something else, as it could break the application at some point later, making it a security risk.

We also verify that we have a user with that username, and if not, we raise that same exception we created before.

{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *}


docs/en/docs/advanced/security/oauth2-scopes.md::Verify the `scopes` { #verify-the-scopes }::L185

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Verify the `scopes` { #verify-the-scopes }
## Verify the `scopes` { #verify-the-scopes }

We now verify that all the scopes required, by this dependency and all the dependants (including *path operations*), are included in the scopes provided in the token received, otherwise raise an `HTTPException`.

For this, we use `security_scopes.scopes`, that contains a `list` with all these scopes as `str`.

{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *}


docs/en/docs/advanced/security/oauth2-scopes.md::Dependency tree and scopes { #dependency-tree-and-scopes }::L193

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Dependency tree and scopes { #dependency-tree-and-scopes }
## Dependency tree and scopes { #dependency-tree-and-scopes }

Let's review again this dependency tree and the scopes.

As the `get_current_active_user` dependency has `get_current_user` as a sub-dependency, the scope `"me"` declared at `get_current_active_user` will be included in the list of required scopes in the `security_scopes.scopes` passed to `get_current_user`.

The *path operation* itself also declares a scope, `"items"`, so this will also be in the list of `security_scopes.scopes` passed to `get_current_user`.

Here's what the hierarchy of dependencies and scopes looks like:

* The *path operation* `read_own_items` has:
    * Required scopes `["items"]` with the dependency:
    * `get_current_active_user`:
        *  The dependency function `get_current_active_user` has:
            * Required scopes `["me"]` with the dependency:
            * `get_current_user`:
                * The dependency function `get_current_user` has:
                    * No scopes required by itself.
                    * A dependency using `oauth2_scheme`.
                    * A `security_scopes` parameter of type `SecurityScopes`:
                        * This `security_scopes` parameter has a property `scopes` with a `list` containing all these scopes declared above, so:
                            * `security_scopes.scopes` will contain `["me", "items"]` for the *path operation* `read_own_items`.
                            * `security_scopes.scopes` will contain `["me"]` for the *path operation* `read_users_me`, because it is declared in the dependency `get_current_active_user`.
                            * `security_scopes.scopes` will contain `[]` (nothing) for the *path operation* `read_system_status`, because it didn't declare any `Security` with `scopes`, and its dependency, `get_current_user`, doesn't declare any `scopes` either.

/// tip

The important and "magic" thing here is that `get_current_user` will have a different list of `scopes` to check for each *path operation*.

All depending on the `scopes` declared in each *path operation* and each dependency in the dependency tree for that specific *path operation*.

///


docs/en/docs/advanced/security/oauth2-scopes.md::More details about `SecurityScopes` { #more-details-about-securityscopes }::L226

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: More details about `SecurityScopes` { #more-details-about-securityscopes }
## More details about `SecurityScopes` { #more-details-about-securityscopes }

You can use `SecurityScopes` at any point, and in multiple places, it doesn't have to be at the "root" dependency.

It will always have the security scopes declared in the current `Security` dependencies and all the dependants for **that specific** *path operation* and **that specific** dependency tree.

Because the `SecurityScopes` will have all the scopes declared by dependants, you can use it to verify that a token has the required scopes in a central dependency function, and then declare different scope requirements in different *path operations*.

They will be checked independently for each *path operation*.


docs/en/docs/advanced/security/oauth2-scopes.md::Check it { #check-it }::L236

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: Check it { #check-it }
## Check it { #check-it }

If you open the API docs, you can authenticate and specify which scopes you want to authorize.

<img src="/img/tutorial/security/image11.png">

If you don't select any scope, you will be "authenticated", but when you try to access `/users/me/` or `/users/me/items/` you will get an error saying that you don't have enough permissions. You will still be able to access `/status/`.

And if you select the scope `me` but not the scope `items`, you will be able to access `/users/me/` but not `/users/me/items/`.

That's what would happen to a third party application that tried to access one of these *path operations* with a token provided by a user, depending on how many permissions the user gave the application.


docs/en/docs/advanced/security/oauth2-scopes.md::About third party integrations { #about-third-party-integrations }::L248

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: About third party integrations { #about-third-party-integrations }
## About third party integrations { #about-third-party-integrations }

In this example we are using the OAuth2 "password" flow.

This is appropriate when we are logging in to our own application, probably with our own frontend.

Because we can trust it to receive the `username` and `password`, as we control it.

But if you are building an OAuth2 application that others would connect to (i.e., if you are building an authentication provider equivalent to Facebook, Google, GitHub, etc.) you should use one of the other flows.

The most common is the implicit flow.

The most secure is the code flow, but it's more complex to implement as it requires more steps. As it is more complex, many providers end up suggesting the implicit flow.

/// note

It's common that each authentication provider names their flows in a different way, to make it part of their brand.

But in the end, they are implementing the same OAuth2 standard.

///

**FastAPI** includes utilities for all these OAuth2 authentication flows in `fastapi.security.oauth2`.


docs/en/docs/advanced/security/oauth2-scopes.md::`Security` in decorator `dependencies` { #security-in-decorator-dependencies }::L272

# Doc: docs/en/docs/advanced/security/oauth2-scopes.md | Page: OAuth2 scopes { #oauth2-scopes } | Section: `Security` in decorator `dependencies` { #security-in-decorator-dependencies }
## `Security` in decorator `dependencies` { #security-in-decorator-dependencies }

The same way you can define a `list` of `Depends` in the decorator's `dependencies` parameter (as explained in [Dependencies in path operation decorators](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md)), you could also use `Security` with `scopes` there.


docs/en/docs/advanced/settings.md::Settings and Environment Variables { #settings-and-environment-variables }::L1

# Doc: docs/en/docs/advanced/settings.md | Page: Settings and Environment Variables { #settings-and-environment-variables } | Section: Settings and Environment Variables { #settings-and-environment-variables }
# Settings and Environment Variables { #settings-and-environment-variables }

In many cases your application could need some external settings or configurations, for example secret keys, database credentials, credentials for email services, etc.

Most of these settings are variable (can change), like database URLs. And many could be sensitive, like secrets.

For this reason it's common to provide them in environment variables that are read by the application.

/// tip

To understand environment variables you can read [Environment Variables](../environment-variables.md).

///


docs/en/docs/advanced/settings.md::Types and validation { #types-and-validation }::L15

# Doc: docs/en/docs/advanced/settings.md | Page: Settings and Environment Variables { #settings-and-environment-variables } | Section: Types and validation { #types-and-validation }
## Types and validation { #types-and-validation }

These environment variables can only handle text strings, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, such as Linux, Windows, and macOS).

That means that any value read in Python from an environment variable will be a `str`, and any conversion to a different type or any validation has to be done in code.


docs/en/docs/advanced/settings.md::Pydantic `Settings` { #pydantic-settings }::L21

# Doc: docs/en/docs/advanced/settings.md | Page: Settings and Environment Variables { #settings-and-environment-variables } | Section: Pydantic `Settings` { #pydantic-settings }
## Pydantic `Settings` { #pydantic-settings }

Fortunately, Pydantic provides a great utility to handle these settings coming from environment variables with [Pydantic: Settings management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).

### Install `pydantic-settings` { #install-pydantic-settings }

First, make sure you create your [virtual environment](../virtual-environments.md), activate it, and then install the `pydantic-settings` package:

```console
$ pip install pydantic-settings
---> 100%
```

It also comes included when you install the `all` extras with:

```console
$ pip install "fastapi[all]"
---> 100%
```

### Create the `Settings` object { #create-the-settings-object }

Import `BaseSettings` from Pydantic and create a sub-class, very much like with a Pydantic model.

The same way as with Pydantic models, you declare class attributes with type annotations, and possibly default values.

You can use all the same validation features and tools you use for Pydantic models, like different data types and additional validations with `Field()`.

{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}

/// tip

If you want something quick to copy and paste, don't use this example, use the last one below.

///

Then, when you create an instance of that `Settings` class (in this case, in the `settings` object), Pydantic will read the environment variables in a case-insensitive way, so, an upper-case variable `APP_NAME` will still be read for the attribute `app_name`.

Next it will convert and validate the data. So, when you use that `settings` object, you will have data of the types you declared (e.g. `items_per_user` will be an `int`).

### Use the `settings` { #use-the-settings }

Then you can use the new `settings` object in your application:

{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}

### Run the server { #run-the-server }

Next, you would run the server passing the configurations as environment variables, for example you could set an `ADMIN_EMAIL` and `APP_NAME` with:

```console
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py

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

/// tip

To set multiple env vars for a single command just separate them with a space, and put them all before the command.

///

And then the `admin_email` setting would be set to `"deadpool@example.com"`.

The `app_name` would be `"ChimichangApp"`.

And the `items_per_user` would keep its default value of `50`.


docs/en/docs/advanced/settings.md::Settings in another module { #settings-in-another-module }::L101

# Doc: docs/en/docs/advanced/settings.md | Page: Settings and Environment Variables { #settings-and-environment-variables } | Section: Settings in another module { #settings-in-another-module }
## Settings in another module { #settings-in-another-module }

You could put those settings in another module file as you saw in [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md).

For example, you could have a file `config.py` with:

{* ../../docs_src/settings/app01_py310/config.py *}

And then use it in a file `main.py`:

{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}

/// tip

You would also need a file `__init__.py` as you saw in [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md).

///