docs/en/docs/tutorial/query-param-models.md::Forbid Extra Query Parameters { #forbid-extra-query-parameters }::L29

# Doc: docs/en/docs/tutorial/query-param-models.md | Page: Query Parameter Models { #query-parameter-models } | Section: Forbid Extra Query Parameters { #forbid-extra-query-parameters }
## Forbid Extra Query Parameters { #forbid-extra-query-parameters }

In some special use cases (probably not very common), you might want to **restrict** the query parameters that you want to receive.

You can use Pydantic's model configuration to `forbid` any `extra` fields:

{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}

If a client tries to send some **extra** data in the **query parameters**, they will receive an **error** response.

For example, if the client tries to send a `tool` query parameter with a value of `plumbus`, like:

```http
https://example.com/items/?limit=10&tool=plumbus
```

They will receive an **error** response telling them that the query parameter `tool` is not allowed:

```json
{
    "detail": [
        {
            "type": "extra_forbidden",
            "loc": ["query", "tool"],
            "msg": "Extra inputs are not permitted",
            "input": "plumbus"
        }
    ]
}
```


docs/en/docs/tutorial/query-param-models.md::Summary { #summary }::L60

# Doc: docs/en/docs/tutorial/query-param-models.md | Page: Query Parameter Models { #query-parameter-models } | Section: Summary { #summary }
## Summary { #summary }

You can use **Pydantic models** to declare **query parameters** in **FastAPI**. 😎

/// tip

Spoiler alert: you can also use Pydantic models to declare cookies and headers, but you will read about that later in the tutorial. 🤫

///


docs/en/docs/tutorial/query-params-str-validations.md::Query Parameters and String Validations { #query-parameters-and-string-validations }::L1

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Query Parameters and String Validations { #query-parameters-and-string-validations }
# Query Parameters and String Validations { #query-parameters-and-string-validations }

**FastAPI** allows you to declare additional information and validation for your parameters.

Let's take this application as example:

{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}

The query parameter `q` is of type `str | None`, that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.

/// note

FastAPI will know that the value of `q` is not required because of the default value `= None`.

Having `str | None` will allow your editor to give you better support and detect errors.

///


docs/en/docs/tutorial/query-params-str-validations.md::Additional validation { #additional-validation }::L19

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Additional validation { #additional-validation }
## Additional validation { #additional-validation }

We are going to enforce that even though `q` is optional, whenever it is provided, **its length doesn't exceed 50 characters**.

### Import `Query` and `Annotated` { #import-query-and-annotated }

To achieve that, first import:

* `Query` from `fastapi`
* `Annotated` from `typing`

{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}

/// note

FastAPI added support for `Annotated` (and started recommending it) in version 0.95.0.

If you have an older version, you would get errors when trying to use `Annotated`.

Make sure you [Upgrade the FastAPI version](../deployment/versions.md#upgrading-the-fastapi-versions) to at least 0.95.1 before using `Annotated`.

///


docs/en/docs/tutorial/query-params-str-validations.md::Use `Annotated` in the type for the `q` parameter { #use-annotated-in-the-type-for-the-q-parameter }::L42

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Use `Annotated` in the type for the `q` parameter { #use-annotated-in-the-type-for-the-q-parameter }
## Use `Annotated` in the type for the `q` parameter { #use-annotated-in-the-type-for-the-q-parameter }

Remember I told you before that `Annotated` can be used to add metadata to your parameters in the [Python Types Intro](../python-types.md#type-hints-with-metadata-annotations)?

Now it's the time to use it with FastAPI. 🚀

We had this type annotation:

```Python
q: str | None = None
```

What we will do is wrap that with `Annotated`, so it becomes:

```Python
q: Annotated[str | None] = None
```

Both of those versions mean the same thing, `q` is a parameter that can be a `str` or `None`, and by default, it is `None`.

Now let's jump to the fun stuff. 🎉


docs/en/docs/tutorial/query-params-str-validations.md::Add `Query` to `Annotated` in the `q` parameter { #add-query-to-annotated-in-the-q-parameter }::L64

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Add `Query` to `Annotated` in the `q` parameter { #add-query-to-annotated-in-the-q-parameter }
## Add `Query` to `Annotated` in the `q` parameter { #add-query-to-annotated-in-the-q-parameter }

Now that we have this `Annotated` where we can put more information (in this case some additional validation), add `Query` inside of `Annotated`, and set the parameter `max_length` to `50`:

{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}

Notice that the default value is still `None`, so the parameter is still optional.

But now, having `Query(max_length=50)` inside of `Annotated`, we are telling FastAPI that we want it to have **additional validation** for this value, we want it to have maximum 50 characters. 😎

/// tip

Here we are using `Query()` because this is a **query parameter**. Later we will see others like `Path()`, `Body()`, `Header()`, and `Cookie()`, that also accept the same arguments as `Query()`.

///

FastAPI will now:

* **Validate** the data making sure that the max length is 50 characters
* Show a **clear error** for the client when the data is not valid
* **Document** the parameter in the OpenAPI schema *path operation* (so it will show up in the **automatic docs UI**)


docs/en/docs/tutorial/query-params-str-validations.md::Alternative (old): `Query` as the default value { #alternative-old-query-as-the-default-value }::L86

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Alternative (old): `Query` as the default value { #alternative-old-query-as-the-default-value }
## Alternative (old): `Query` as the default value { #alternative-old-query-as-the-default-value }

Previous versions of FastAPI (before <dfn title="before 2023-03">0.95.0</dfn>) required you to use `Query` as the default value of your parameter, instead of putting it in `Annotated`, there's a high chance that you will see code using it around, so I'll explain it to you.

/// tip

For new code and whenever possible, use `Annotated` as explained above. There are multiple advantages (explained below) and no disadvantages. 🍰

///

This is how you would use `Query()` as the default value of your function parameter, setting the parameter `max_length` to 50:

{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}

As in this case (without using `Annotated`) we have to replace the default value `None` in the function with `Query()`, we now need to set the default value with the parameter `Query(default=None)`, it serves the same purpose of defining that default value (at least for FastAPI).

So:

```Python
q: str | None = Query(default=None)
```

...makes the parameter optional, with a default value of `None`, the same as:

```Python
q: str | None = None
```

But the `Query` version declares it explicitly as being a query parameter.

Then, we can pass more parameters to `Query`. In this case, the `max_length` parameter that applies to strings:

```Python
q: str | None = Query(default=None, max_length=50)
```

This will validate the data, show a clear error when the data is not valid, and document the parameter in the OpenAPI schema *path operation*.

### `Query` as the default value or in `Annotated` { #query-as-the-default-value-or-in-annotated }

Keep in mind that when using `Query` inside of `Annotated` you cannot use the `default` parameter for `Query`.

Instead, use the actual default value of the function parameter. Otherwise, it would be inconsistent.

For example, this is not allowed:

```Python
q: Annotated[str, Query(default="rick")] = "morty"
```

...because it's not clear if the default value should be `"rick"` or `"morty"`.

So, you would use (preferably):

```Python
q: Annotated[str, Query()] = "rick"
```

...or in older code bases you will find:

```Python
q: str = Query(default="rick")
```

### Advantages of `Annotated` { #advantages-of-annotated }

**Using `Annotated` is recommended** instead of the default value in function parameters, it is **better** for multiple reasons. 🤓

The **default** value of the **function parameter** is the **actual default** value, that's more intuitive with Python in general. 😌

You could **call** that same function in **other places** without FastAPI, and it would **work as expected**. If there's a **required** parameter (without a default value), your **editor** will let you know with an error, **Python** will also complain if you run it without passing the required parameter.

When you don't use `Annotated` and instead use the **(old) default value style**, if you call that function without FastAPI in **other places**, you have to **remember** to pass the arguments to the function for it to work correctly, otherwise the values will be different from what you expect (e.g. `QueryInfo` or something similar instead of `str`). And your editor won't complain, and Python won't complain running that function, only when the operations inside error out.

Because `Annotated` can have more than one metadata annotation, you could now even use the same function with other tools, like [Typer](https://typer.tiangolo.com/). 🚀


docs/en/docs/tutorial/query-params-str-validations.md::Add more validations { #add-more-validations }::L163

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Add more validations { #add-more-validations }
## Add more validations { #add-more-validations }

You can also add a parameter `min_length`:

{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}


docs/en/docs/tutorial/query-params-str-validations.md::Add regular expressions { #add-regular-expressions }::L169

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Add regular expressions { #add-regular-expressions }
## Add regular expressions { #add-regular-expressions }

You can define a <dfn title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</dfn> `pattern` that the parameter should match:

{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}

This specific regular expression pattern checks that the received parameter value:

* `^`: starts with the following characters, doesn't have characters before.
* `fixedquery`: has the exact value `fixedquery`.
* `$`: ends there, doesn't have any more characters after `fixedquery`.

If you feel lost with all these **"regular expression"** ideas, don't worry. They are a hard topic for many people. You can still do a lot of stuff without needing regular expressions yet.

Now you know that whenever you need them you can use them in **FastAPI**.


docs/en/docs/tutorial/query-params-str-validations.md::Default values { #default-values }::L185

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Default values { #default-values }
## Default values { #default-values }

You can, of course, use default values other than `None`.

Let's say that you want to declare the `q` query parameter to have a `min_length` of `3`, and to have a default value of `"fixedquery"`:

{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}

/// note

Having a default value of any type, including `None`, makes the parameter optional (not required).

///


docs/en/docs/tutorial/query-params-str-validations.md::Required parameters { #required-parameters }::L199

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Required parameters { #required-parameters }
## Required parameters { #required-parameters }

When we don't need to declare more validations or metadata, we can make the `q` query parameter required just by not declaring a default value, like:

```Python
q: str
```

instead of:

```Python
q: str | None = None
```

But we are now declaring it with `Query`, for example like:

```Python
q: Annotated[str | None, Query(min_length=3)] = None
```

So, when you need to declare a value as required while using `Query`, you can simply not declare a default value:

{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}

### Required, can be `None` { #required-can-be-none }

You can declare that a parameter can accept `None`, but that it's still required. This would force clients to send a value, even if the value is `None`.

To do that, you can declare that `None` is a valid type but simply do not declare a default value:

{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}


docs/en/docs/tutorial/query-params-str-validations.md::Query parameter list / multiple values { #query-parameter-list-multiple-values }::L231

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Query parameter list / multiple values { #query-parameter-list-multiple-values }
## Query parameter list / multiple values { #query-parameter-list-multiple-values }

When you define a query parameter explicitly with `Query` you can also declare it to receive a list of values, or said in another way, to receive multiple values.

For example, to declare a query parameter `q` that can appear multiple times in the URL, you can write:

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

Then, with a URL like:

```
http://localhost:8000/items/?q=foo&q=bar
```

you would receive the multiple `q` *query parameters'* values (`foo` and `bar`) in a Python `list` inside your *path operation function*, in the *function parameter* `q`.

So, the response to that URL would be:

```JSON
{
  "q": [
    "foo",
    "bar"
  ]
}
```

/// tip

To declare a query parameter with a type of `list`, like in the example above, you need to explicitly use `Query`, otherwise it would be interpreted as a request body.

///

The interactive API docs will update accordingly, to allow multiple values:

<img src="/img/tutorial/query-params-str-validations/image02.png">

### Query parameter list / multiple values with defaults { #query-parameter-list-multiple-values-with-defaults }

You can also define a default `list` of values if none are provided:

{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}

If you go to:

```
http://localhost:8000/items/
```

the default of `q` will be: `["foo", "bar"]` and your response will be:

```JSON
{
  "q": [
    "foo",
    "bar"
  ]
}
```

#### Using just `list` { #using-just-list }

You can also use `list` directly instead of `list[str]`:

{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}

/// note

Keep in mind that in this case, FastAPI won't check the contents of the list.

For example, `list[int]` would check (and document) that the contents of the list are integers. But `list` alone wouldn't.

///


docs/en/docs/tutorial/query-params-str-validations.md::Declare more metadata { #declare-more-metadata }::L305

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Declare more metadata { #declare-more-metadata }
## Declare more metadata { #declare-more-metadata }

You can add more information about the parameter.

That information will be included in the generated OpenAPI and used by the documentation user interfaces and external tools.

/// note

Keep in mind that different tools might have different levels of OpenAPI support.

Some of them might not show all the extra information declared yet, although in most of the cases, the missing feature is already planned for development.

///

You can add a `title`:

{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}

And a `description`:

{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}


docs/en/docs/tutorial/query-params-str-validations.md::Alias parameters { #alias-parameters }::L327

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Alias parameters { #alias-parameters }
## Alias parameters { #alias-parameters }

Imagine that you want the parameter to be `item-query`.

Like in:

```
http://127.0.0.1:8000/items/?item-query=foobaritems
```

But `item-query` is not a valid Python variable name.

The closest would be `item_query`.

But you still need it to be exactly `item-query`...

Then you can declare an `alias`, and that alias is what will be used to find the parameter value:

{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}


docs/en/docs/tutorial/query-params-str-validations.md::Deprecating parameters { #deprecating-parameters }::L347

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Deprecating parameters { #deprecating-parameters }
## Deprecating parameters { #deprecating-parameters }

Now let's say you don't like this parameter anymore.

You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <dfn title="obsolete, recommended not to use it">deprecated</dfn>.

Then pass the parameter `deprecated=True` to `Query`:

{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}

The docs will show it like this:

<img src="/img/tutorial/query-params-str-validations/image01.png">


docs/en/docs/tutorial/query-params-str-validations.md::Exclude parameters from OpenAPI { #exclude-parameters-from-openapi }::L361

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Exclude parameters from OpenAPI { #exclude-parameters-from-openapi }
## Exclude parameters from OpenAPI { #exclude-parameters-from-openapi }

To exclude a query parameter from the generated OpenAPI schema (and thus, from the automatic documentation systems), set the parameter `include_in_schema` of `Query` to `False`:

{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}


docs/en/docs/tutorial/query-params-str-validations.md::Custom Validation { #custom-validation }::L367

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Custom Validation { #custom-validation }
## Custom Validation { #custom-validation }

There could be cases where you need to do some **custom validation** that can't be done with the parameters shown above.

In those cases, you can use a **custom validator function** that is applied after the normal validation (e.g. after validating that the value is a `str`).

You can achieve that using [Pydantic's `AfterValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) inside of `Annotated`.

/// tip

Pydantic also has [`BeforeValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator) and others. 🤓

///

For example, this custom validator checks that the item ID starts with `isbn-` for an ISBN book number or with `imdb-` for an IMDB movie URL ID:

{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}

/// note

This is available with Pydantic version 2 or above. 😎

///

/// tip

If you need to do any type of validation that requires communicating with any **external component**, like a database or another API, you should instead use **FastAPI Dependencies**, you will learn about them later.

These custom validators are for things that can be checked with **only** the **same data** provided in the request.

///

### Understand that Code { #understand-that-code }

The important point is just using **`AfterValidator` with a function inside `Annotated`**. Feel free to skip this part. 🤸

---

But if you're curious about this specific code example and you're still entertained, here are some extra details.

#### String with `value.startswith()` { #string-with-value-startswith }

Did you notice? A string using `value.startswith()` can take a tuple, and it will check each value in the tuple:

{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}

#### A Random Item { #a-random-item }

With `data.items()` we get an <dfn title="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</dfn> with tuples containing the key and value for each dictionary item.

We convert this iterable object into a proper `list` with `list(data.items())`.

Then with `random.choice()` we can get a **random value** from the list, so, we get a tuple with `(id, name)`. It will be something like `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.

Then we **assign those two values** of the tuple to the variables `id` and `name`.

So, if the user didn't provide an item ID, they will still receive a random suggestion.

...we do all this in a **single simple line**. 🤯 Don't you love Python? 🐍

{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}


docs/en/docs/tutorial/query-params-str-validations.md::Recap { #recap }::L429

# Doc: docs/en/docs/tutorial/query-params-str-validations.md | Page: Query Parameters and String Validations { #query-parameters-and-string-validations } | Section: Recap { #recap }
## Recap { #recap }

You can declare additional validations and metadata for your parameters.

Generic validations and metadata:

* `alias`
* `title`
* `description`
* `deprecated`

Validations specific for strings:

* `min_length`
* `max_length`
* `pattern`

Custom validations using `AfterValidator`.

In these examples you saw how to declare validations for `str` values.

See the next chapters to learn how to declare validations for other types, like numbers.


docs/en/docs/tutorial/query-params.md::Query Parameters { #query-parameters }::L1

# Doc: docs/en/docs/tutorial/query-params.md | Page: Query Parameters { #query-parameters } | Section: Query Parameters { #query-parameters }
# Query Parameters { #query-parameters }

When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters.

{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}

The query is the set of key-value pairs that go after the `?` in a URL, separated by `&` characters.

For example, in the URL:

```
http://127.0.0.1:8000/items/?skip=0&limit=10
```

...the query parameters are:

* `skip`: with a value of `0`
* `limit`: with a value of `10`

As they are part of the URL, they are "naturally" strings.

But when you declare them with Python types (in the example above, as `int`), they are converted to that type and validated against it.

All the same processes that apply to path parameters also apply to query parameters:

* Editor support (obviously)
* Data <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>
* Data validation
* Automatic documentation


docs/en/docs/tutorial/query-params.md::Defaults { #defaults }::L31

# Doc: docs/en/docs/tutorial/query-params.md | Page: Query Parameters { #query-parameters } | Section: Defaults { #defaults }
## Defaults { #defaults }

As query parameters are not a fixed part of a path, they can be optional and can have default values.

In the example above they have default values of `skip=0` and `limit=10`.

So, going to the URL:

```
http://127.0.0.1:8000/items/
```

would be the same as going to:

```
http://127.0.0.1:8000/items/?skip=0&limit=10
```

But if you go to, for example:

```
http://127.0.0.1:8000/items/?skip=20
```

The parameter values in your function will be:

* `skip=20`: because you set it in the URL
* `limit=10`: because that was the default value


docs/en/docs/tutorial/query-params.md::Optional parameters { #optional-parameters }::L60

# Doc: docs/en/docs/tutorial/query-params.md | Page: Query Parameters { #query-parameters } | Section: Optional parameters { #optional-parameters }
## Optional parameters { #optional-parameters }

The same way, you can declare optional query parameters, by setting their default to `None`:

{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}

In this case, the function parameter `q` will be optional, and will be `None` by default.

/// tip

Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter.

///


docs/en/docs/tutorial/query-params.md::Query parameter type conversion { #query-parameter-type-conversion }::L74

# Doc: docs/en/docs/tutorial/query-params.md | Page: Query Parameters { #query-parameters } | Section: Query parameter type conversion { #query-parameter-type-conversion }
## Query parameter type conversion { #query-parameter-type-conversion }

You can also declare `bool` types, and they will be converted:

{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}

In this case, if you go to:

```
http://127.0.0.1:8000/items/foo?short=1
```

or

```
http://127.0.0.1:8000/items/foo?short=True
```

or

```
http://127.0.0.1:8000/items/foo?short=true
```

or

```
http://127.0.0.1:8000/items/foo?short=on
```

or

```
http://127.0.0.1:8000/items/foo?short=yes
```

or any other case variation (uppercase, first letter in uppercase, etc), your function will see the parameter `short` with a `bool` value of `True`. Otherwise as `False`.


docs/en/docs/tutorial/query-params.md::Multiple path and query parameters { #multiple-path-and-query-parameters }::L113

# Doc: docs/en/docs/tutorial/query-params.md | Page: Query Parameters { #query-parameters } | Section: Multiple path and query parameters { #multiple-path-and-query-parameters }
## Multiple path and query parameters { #multiple-path-and-query-parameters }

You can declare multiple path parameters and query parameters at the same time, **FastAPI** knows which is which.

And you don't have to declare them in any specific order.

They will be detected by name:

{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}


docs/en/docs/tutorial/query-params.md::Required query parameters { #required-query-parameters }::L123

# Doc: docs/en/docs/tutorial/query-params.md | Page: Query Parameters { #query-parameters } | Section: Required query parameters { #required-query-parameters }
## Required query parameters { #required-query-parameters }

When you declare a default value for non-path parameters (for now, we have only seen query parameters), then it is not required.

If you don't want to add a specific value but just make it optional, set the default as `None`.

But when you want to make a query parameter required, you can just not declare any default value:

{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}

Here the query parameter `needy` is a required query parameter of type `str`.

If you open in your browser a URL like:

```
http://127.0.0.1:8000/items/foo-item
```

...without adding the required parameter `needy`, you will see an error like:

```JSON
{
  "detail": [
    {
      "type": "missing",
      "loc": [
        "query",
        "needy"
      ],
      "msg": "Field required",
      "input": null
    }
  ]
}
```

As `needy` is a required parameter, you would need to set it in the URL:

```
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
```

...this would work:

```JSON
{
    "item_id": "foo-item",
    "needy": "sooooneedy"
}
```

And of course, you can define some parameters as required, some as having a default value, and some entirely optional:

{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}

In this case, there are 3 query parameters:

* `needy`, a required `str`.
* `skip`, an `int` with a default value of `0`.
* `limit`, an optional `int`.

/// tip

You could also use `Enum`s the same way as with [Path Parameters](path-params.md#predefined-values).

///


docs/en/docs/tutorial/request-files.md::Request Files { #request-files }::L1

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: Request Files { #request-files }
# Request Files { #request-files }

You can define files to be uploaded by the client using `File`.

/// note

To receive uploaded files, first install [`python-multipart`](https://github.com/Kludex/python-multipart).

Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:

```console
$ pip install python-multipart
```

This is because uploaded files are sent as "form data".

///


docs/en/docs/tutorial/request-files.md::Import `File` { #import-file }::L19

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: Import `File` { #import-file }
## Import `File` { #import-file }

Import `File` and `UploadFile` from `fastapi`:

{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}


docs/en/docs/tutorial/request-files.md::Define `File` Parameters { #define-file-parameters }::L25

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: Define `File` Parameters { #define-file-parameters }
## Define `File` Parameters { #define-file-parameters }

Create file parameters the same way you would for `Body` or `Form`:

{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}

/// note

`File` is a class that inherits directly from `Form`.

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

///

/// tip

To declare File bodies, you need to use `File`, because otherwise the parameters would be interpreted as query parameters or body (JSON) parameters.

///

The files will be uploaded as "form data".

If you declare the type of your *path operation function* parameter as `bytes`, **FastAPI** will read the file for you and you will receive the contents as `bytes`.

Keep in mind that this means that the whole contents will be stored in memory. This will work well for small files.

But there are several cases in which you might benefit from using `UploadFile`.


docs/en/docs/tutorial/request-files.md::File Parameters with `UploadFile` { #file-parameters-with-uploadfile }::L53

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: File Parameters with `UploadFile` { #file-parameters-with-uploadfile }
## File Parameters with `UploadFile` { #file-parameters-with-uploadfile }

Define a file parameter with a type of `UploadFile`:

{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}

Using `UploadFile` has several advantages over `bytes`:

* You don't have to use `File()` in the default value of the parameter.
* It uses a "spooled" file:
    * A file stored in memory up to a maximum size limit, and after passing this limit it will be stored on disk.
* This means that it will work well for large files like images, videos, large binaries, etc. without consuming all the memory.
* You can get metadata from the uploaded file.
* It has a [file-like](https://docs.python.org/3/glossary.html#term-file-like-object) `async` interface.
* It exposes an actual Python [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) object that you can pass directly to other libraries that expect a file-like object.

### `UploadFile` { #uploadfile }

`UploadFile` has the following attributes:

* `filename`: A `str` with the original file name that was uploaded (e.g. `myimage.jpg`).
* `content_type`: A `str` with the content type (MIME type / media type) (e.g. `image/jpeg`).
* `file`: A [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) (a [file-like](https://docs.python.org/3/glossary.html#term-file-like-object) object). This is the actual Python file object that you can pass directly to other functions or libraries that expect a "file-like" object.

`UploadFile` has the following `async` methods. They all call the corresponding file methods underneath (using the internal `SpooledTemporaryFile`).

* `write(data)`: Writes `data` (`str` or `bytes`) to the file.
* `read(size)`: Reads `size` (`int`) bytes/characters of the file.
* `seek(offset)`: Goes to the byte position `offset` (`int`) in the file.
    * E.g., `await myfile.seek(0)` would go to the start of the file.
    * This is especially useful if you run `await myfile.read()` once and then need to read the contents again.
* `close()`: Closes the file.

As all these methods are `async` methods, you need to "await" them.

For example, inside of an `async` *path operation function* you can get the contents with:

```Python
contents = await myfile.read()
```

If you are inside of a normal `def` *path operation function*, you can access the `UploadFile.file` directly, for example:

```Python
contents = myfile.file.read()
```

/// note | `async` Technical Details

When you use the `async` methods, **FastAPI** runs the file methods in a threadpool and awaits for them.

///

/// note | Starlette Technical Details

**FastAPI**'s `UploadFile` inherits directly from **Starlette**'s `UploadFile`, but adds some necessary parts to make it compatible with **Pydantic** and the other parts of FastAPI.

///


docs/en/docs/tutorial/request-files.md::What is "Form Data" { #what-is-form-data }::L112

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: What is "Form Data" { #what-is-form-data }
## What is "Form Data" { #what-is-form-data }

The way HTML forms (`<form></form>`) send the data to the server normally uses a "special" encoding for that data, it's different from JSON.

**FastAPI** will make sure to read that data from the right place instead of JSON.

/// note | Technical Details

Data from forms is normally encoded using the "media type" `application/x-www-form-urlencoded` when it doesn't include files.

But when the form includes files, it is encoded as `multipart/form-data`. If you use `File`, **FastAPI** will know it has to get the files from the correct part of the body.

If you want to read more about these encodings and form fields, head to the [<abbr title="Mozilla Developer Network">MDN</abbr> web docs for `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).

///

/// warning

You can declare multiple `File` and `Form` parameters in a *path operation*, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `multipart/form-data` instead of `application/json`.

This is not a limitation of **FastAPI**, it's part of the HTTP protocol.

///


docs/en/docs/tutorial/request-files.md::Optional File Upload { #optional-file-upload }::L136

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: Optional File Upload { #optional-file-upload }
## Optional File Upload { #optional-file-upload }

You can make a file optional by using standard type annotations and setting a default value of `None`:

{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}


docs/en/docs/tutorial/request-files.md::`UploadFile` with Additional Metadata { #uploadfile-with-additional-metadata }::L142

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: `UploadFile` with Additional Metadata { #uploadfile-with-additional-metadata }
## `UploadFile` with Additional Metadata { #uploadfile-with-additional-metadata }

You can also use `File()` with `UploadFile`, for example, to set additional metadata:

{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}


docs/en/docs/tutorial/request-files.md::Multiple File Uploads { #multiple-file-uploads }::L148

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: Multiple File Uploads { #multiple-file-uploads }
## Multiple File Uploads { #multiple-file-uploads }

It's possible to upload several files at the same time.

They would be associated to the same "form field" sent using "form data".

To use that, declare a list of `bytes` or `UploadFile`:

{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}

You will receive, as declared, a `list` of `bytes` or `UploadFile`s.

/// note | Technical Details

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

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

///

### Multiple File Uploads with Additional Metadata { #multiple-file-uploads-with-additional-metadata }

And the same way as before, you can use `File()` to set additional parameters, even for `UploadFile`:

{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}


docs/en/docs/tutorial/request-files.md::Recap { #recap }::L174

# Doc: docs/en/docs/tutorial/request-files.md | Page: Request Files { #request-files } | Section: Recap { #recap }
## Recap { #recap }

Use `File`, `bytes`, and `UploadFile` to declare files to be uploaded in the request, sent as form data.


docs/en/docs/tutorial/request-form-models.md::Form Models { #form-models }::L1

# Doc: docs/en/docs/tutorial/request-form-models.md | Page: Form Models { #form-models } | Section: Form Models { #form-models }
# Form Models { #form-models }

You can use **Pydantic models** to declare **form fields** in FastAPI.

/// note

To use forms, first install [`python-multipart`](https://github.com/Kludex/python-multipart).

Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:

```console
$ pip install python-multipart
```

///

/// note

This is supported since FastAPI version `0.113.0`. 🤓

///


docs/en/docs/tutorial/request-form-models.md::Pydantic Models for Forms { #pydantic-models-for-forms }::L23

# Doc: docs/en/docs/tutorial/request-form-models.md | Page: Form Models { #form-models } | Section: Pydantic Models for Forms { #pydantic-models-for-forms }
## Pydantic Models for Forms { #pydantic-models-for-forms }

You just need to declare a **Pydantic model** with the fields you want to receive as **form fields**, and then declare the parameter as `Form`:

{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}

**FastAPI** will **extract** the data for **each field** from the **form data** in the request and give you the Pydantic model you defined.


docs/en/docs/tutorial/request-form-models.md::Check the Docs { #check-the-docs }::L31

# Doc: docs/en/docs/tutorial/request-form-models.md | Page: Form Models { #form-models } | Section: Check the Docs { #check-the-docs }
## Check the Docs { #check-the-docs }

You can verify it in the docs UI at `/docs`:


docs/en/docs/tutorial/request-form-models.md::Forbid Extra Form Fields { #forbid-extra-form-fields }::L39

# Doc: docs/en/docs/tutorial/request-form-models.md | Page: Form Models { #form-models } | Section: Forbid Extra Form Fields { #forbid-extra-form-fields }
## Forbid Extra Form Fields { #forbid-extra-form-fields }

In some special use cases (probably not very common), you might want to **restrict** the form fields to only those declared in the Pydantic model. And **forbid** any **extra** fields.

/// note

This is supported since FastAPI version `0.114.0`. 🤓

///

You can use Pydantic's model configuration to `forbid` any `extra` fields:

{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}

If a client tries to send some extra data, they will receive an **error** response.

For example, if the client tries to send the form fields:

* `username`: `Rick`
* `password`: `Portal Gun`
* `extra`: `Mr. Poopybutthole`

They will receive an error response telling them that the field `extra` is not allowed:

```json
{
    "detail": [
        {
            "type": "extra_forbidden",
            "loc": ["body", "extra"],
            "msg": "Extra inputs are not permitted",
            "input": "Mr. Poopybutthole"
        }
    ]
}
```


docs/en/docs/tutorial/request-form-models.md::Summary { #summary }::L76

# Doc: docs/en/docs/tutorial/request-form-models.md | Page: Form Models { #form-models } | Section: Summary { #summary }
## Summary { #summary }

You can use Pydantic models to declare form fields in FastAPI. 😎


docs/en/docs/tutorial/request-forms-and-files.md::Request Forms and Files { #request-forms-and-files }::L1

# Doc: docs/en/docs/tutorial/request-forms-and-files.md | Page: Request Forms and Files { #request-forms-and-files } | Section: Request Forms and Files { #request-forms-and-files }
# Request Forms and Files { #request-forms-and-files }

You can define files and form fields at the same time using `File` and `Form`.

/// note

To receive uploaded files and/or form data, first install [`python-multipart`](https://github.com/Kludex/python-multipart).

Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:

```console
$ pip install python-multipart
```

///


docs/en/docs/tutorial/request-forms-and-files.md::Import `File` and `Form` { #import-file-and-form }::L17

# Doc: docs/en/docs/tutorial/request-forms-and-files.md | Page: Request Forms and Files { #request-forms-and-files } | Section: Import `File` and `Form` { #import-file-and-form }
## Import `File` and `Form` { #import-file-and-form }

{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}


docs/en/docs/tutorial/request-forms-and-files.md::Define `File` and `Form` parameters { #define-file-and-form-parameters }::L21

# Doc: docs/en/docs/tutorial/request-forms-and-files.md | Page: Request Forms and Files { #request-forms-and-files } | Section: Define `File` and `Form` parameters { #define-file-and-form-parameters }
## Define `File` and `Form` parameters { #define-file-and-form-parameters }

Create file and form parameters the same way you would for `Body` or `Query`:

{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}

The files and form fields will be uploaded as form data and you will receive the files and form fields.

And you can declare some of the files as `bytes` and some as `UploadFile`.

/// warning

You can declare multiple `File` and `Form` parameters in a *path operation*, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `multipart/form-data` instead of `application/json`.

This is not a limitation of **FastAPI**, it's part of the HTTP protocol.

///


docs/en/docs/tutorial/request-forms-and-files.md::Recap { #recap }::L39

# Doc: docs/en/docs/tutorial/request-forms-and-files.md | Page: Request Forms and Files { #request-forms-and-files } | Section: Recap { #recap }
## Recap { #recap }

Use `File` and `Form` together when you need to receive data and files in the same request.


docs/en/docs/tutorial/request-forms.md::Form Data { #form-data }::L1

# Doc: docs/en/docs/tutorial/request-forms.md | Page: Form Data { #form-data } | Section: Form Data { #form-data }
# Form Data { #form-data }

When you need to receive form fields instead of JSON, you can use `Form`.

/// note

To use forms, first install [`python-multipart`](https://github.com/Kludex/python-multipart).

Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:

```console
$ pip install python-multipart
```

///


docs/en/docs/tutorial/request-forms.md::Import `Form` { #import-form }::L17

# Doc: docs/en/docs/tutorial/request-forms.md | Page: Form Data { #form-data } | Section: Import `Form` { #import-form }
## Import `Form` { #import-form }

Import `Form` from `fastapi`:

{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}


docs/en/docs/tutorial/request-forms.md::Define `Form` parameters { #define-form-parameters }::L23

# Doc: docs/en/docs/tutorial/request-forms.md | Page: Form Data { #form-data } | Section: Define `Form` parameters { #define-form-parameters }
## Define `Form` parameters { #define-form-parameters }

Create form parameters the same way you would for `Body` or `Query`:

{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}

For example, in one of the ways the OAuth2 specification can be used (called "password flow") it is required to send a `username` and `password` as form fields.

The <dfn title="specification">spec</dfn> requires the fields to be exactly named `username` and `password`, and to be sent as form fields, not JSON.

With `Form` you can declare the same configurations as with `Body` (and `Query`, `Path`, `Cookie`), including validation, examples, an alias (e.g. `user-name` instead of `username`), etc.

/// note

`Form` is a class that inherits directly from `Body`.

///

/// tip

To declare form bodies, you need to use `Form` explicitly, because without it the parameters would be interpreted as query parameters or body (JSON) parameters.

///


docs/en/docs/tutorial/request-forms.md::About "Form Fields" { #about-form-fields }::L47

# Doc: docs/en/docs/tutorial/request-forms.md | Page: Form Data { #form-data } | Section: About "Form Fields" { #about-form-fields }
## About "Form Fields" { #about-form-fields }

The way HTML forms (`<form></form>`) send the data to the server normally uses a "special" encoding for that data, it's different from JSON.

**FastAPI** will make sure to read that data from the right place instead of JSON.

/// note | Technical Details

Data from forms is normally encoded using the "media type" `application/x-www-form-urlencoded`.

But when the form includes files, it is encoded as `multipart/form-data`. You'll read about handling files in the next chapter.

If you want to read more about these encodings and form fields, head to the [<abbr title="Mozilla Developer Network">MDN</abbr> web docs for `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).

///

/// warning

You can declare multiple `Form` parameters in a *path operation*, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `application/x-www-form-urlencoded` instead of `application/json`.

This is not a limitation of **FastAPI**, it's part of the HTTP protocol.

///


docs/en/docs/tutorial/request-forms.md::Recap { #recap }::L71

# Doc: docs/en/docs/tutorial/request-forms.md | Page: Form Data { #form-data } | Section: Recap { #recap }
## Recap { #recap }

Use `Form` to declare form data input parameters.


docs/en/docs/tutorial/response-model.md::Response Model - Return Type { #response-model-return-type }::L1

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: Response Model - Return Type { #response-model-return-type }
# Response Model - Return Type { #response-model-return-type }

You can declare the type used for the response by annotating the *path operation function* **return type**.

You can use **type annotations** the same way you would for input data in function **parameters**, you can use Pydantic models, lists, dictionaries, scalar values like integers, booleans, etc.

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

FastAPI will use this return type to:

* **Validate** the returned data.
    * If the data is invalid (e.g. you are missing a field), it means that *your* app code is broken, not returning what it should, and it will return a server error instead of returning incorrect data. This way you and your clients can be certain that they will receive the data and the data shape expected.
* Add a **JSON Schema** for the response, in the OpenAPI *path operation*.
    * This will be used by the **automatic docs**.
    * It will also be used by automatic client code generation tools.
* **Serialize** the returned data to JSON using Pydantic, which is written in **Rust**, so it will be **much faster**.

But most importantly:

* It will **limit and filter** the output data to what is defined in the return type.
    * This is particularly important for **security**, we'll see more of that below.


docs/en/docs/tutorial/response-model.md::`response_model` Parameter { #response-model-parameter }::L23

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: `response_model` Parameter { #response-model-parameter }
## `response_model` Parameter { #response-model-parameter }

There are some cases where you need or want to return some data that is not exactly what the type declares.

For example, you could want to **return a dictionary** or a database object, but **declare it as a Pydantic model**. This way the Pydantic model would do all the data documentation, validation, etc. for the object that you returned (e.g. a dictionary or database object).

If you added the return type annotation, tools and editors would complain with a (correct) error telling you that your function is returning a type (e.g. a dict) that is different from what you declared (e.g. a Pydantic model).

In those cases, you can use the *path operation decorator* parameter `response_model` instead of the return type.

You can use the `response_model` parameter in any of the *path operations*:

* `@app.get()`
* `@app.post()`
* `@app.put()`
* `@app.delete()`
* etc.

{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}

/// note

Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc). Not of your *path operation function*, like all the parameters and body.

///

`response_model` receives the same type you would declare for a Pydantic model field, so, it can be a Pydantic model, but it can also be, e.g. a `list` of Pydantic models, like `List[Item]`.

FastAPI will use this `response_model` to do all the data documentation, validation, etc. and also to **convert and filter the output data** to its type declaration.

/// tip

If you have strict type checks in your editor, mypy, etc, you can declare the function return type as `Any`.

That way you tell the editor that you are intentionally returning anything. But FastAPI will still do the data documentation, validation, filtering, etc. with the `response_model`.

///

### `response_model` Priority { #response-model-priority }

If you declare both a return type and a `response_model`, the `response_model` will take priority and be used by FastAPI.

This way you can add correct type annotations to your functions even when you are returning a type different than the response model, to be used by the editor and tools like mypy. And still you can have FastAPI do the data validation, documentation, etc. using the `response_model`.

You can also use `response_model=None` to disable creating a response model for that *path operation*, you might need to do it if you are adding type annotations for things that are not valid Pydantic fields, you will see an example of that in one of the sections below.


docs/en/docs/tutorial/response-model.md::Return the same input data { #return-the-same-input-data }::L69

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: Return the same input data { #return-the-same-input-data }
## Return the same input data { #return-the-same-input-data }

Here we are declaring a `UserIn` model, it will contain a plaintext password:

{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}

/// note

To use `EmailStr`, first install [`email-validator`](https://github.com/JoshData/python-email-validator).

Make sure you create a [virtual environment](../virtual-environments.md), activate it, and then install it, for example:

```console
$ pip install email-validator
```

or with:

```console
$ pip install "pydantic[email]"
```

///

And we are using this model to declare our input and the same model to declare our output:

{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}

Now, whenever a browser is creating a user with a password, the API will return the same password in the response.

In this case, it might not be a problem, because it's the same user sending the password.

But if we use the same model for another *path operation*, we could be sending our user's passwords to every client.

/// danger

Never store the plain password of a user or send it in a response like this, unless you know all the caveats and you know what you are doing.

///


docs/en/docs/tutorial/response-model.md::Add an output model { #add-an-output-model }::L109

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: Add an output model { #add-an-output-model }
## Add an output model { #add-an-output-model }

We can instead create an input model with the plaintext password and an output model without it:

{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}

Here, even though our *path operation function* is returning the same input user that contains the password:

{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}

...we declared the `response_model` to be our model `UserOut`, that doesn't include the password:

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

So, **FastAPI** will take care of filtering out all the data that is not declared in the output model (using Pydantic).

### `response_model` or Return Type { #response-model-or-return-type }

In this case, because the two models are different, if we annotated the function return type as `UserOut`, the editor and tools would complain that we are returning an invalid type, as those are different classes.

That's why in this example we have to declare it in the `response_model` parameter.

...but continue reading below to see how to overcome that.


docs/en/docs/tutorial/response-model.md::Return Type and Data Filtering { #return-type-and-data-filtering }::L133

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: Return Type and Data Filtering { #return-type-and-data-filtering }
## Return Type and Data Filtering { #return-type-and-data-filtering }

Let's continue from the previous example. We wanted to **annotate the function with one type**, but we wanted to be able to return from the function something that actually includes **more data**.

We want FastAPI to keep **filtering** the data using the response model. So that even though the function returns more data, the response will only include the fields declared in the response model.

In the previous example, because the classes were different, we had to use the `response_model` parameter. But that also means that we don't get the support from the editor and tools checking the function return type.

But in most of the cases where we need to do something like this, we want the model just to **filter/remove** some of the data as in this example.

And in those cases, we can use classes and inheritance to take advantage of function **type annotations** to get better support in the editor and tools, and still get the FastAPI **data filtering**.

{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}

With this, we get tooling support, from editors and mypy as this code is correct in terms of types, but we also get the data filtering from FastAPI.

How does this work? Let's check that out. 🤓

### Type Annotations and Tooling { #type-annotations-and-tooling }

First let's see how editors, mypy and other tools would see this.

`BaseUser` has the base fields. Then `UserIn` inherits from `BaseUser` and adds the `password` field, so, it will include all the fields from both models.

We annotate the function return type as `BaseUser`, but we are actually returning a `UserIn` instance.

The editor, mypy, and other tools won't complain about this because, in typing terms, `UserIn` is a subclass of `BaseUser`, which means it's a *valid* type when what is expected is anything that is a `BaseUser`.

### FastAPI Data Filtering { #fastapi-data-filtering }

Now, for FastAPI, it will see the return type and make sure that what you return includes **only** the fields that are declared in the type.

FastAPI does several things internally with Pydantic to make sure that those same rules of class inheritance are not used for the returned data filtering, otherwise you could end up returning much more data than what you expected.

This way, you can get the best of both worlds: type annotations with **tooling support** and **data filtering**.


docs/en/docs/tutorial/response-model.md::See it in the docs { #see-it-in-the-docs }::L169

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: See it in the docs { #see-it-in-the-docs }
## See it in the docs { #see-it-in-the-docs }

When you see the automatic docs, you can check that the input model and output model will both have their own JSON Schema:

And both models will be used for the interactive API documentation:


docs/en/docs/tutorial/response-model.md::Other Return Type Annotations { #other-return-type-annotations }::L179

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: Other Return Type Annotations { #other-return-type-annotations }
## Other Return Type Annotations { #other-return-type-annotations }

There might be cases where you return something that is not a valid Pydantic field and you annotate it in the function, only to get the support provided by tooling (the editor, mypy, etc).

### Return a Response Directly { #return-a-response-directly }

The most common case would be [returning a Response directly as explained later in the advanced docs](../advanced/response-directly.md).

{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}

This simple case is handled automatically by FastAPI because the return type annotation is the class (or a subclass of) `Response`.

And tools will also be happy because both `RedirectResponse` and `JSONResponse` are subclasses of `Response`, so the type annotation is correct.

### Annotate a Response Subclass { #annotate-a-response-subclass }

You can also use a subclass of `Response` in the type annotation:

{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}

This will also work because `RedirectResponse` is a subclass of `Response`, and FastAPI will automatically handle this simple case.

### Invalid Return Type Annotations { #invalid-return-type-annotations }

But when you return some other arbitrary object that is not a valid Pydantic type (e.g. a database object) and you annotate it like that in the function, FastAPI will try to create a Pydantic response model from that type annotation, and will fail.

The same would happen if you had something like a <dfn title='A union between multiple types means "any of these types".'>union</dfn> between different types where one or more of them are not valid Pydantic types, for example this would fail 💥:

{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}

...this fails because the type annotation is not a Pydantic type and is not just a single `Response` class or subclass, it's a union (any of the two) between a `Response` and a `dict`.

### Disable Response Model { #disable-response-model }

Continuing from the example above, you might not want to have the default data validation, documentation, filtering, etc. that is performed by FastAPI.

But you might want to still keep the return type annotation in the function to get the support from tools like editors and type checkers (e.g. mypy).

In this case, you can disable the response model generation by setting `response_model=None`:

{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}

This will make FastAPI skip the response model generation and that way you can have any return type annotations you need without it affecting your FastAPI application. 🤓


docs/en/docs/tutorial/response-model.md::Response Model encoding parameters { #response-model-encoding-parameters }::L223

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: Response Model encoding parameters { #response-model-encoding-parameters }
## Response Model encoding parameters { #response-model-encoding-parameters }

Your response model could have default values, like:

{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}

* `description: Union[str, None] = None` (or `str | None = None` in Python 3.10) has a default of `None`.
* `tax: float = 10.5` has a default of `10.5`.
* `tags: List[str] = []` has a default of an empty list: `[]`.

but you might want to omit them from the result if they were not actually stored.

For example, if you have models with many optional attributes in a NoSQL database, but you don't want to send very long JSON responses full of default values.

### Use the `response_model_exclude_unset` parameter { #use-the-response-model-exclude-unset-parameter }

You can set the *path operation decorator* parameter `response_model_exclude_unset=True`:

{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}

and those default values won't be included in the response, only the values actually set.

So, if you send a request to that *path operation* for the item with ID `foo`, the response (not including default values) will be:

```JSON
{
    "name": "Foo",
    "price": 50.2
}
```

/// note

You can also use:

* `response_model_exclude_defaults=True`
* `response_model_exclude_none=True`

as described in [the Pydantic docs](https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict) for `exclude_defaults` and `exclude_none`.

///

#### Data with values for fields with defaults { #data-with-values-for-fields-with-defaults }

But if your data has values for the model's fields with default values, like the item with ID `bar`:

```Python hl_lines="3  5"
{
    "name": "Bar",
    "description": "The bartenders",
    "price": 62,
    "tax": 20.2
}
```

they will be included in the response.

#### Data with the same values as the defaults { #data-with-the-same-values-as-the-defaults }

If the data has the same values as the default ones, like the item with ID `baz`:

```Python hl_lines="3  5-6"
{
    "name": "Baz",
    "description": None,
    "price": 50.2,
    "tax": 10.5,
    "tags": []
}
```

FastAPI is smart enough (actually, Pydantic is smart enough) to realize that, even though `description`, `tax`, and `tags` have the same values as the defaults, they were set explicitly (instead of taken from the defaults).

So, they will be included in the JSON response.

/// tip

Notice that the default values can be anything, not only `None`.

They can be a list (`[]`), a `float` of `10.5`, etc.

///

### `response_model_include` and `response_model_exclude` { #response-model-include-and-response-model-exclude }

You can also use the *path operation decorator* parameters `response_model_include` and `response_model_exclude`.

They take a `set` of `str` with the name of the attributes to include (omitting the rest) or to exclude (including the rest).

This can be used as a quick shortcut if you have only one Pydantic model and want to remove some data from the output.

/// tip

But it is still recommended to use the ideas above, using multiple classes, instead of these parameters.

This is because the JSON Schema generated in your app's OpenAPI (and the docs) will still be the one for the complete model, even if you use `response_model_include` or `response_model_exclude` to omit some attributes.

This also applies to `response_model_by_alias` that works similarly.

///

{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}

/// tip

The syntax `{"name", "description"}` creates a `set` with those two values.

It is equivalent to `set(["name", "description"])`.

///

#### Using `list`s instead of `set`s { #using-lists-instead-of-sets }

If you forget to use a `set` and use a `list` or `tuple` instead, FastAPI will still convert it to a `set` and it will work correctly:

{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}


docs/en/docs/tutorial/response-model.md::Recap { #recap }::L340

# Doc: docs/en/docs/tutorial/response-model.md | Page: Response Model - Return Type { #response-model-return-type } | Section: Recap { #recap }
## Recap { #recap }

Use the *path operation decorator's* parameter `response_model` to define response models and especially to ensure private data is filtered out.

Use `response_model_exclude_unset` to return only the values explicitly set.


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

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

The same way you can specify a response model, you can also declare the HTTP status code used for the response with the parameter `status_code` in any of the *path operations*:

* `@app.get()`
* `@app.post()`
* `@app.put()`
* `@app.delete()`
* etc.

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

/// note

Notice that `status_code` is a parameter of the "decorator" method (`get`, `post`, etc). Not of your *path operation function*, like all the parameters and body.

///

The `status_code` parameter receives a number with the HTTP status code.

/// note

`status_code` can alternatively also receive an `IntEnum`, such as Python's [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus).

///

It will:

* Return that status code in the response.
* Document it as such in the OpenAPI schema (and so, in the user interfaces):

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

/// note

Some response codes (see the next section) indicate that the response does not have a body.

FastAPI knows this, and will produce OpenAPI docs that state there is no response body.

///


docs/en/docs/tutorial/response-status-code.md::About HTTP status codes { #about-http-status-codes }::L42

# Doc: docs/en/docs/tutorial/response-status-code.md | Page: Response Status Code { #response-status-code } | Section: About HTTP status codes { #about-http-status-codes }
## About HTTP status codes { #about-http-status-codes }

/// note

If you already know what HTTP status codes are, skip to the next section.

///

In HTTP, you send a numeric status code of 3 digits as part of the response.

These status codes have an associated name to help recognize them, but the important part is the number.

In short:

* `100 - 199` are for "Information". You rarely use them directly.  Responses with these status codes cannot have a body.
* **`200 - 299`** are for "Successful" responses. These are the ones you would use the most.
    * `200` is the default status code, which means everything was "OK".
    * Another example would be `201`, "Created". It is commonly used after creating a new record in the database.
    * A special case is `204`, "No Content".  This response is used when there is no content to return to the client, and so the response must not have a body.
* **`300 - 399`** are for "Redirection".  Responses with these status codes may or may not have a body, except for `304`, "Not Modified", which must not have one.
* **`400 - 499`** are for "Client error" responses. These are the second type you would probably use the most.
    * An example is `404`, for a "Not Found" response.
    * For generic errors from the client, you can just use `400`.
* `500 - 599` are for server errors. You almost never use them directly. When something goes wrong at some part in your application code, or server, it will automatically return one of these status codes.

/// tip

To know more about each status code and which code is for what, check the [<abbr title="Mozilla Developer Network">MDN</abbr> documentation about HTTP status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).

///


docs/en/docs/tutorial/response-status-code.md::Shortcut to remember the names { #shortcut-to-remember-the-names }::L73

# Doc: docs/en/docs/tutorial/response-status-code.md | Page: Response Status Code { #response-status-code } | Section: Shortcut to remember the names { #shortcut-to-remember-the-names }
## Shortcut to remember the names { #shortcut-to-remember-the-names }

Let's see the previous example again:

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

`201` is the status code for "Created".

But you don't have to memorize what each of these codes mean.

You can use the convenience variables from `fastapi.status`.

{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}

They are just a convenience, they hold the same number, but that way you can use the editor's autocomplete to find them:

<img src="/img/tutorial/response-status-code/image02.png">

/// note | Technical Details

You could also use `from starlette import status`.

**FastAPI** provides the same `starlette.status` as `fastapi.status` just as a convenience for you, the developer. But it comes directly from Starlette.

///


docs/en/docs/tutorial/response-status-code.md::Changing the default { #changing-the-default }::L99

# Doc: docs/en/docs/tutorial/response-status-code.md | Page: Response Status Code { #response-status-code } | Section: Changing the default { #changing-the-default }
## Changing the default { #changing-the-default }

Later, in the [Advanced User Guide](../advanced/response-change-status-code.md), you will see how to return a different status code than the default you are declaring here.


docs/en/docs/tutorial/schema-extra-example.md::Declare Request Example Data { #declare-request-example-data }::L1

# Doc: docs/en/docs/tutorial/schema-extra-example.md | Page: Declare Request Example Data { #declare-request-example-data } | Section: Declare Request Example Data { #declare-request-example-data }
# Declare Request Example Data { #declare-request-example-data }

You can declare examples of the data your app can receive.

Here are several ways to do it.


docs/en/docs/tutorial/schema-extra-example.md::Extra JSON Schema data in Pydantic models { #extra-json-schema-data-in-pydantic-models }::L7

# Doc: docs/en/docs/tutorial/schema-extra-example.md | Page: Declare Request Example Data { #declare-request-example-data } | Section: Extra JSON Schema data in Pydantic models { #extra-json-schema-data-in-pydantic-models }
## Extra JSON Schema data in Pydantic models { #extra-json-schema-data-in-pydantic-models }

You can declare `examples` for a Pydantic model that will be added to the generated JSON Schema.

{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}

That extra info will be added as-is to the output **JSON Schema** for that model, and it will be used in the API docs.

You can use the attribute `model_config` that takes a `dict` as described in [Pydantic's docs: Configuration](https://docs.pydantic.dev/latest/api/config/).

You can set `"json_schema_extra"` with a `dict` containing any additional data you would like to show up in the generated JSON Schema, including `examples`.

/// tip

You could use the same technique to extend the JSON Schema and add your own custom extra info.

For example you could use it to add metadata for a frontend user interface, etc.

///

/// note

OpenAPI 3.1.0 (used since FastAPI 0.99.0) added support for `examples`, which is part of the **JSON Schema** standard.

Before that, it only supported the keyword `example` with a single example. That is still supported by OpenAPI 3.1.0, but is deprecated and is not part of the JSON Schema standard. So you are encouraged to migrate `example` to `examples`. 🤓

You can read more at the end of this page.

///


docs/en/docs/tutorial/schema-extra-example.md::`Field` additional arguments { #field-additional-arguments }::L37

# Doc: docs/en/docs/tutorial/schema-extra-example.md | Page: Declare Request Example Data { #declare-request-example-data } | Section: `Field` additional arguments { #field-additional-arguments }
## `Field` additional arguments { #field-additional-arguments }

When using `Field()` with Pydantic models, you can also declare additional `examples`:

{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}


docs/en/docs/tutorial/schema-extra-example.md::`examples` in JSON Schema - OpenAPI { #examples-in-json-schema-openapi }::L43

# Doc: docs/en/docs/tutorial/schema-extra-example.md | Page: Declare Request Example Data { #declare-request-example-data } | Section: `examples` in JSON Schema - OpenAPI { #examples-in-json-schema-openapi }
## `examples` in JSON Schema - OpenAPI { #examples-in-json-schema-openapi }

When using any of:

* `Path()`
* `Query()`
* `Header()`
* `Cookie()`
* `Body()`
* `Form()`
* `File()`

you can also declare a group of `examples` with additional information that will be added to their **JSON Schemas** inside of **OpenAPI**.

### `Body` with `examples` { #body-with-examples }

Here we pass `examples` containing one example of the data expected in `Body()`:

{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *}

### Example in the docs UI { #example-in-the-docs-ui }

With any of the methods above it would look like this in the `/docs`:

### `Body` with multiple `examples` { #body-with-multiple-examples }

You can of course also pass multiple `examples`:

{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *}

When you do this, the examples will be part of the internal **JSON Schema** for that body data.

Nevertheless, at the <dfn title="2023-08-26">time of writing this</dfn>, Swagger UI, the tool in charge of showing the docs UI, doesn't support showing multiple examples for the data in **JSON Schema**. But read below for a workaround.

### OpenAPI-specific `examples` { #openapi-specific-examples }

Since before **JSON Schema** supported `examples`, OpenAPI had support for a different field also called `examples`.

This **OpenAPI-specific** `examples` goes in another section in the OpenAPI specification. It goes in the **details for each *path operation***, not inside each JSON Schema.

And Swagger UI has supported this particular `examples` field for a while. So, you can use it to **show** different **examples in the docs UI**.

The shape of this OpenAPI-specific field `examples` is a `dict` with **multiple examples** (instead of a `list`), each with extra information that will be added to **OpenAPI** too.

This doesn't go inside of each JSON Schema contained in OpenAPI, this goes outside, in the *path operation* directly.

### Using the `openapi_examples` Parameter { #using-the-openapi-examples-parameter }

You can declare the OpenAPI-specific `examples` in FastAPI with the parameter `openapi_examples` for:

* `Path()`
* `Query()`
* `Header()`
* `Cookie()`
* `Body()`
* `Form()`
* `File()`

The keys of the `dict` identify each example, and each value is another `dict`.

Each specific example `dict` in the `examples` can contain:

* `summary`: Short description for the example.
* `description`: A long description that can contain Markdown text.
* `value`: This is the actual example shown, e.g. a `dict`.
* `externalValue`: alternative to `value`, a URL pointing to the example. Although this might not be supported by as many tools as `value`.

You can use it like this:

{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}

### OpenAPI Examples in the Docs UI { #openapi-examples-in-the-docs-ui }

With `openapi_examples` added to `Body()` the `/docs` would look like:


docs/en/docs/tutorial/schema-extra-example.md::Technical Details { #technical-details }::L122

# Doc: docs/en/docs/tutorial/schema-extra-example.md | Page: Declare Request Example Data { #declare-request-example-data } | Section: Technical Details { #technical-details }
## Technical Details { #technical-details }

/// tip

If you are already using **FastAPI** version **0.99.0 or above**, you can probably **skip** these details.

They are more relevant for older versions, before OpenAPI 3.1.0 was available.

You can consider this a brief OpenAPI and JSON Schema **history lesson**. 🤓

///

/// warning

These are very technical details about the standards **JSON Schema** and **OpenAPI**.

If the ideas above already work for you, that might be enough, and you probably don't need these details, feel free to skip them.

///

Before OpenAPI 3.1.0, OpenAPI used an older and modified version of **JSON Schema**.

JSON Schema didn't have `examples`, so OpenAPI added its own `example` field to its own modified version.

OpenAPI also added `example` and `examples` fields to other parts of the specification:

* [`Parameter Object` (in the specification)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object) that was used by FastAPI's:
    * `Path()`
    * `Query()`
    * `Header()`
    * `Cookie()`
* [`Request Body Object`, in the field `content`, on the `Media Type Object` (in the specification)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object) that was used by FastAPI's:
    * `Body()`
    * `File()`
    * `Form()`

/// note

This old OpenAPI-specific `examples` parameter is now `openapi_examples` since FastAPI `0.103.0`.

///

### JSON Schema's `examples` field { #json-schemas-examples-field }

But then JSON Schema added an [`examples`](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5) field to a new version of the specification.

And then the new OpenAPI 3.1.0 was based on the latest version (JSON Schema 2020-12) that included this new field `examples`.

And now this new `examples` field takes precedence over the old single (and custom) `example` field, that is now deprecated.

This new `examples` field in JSON Schema is **just a `list`** of examples, not a dict with extra metadata as in the other places in OpenAPI (described above).

/// note

Even after OpenAPI 3.1.0 was released with this new simpler integration with JSON Schema, for a while, Swagger UI, the tool that provides the automatic docs, didn't support OpenAPI 3.1.0 (it does since version 5.0.0 🎉).

Because of that, versions of FastAPI previous to 0.99.0 still used versions of OpenAPI lower than 3.1.0.

///

### Pydantic and FastAPI `examples` { #pydantic-and-fastapi-examples }

When you add `examples` inside a Pydantic model, using `schema_extra` or `Field(examples=["something"])` that example is added to the **JSON Schema** for that Pydantic model.

And that **JSON Schema** of the Pydantic model is included in the **OpenAPI** of your API, and then it's used in the docs UI.

In versions of FastAPI before 0.99.0 (0.99.0 and above use the newer OpenAPI 3.1.0) when you used `example` or `examples` with any of the other utilities (`Query()`, `Body()`, etc.) those examples were not added to the JSON Schema that describes that data (not even to OpenAPI's own version of JSON Schema), they were added directly to the *path operation* declaration in OpenAPI (outside the parts of OpenAPI that use JSON Schema).

But now that FastAPI 0.99.0 and above uses OpenAPI 3.1.0, that uses JSON Schema 2020-12, and Swagger UI 5.0.0 and above, everything is more consistent and the examples are included in JSON Schema.

### Swagger UI and OpenAPI-specific `examples` { #swagger-ui-and-openapi-specific-examples }

Now, as Swagger UI didn't support multiple JSON Schema examples (as of 2023-08-26), users didn't have a way to show multiple examples in the docs.

To solve that, FastAPI `0.103.0` **added support** for declaring the same old **OpenAPI-specific** `examples` field with the new parameter `openapi_examples`. 🤓

### Summary { #summary }

I used to say I didn't like history that much... and look at me now giving "tech history" lessons. 😅

In short, **upgrade to FastAPI 0.99.0 or above**, and things are much **simpler, consistent, and intuitive**, and you don't have to know all these historic details. 😎


docs/en/docs/tutorial/security/first-steps.md::Security - First Steps { #security-first-steps }::L1

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: Security - First Steps { #security-first-steps }
# Security - First Steps { #security-first-steps }

Let's imagine that you have your **backend** API in some domain.

And you have a **frontend** in another domain or in a different path of the same domain (or in a mobile application).

And you want to have a way for the frontend to authenticate with the backend, using a **username** and **password**.

We can use **OAuth2** to build that with **FastAPI**.

But let's save you the time of reading the full long specification just to find those little pieces of information you need.

Let's use the tools provided by **FastAPI** to handle security.


docs/en/docs/tutorial/security/first-steps.md::How it looks { #how-it-looks }::L15

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: How it looks { #how-it-looks }
## How it looks { #how-it-looks }

Let's first just use the code and see how it works, and then we'll come back to understand what's happening.


docs/en/docs/tutorial/security/first-steps.md::Create `main.py` { #create-main-py }::L19

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: Create `main.py` { #create-main-py }
## Create `main.py` { #create-main-py }

Copy the example in a file `main.py`:

{* ../../docs_src/security/tutorial001_an_py310.py *}


docs/en/docs/tutorial/security/first-steps.md::Run it { #run-it }::L25

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: Run it { #run-it }
## Run it { #run-it }

/// note

The [`python-multipart`](https://github.com/Kludex/python-multipart) package is automatically installed with **FastAPI** when you run the `pip install "fastapi[standard]"` command.

However, if you use the `pip install fastapi` command, the `python-multipart` package is not included by default.

To install it manually, make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install it with:

```console
$ pip install python-multipart
```

This is because **OAuth2** uses "form data" for sending the `username` and `password`.

///

Run the example with:

<div class="termy">

```console
$ fastapi dev

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

</div>


docs/en/docs/tutorial/security/first-steps.md::Check it { #check-it }::L55

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: Check it { #check-it }
## Check it { #check-it }

Go to the interactive docs at: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).

You will see something like this:

/// tip | Authorize button!

You already have a shiny new "Authorize" button.

And your *path operation* has a little lock in the top-right corner that you can click.

///

And if you click it, you have a little authorization form to type a `username` and `password` (and other optional fields):

/// note

It doesn't matter what you type in the form, it won't work yet. But we'll get there.

///

This is of course not the frontend for the final users, but it's a great automatic tool to document interactively all your API.

It can be used by the frontend team (that can also be yourself).

It can be used by third party applications and systems.

And it can also be used by yourself, to debug, check and test the same application.


docs/en/docs/tutorial/security/first-steps.md::The `password` flow { #the-password-flow }::L89

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: The `password` flow { #the-password-flow }
## The `password` flow { #the-password-flow }

Now let's go back a bit and understand what all that is.

The `password` "flow" is one of the ways ("flows") defined in OAuth2, to handle security and authentication.

OAuth2 was designed so that the backend or API could be independent of the server that authenticates the user.

But in this case, the same **FastAPI** application will handle the API and the authentication.

So, let's review it from that simplified point of view:

* The user types the `username` and `password` in the frontend, and hits `Enter`.
* The frontend (running in the user's browser) sends that `username` and `password` to a specific URL in our API (declared with `tokenUrl="token"`).
* The API checks that `username` and `password`, and responds with a "token" (we haven't implemented any of this yet).
    * A "token" is just a string with some content that we can use later to verify this user.
    * Normally, a token is set to expire after some time.
        * So, the user will have to log in again at some point later.
        * And if the token is stolen, the risk is less. It is not like a permanent key that will work forever (in most of the cases).
* The frontend stores that token temporarily somewhere.
* The user clicks in the frontend to go to another section of the frontend web app.
* The frontend needs to fetch some more data from the API.
    * But it needs authentication for that specific endpoint.
    * So, to authenticate with our API, it sends a header `Authorization` with a value of `Bearer ` plus the token.
    * If the token contains `foobar`, the content of the `Authorization` header would be: `Bearer foobar`.


docs/en/docs/tutorial/security/first-steps.md::**FastAPI**'s `OAuth2PasswordBearer` { #fastapis-oauth2passwordbearer }::L115

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: **FastAPI**'s `OAuth2PasswordBearer` { #fastapis-oauth2passwordbearer }
## **FastAPI**'s `OAuth2PasswordBearer` { #fastapis-oauth2passwordbearer }

**FastAPI** provides several tools, at different levels of abstraction, to implement these security features.

In this example we are going to use **OAuth2**, with the **Password** flow, using a **Bearer** token. We do that using the `OAuth2PasswordBearer` class.

/// note

A "bearer" token is not the only option.

But it's the best one for our use case.

And it might be the best for most use cases, unless you are an OAuth2 expert and know exactly why there's another option that better suits your needs.

In that case, **FastAPI** also provides you with the tools to build it.

///

When we create an instance of the `OAuth2PasswordBearer` class we pass in the `tokenUrl` parameter. This parameter contains the URL that the client (the frontend running in the user's browser) will use to send the `username` and `password` in order to get a token.

{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}

/// tip

Here `tokenUrl="token"` refers to a relative URL `token` that we haven't created yet. As it's a relative URL, it's equivalent to `./token`.

Because we are using a relative URL, if your API was located at `https://example.com/`, then it would refer to `https://example.com/token`. But if your API was located at `https://example.com/api/v1/`, then it would refer to `https://example.com/api/v1/token`.

Using a relative URL is important to make sure your application keeps working even in an advanced use case like [Behind a Proxy](../../advanced/behind-a-proxy.md).

///

This parameter doesn't create that endpoint / *path operation*, but declares that the URL `/token` will be the one that the client should use to get the token. That information is used in OpenAPI, and then in the interactive API documentation systems.

We will soon also create the actual path operation.

/// note

If you are a very strict "Pythonista" you might dislike the style of the parameter name `tokenUrl` instead of `token_url`.

That's because it is using the same name as in the OpenAPI spec. So that if you need to investigate more about any of these security schemes you can just copy and paste it to find more information about it.

///

The `oauth2_scheme` variable is an instance of `OAuth2PasswordBearer`, but it is also a "callable".

It could be called as:

```Python
oauth2_scheme(some, parameters)
```

So, it can be used with `Depends`.

### Use it { #use-it }

Now you can pass that `oauth2_scheme` in a dependency with `Depends`.

{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}

This dependency will provide a `str` that is assigned to the parameter `token` of the *path operation function*.

**FastAPI** will know that it can use this dependency to define a "security scheme" in the OpenAPI schema (and the automatic API docs).

/// note | Technical Details

**FastAPI** will know that it can use the class `OAuth2PasswordBearer` (declared in a dependency) to define the security scheme in OpenAPI because it inherits from `fastapi.security.oauth2.OAuth2`, which in turn inherits from `fastapi.security.base.SecurityBase`.

All the security utilities that integrate with OpenAPI (and the automatic API docs) inherit from `SecurityBase`, that's how **FastAPI** can know how to integrate them in OpenAPI.

///


docs/en/docs/tutorial/security/first-steps.md::What it does { #what-it-does }::L187

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: What it does { #what-it-does }
## What it does { #what-it-does }

It will go and look in the request for that `Authorization` header, check if the value is `Bearer ` plus some token, and will return the token as a `str`.

If it doesn't see an `Authorization` header, or the value doesn't have a `Bearer ` token, it will respond with a 401 status code error (`UNAUTHORIZED`) directly.

You don't even have to check if the token exists to return an error. You can be sure that if your function is executed, it will have a `str` in that token.

You can try it already in the interactive docs:

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

We are not verifying the validity of the token yet, but that's a start already.


docs/en/docs/tutorial/security/first-steps.md::Recap { #recap }::L201

# Doc: docs/en/docs/tutorial/security/first-steps.md | Page: Security - First Steps { #security-first-steps } | Section: Recap { #recap }
## Recap { #recap }

So, in just 3 or 4 extra lines, you already have some primitive form of security.


docs/en/docs/tutorial/security/get-current-user.md::Get Current User { #get-current-user }::L1

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Get Current User { #get-current-user }
# Get Current User { #get-current-user }

In the previous chapter the security system (which is based on the dependency injection system) was giving the *path operation function* a `token` as a `str`:

{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}

But that is still not that useful.

Let's make it give us the current user.


docs/en/docs/tutorial/security/get-current-user.md::Create a user model { #create-a-user-model }::L11

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Create a user model { #create-a-user-model }
## Create a user model { #create-a-user-model }

First, let's create a Pydantic user model.

The same way we use Pydantic to declare bodies, we can use it anywhere else:

{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:16] *}


docs/en/docs/tutorial/security/get-current-user.md::Create a `get_current_user` dependency { #create-a-get-current-user-dependency }::L19

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Create a `get_current_user` dependency { #create-a-get-current-user-dependency }
## Create a `get_current_user` dependency { #create-a-get-current-user-dependency }

Let's create a dependency `get_current_user`.

Remember that dependencies can have sub-dependencies?

`get_current_user` will have a dependency with the same `oauth2_scheme` we created before.

The same as we were doing before in the *path operation* directly, our new dependency `get_current_user` will receive a `token` as a `str` from the sub-dependency `oauth2_scheme`:

{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}


docs/en/docs/tutorial/security/get-current-user.md::Get the user { #get-the-user }::L31

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Get the user { #get-the-user }
## Get the user { #get-the-user }

`get_current_user` will use a (fake) utility function we created, that takes a token as a `str` and returns our Pydantic `User` model:

{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}


docs/en/docs/tutorial/security/get-current-user.md::Inject the current user { #inject-the-current-user }::L37

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Inject the current user { #inject-the-current-user }
## Inject the current user { #inject-the-current-user }

So now we can use the same `Depends` with our `get_current_user` in the *path operation*:

{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}

Notice that we declare the type of `current_user` as the Pydantic model `User`.

This will help us inside of the function with all the completion and type checks.

/// tip

You might remember that request bodies are also declared with Pydantic models.

Here **FastAPI** won't get confused because you are using `Depends`.

///

/// tip

The way this dependency system is designed allows us to have different dependencies (different "dependables") that all return a `User` model.

We are not restricted to having only one dependency that can return that type of data.

///


docs/en/docs/tutorial/security/get-current-user.md::Other models { #other-models }::L63

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Other models { #other-models }
## Other models { #other-models }

You can now get the current user directly in the *path operation functions* and deal with the security mechanisms at the **Dependency Injection** level, using `Depends`.

And you can use any model or data for the security requirements (in this case, a Pydantic model `User`).

But you are not restricted to using some specific data model, class or type.

Do you want to have an `id` and `email` and not have any `username` in your model? Sure. You can use these same tools.

Do you want to just have a `str`? Or just a `dict`? Or a database class model instance directly? It all works the same way.

You actually don't have users that log in to your application but robots, bots, or other systems, that have just an access token? Again, it all works the same.

Just use any kind of model, any kind of class, any kind of database that you need for your application. **FastAPI** has you covered with the dependency injection system.


docs/en/docs/tutorial/security/get-current-user.md::Code size { #code-size }::L79

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Code size { #code-size }
## Code size { #code-size }

This example might seem verbose. Keep in mind that we are mixing security, data models, utility functions and *path operations* in the same file.

But here's the key point.

The security and dependency injection stuff is written once.

And you can make it as complex as you want. And still, have it written only once, in a single place. With all the flexibility.

But you can have thousands of endpoints (*path operations*) using the same security system.

And all of them (or any portion of them that you want) can take advantage of re-using these dependencies or any other dependencies you create.

And all these thousands of *path operations* can be as small as 3 lines:

{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}


docs/en/docs/tutorial/security/get-current-user.md::Recap { #recap }::L97

# Doc: docs/en/docs/tutorial/security/get-current-user.md | Page: Get Current User { #get-current-user } | Section: Recap { #recap }
## Recap { #recap }

You can now get the current user directly in your *path operation function*.

We are already halfway there.

We just need to add a *path operation* for the user/client to actually send the `username` and `password`.

That comes next.


docs/en/docs/tutorial/security/index.md::Security { #security }::L1

# Doc: docs/en/docs/tutorial/security/index.md | Page: Security { #security } | Section: Security { #security }
# Security { #security }

There are many ways to handle security, authentication and authorization.

And it normally is a complex and "difficult" topic.

In many frameworks and systems just handling security and authentication takes a big amount of effort and code (in many cases it can be 50% or more of all the code written).

**FastAPI** provides several tools to help you deal with **Security** easily, rapidly, in a standard way, without having to study and learn all the security specifications.

But first, let's check some small concepts.