Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c8a99a6
Add variants for `additional_responses/tutorial002`
YuriiMotov Nov 26, 2025
42e3017
Add variants for `additional_responses/tutorial004`
YuriiMotov Nov 26, 2025
b841e9f
Add variants for `dataclasses/tutorial001`
YuriiMotov Nov 26, 2025
ee37c69
Add variants for `dataclasses/tutorial002`
YuriiMotov Nov 26, 2025
998a92a
Add variants for `dataclasses/tutorial003`
YuriiMotov Nov 26, 2025
c23c072
Add variants for `openapi-callbacks/tutorial001`
YuriiMotov Nov 27, 2025
f13f460
Add variants for `path-operation-advanced-configuration/tutorial004`
YuriiMotov Nov 27, 2025
449c18e
Add variants for `path-operation-advanced-configuration/tutorial007_pv1`
YuriiMotov Nov 27, 2025
699cd28
Add variants for `path-operation-advanced-configuration/tutorial007`
YuriiMotov Nov 27, 2025
63379de
Add variants for `response-directly/tutorial001`
YuriiMotov Nov 27, 2025
e40087b
Ignore ruff warnings for `path_operation_advanced_configuration/tutor…
YuriiMotov Nov 27, 2025
14f2e2b
Add tests for variants of `settings/app2`
YuriiMotov Nov 27, 2025
c9cffa2
Add tests for variants of `settings/app3`, fix config and add pv1 ver…
YuriiMotov Nov 27, 2025
d9770ff
Use highest version of `config` for `app03` in docs
YuriiMotov Nov 27, 2025
f6bfde2
Add tests for `using_request_directly/tutorial001`
YuriiMotov Nov 27, 2025
099878b
Simplify tests for variants `websockets.tutorial003`
YuriiMotov Nov 27, 2025
a1a7c63
Use highest versions of files for `app02` in `settings.md`
YuriiMotov Nov 27, 2025
a884f81
Fix test for `response-directly` with Pydantic v1
YuriiMotov Nov 27, 2025
abf88cc
Fix import of `Annotated` in `settings.app03`
YuriiMotov Nov 27, 2025
525ad78
Fix test coverage for `settings.app03`
YuriiMotov Nov 27, 2025
a35fc49
Fix `ln` and `hl` for `fastapi/openapi/docs.py` in `configure-swagger…
YuriiMotov Nov 27, 2025
6e902ac
Add variants for `custom_request_and_route/tutorial001`
YuriiMotov Nov 27, 2025
bf8f406
Add variants for `custom_request_and_route/tutorial002`
YuriiMotov Nov 27, 2025
ff9c332
Add variants for `custom_request_and_route/tutorial003`
YuriiMotov Nov 27, 2025
dc99673
Use highest version of variant in `cookie-param-models.md`
YuriiMotov Nov 28, 2025
90475b5
Merge branch 'master' into add-variants-advenced-code-examples
YuriiMotov Nov 29, 2025
6eb7490
Update `testing.md` to use new code- include style
YuriiMotov Nov 30, 2025
0438c54
Update code includes in `bigger-applications.md`
YuriiMotov Dec 1, 2025
f04a454
Merge remote-tracking branch 'upstream/master' into add-variants-adve…
YuriiMotov Dec 1, 2025
8222a16
Use highest version of variant in `testing.md`
YuriiMotov Dec 1, 2025
0eef5aa
Fix `custom_request_and_route/tutorial002_an**`
YuriiMotov Dec 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/en/docs/advanced/additional-responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ You can use this same `responses` parameter to add different media types for the

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

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

/// note

Expand Down Expand Up @@ -237,7 +237,7 @@ You can use that technique to reuse some predefined responses in your *path oper

For example:

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

## More information about OpenAPI responses { #more-information-about-openapi-responses }

Expand Down
6 changes: 3 additions & 3 deletions docs/en/docs/advanced/dataclasses.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FastAPI is built on top of **Pydantic**, and I have been showing you how to use

But FastAPI also supports using <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> the same way:

{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}

This is still supported thanks to **Pydantic**, as it has <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">internal support for `dataclasses`</a>.

Expand Down Expand Up @@ -32,7 +32,7 @@ But if you have a bunch of dataclasses laying around, this is a nice trick to us

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

{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}

The dataclass will be automatically converted to a Pydantic dataclass.

Expand All @@ -48,7 +48,7 @@ In some cases, you might still have to use Pydantic's version of `dataclasses`.

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

{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}

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

Expand Down
8 changes: 4 additions & 4 deletions docs/en/docs/advanced/openapi-callbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ It will have a *path operation* that will receive an `Invoice` body, and a query

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

{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}

/// tip

Expand Down Expand Up @@ -90,7 +90,7 @@ Temporarily adopting this point of view (of the *external developer*) can help y

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

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

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

Expand All @@ -101,7 +101,7 @@ It should look just like a normal FastAPI *path operation*:
* It should probably have a declaration of the body it should receive, e.g. `body: InvoiceEvent`.
* And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`.

{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}

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

Expand Down Expand Up @@ -169,7 +169,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that

Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router:

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

/// tip

Expand Down
10 changes: 5 additions & 5 deletions docs/en/docs/advanced/path-operation-advanced-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate

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

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

## Additional Responses { #additional-responses }

Expand Down Expand Up @@ -155,13 +155,13 @@ For example, in this application we don't use FastAPI's integrated functionality

//// tab | Pydantic v2

{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}

////

//// tab | Pydantic v1

{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}

////

Expand All @@ -179,13 +179,13 @@ And then in our code, we parse that YAML content directly, and then we are again

//// tab | Pydantic v2

{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}

////

//// tab | Pydantic v1

{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}

////

Expand Down
2 changes: 1 addition & 1 deletion docs/en/docs/advanced/response-directly.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ For example, you cannot put a Pydantic model in a `JSONResponse` without first c

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

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

/// note | Technical Details

Expand Down
8 changes: 4 additions & 4 deletions docs/en/docs/advanced/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ This could be especially useful during testing, as it's very easy to override a

Coming from the previous example, your `config.py` file could look like:

{* ../../docs_src/settings/app02/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}

Notice that now we don't create a default instance `settings = Settings()`.

Expand All @@ -174,7 +174,7 @@ And then we can require it from the *path operation function* as a dependency an

Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:

{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}

In the dependency override we set a new value for the `admin_email` when creating the new `Settings` object, and then we return that new object.

Expand Down Expand Up @@ -217,7 +217,7 @@ And then update your `config.py` with:

//// tab | Pydantic v2

{* ../../docs_src/settings/app03_an/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}

/// tip

Expand All @@ -229,7 +229,7 @@ The `model_config` attribute is used just for Pydantic configuration. You can re

//// tab | Pydantic v1

{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}

/// tip

Expand Down
2 changes: 1 addition & 1 deletion docs/en/docs/how-to/configure-swagger-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ FastAPI includes some default configuration parameters appropriate for most of t

It includes these default configurations:

{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}

You can override any of them by setting a different value in the argument `swagger_ui_parameters`.

Expand Down
12 changes: 6 additions & 6 deletions docs/en/docs/how-to/custom-request-and-route.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ If there's no `gzip` in the header, it will not try to decompress the body.

That way, the same route class can handle gzip compressed or uncompressed requests.

{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}

### Create a custom `GzipRoute` class { #create-a-custom-gziproute-class }

Expand All @@ -54,7 +54,7 @@ This method returns a function. And that function is what will receive a request

Here we use it to create a `GzipRequest` from the original request.

{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}

/// note | Technical Details

Expand Down Expand Up @@ -92,18 +92,18 @@ We can also use this same approach to access the request body in an exception ha

All we need to do is handle the request inside a `try`/`except` block:

{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}

If an exception occurs, the`Request` instance will still be in scope, so we can read and make use of the request body when handling the error:

{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}

## Custom `APIRoute` class in a router { #custom-apiroute-class-in-a-router }

You can also set the `route_class` parameter of an `APIRouter`:

{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}

In this example, the *path operations* under the `router` will use the custom `TimedRoute` class, and will have an extra `X-Response-Time` header in the response with the time it took to generate the response:

{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}
78 changes: 13 additions & 65 deletions docs/en/docs/tutorial/bigger-applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,15 @@ You can create the *path operations* for that module using `APIRouter`.

You import it and create an "instance" the same way you would with the class `FastAPI`:

```Python hl_lines="1 3" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}

### *Path operations* with `APIRouter` { #path-operations-with-apirouter }

And then you use it to declare your *path operations*.

Use it the same way you would use the `FastAPI` class:

```Python hl_lines="6 11 16" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}

You can think of `APIRouter` as a "mini `FastAPI`" class.

Expand All @@ -121,35 +117,7 @@ So we put them in their own `dependencies` module (`app/dependencies.py`).

We will now use a simple dependency to read a custom `X-Token` header:

//// tab | Python 3.9+

```Python hl_lines="3 6-8" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
```

////

//// tab | Python 3.8+

```Python hl_lines="1 5-7" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
```

////

//// tab | Python 3.8+ non-Annotated

/// tip

Prefer to use the `Annotated` version if possible.

///

```Python hl_lines="1 4-6" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app/dependencies.py!}
```

////
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}

/// tip

Expand Down Expand Up @@ -181,9 +149,7 @@ We know all the *path operations* in this module have the same:

So, instead of adding all that to each *path operation*, we can add it to the `APIRouter`.

```Python hl_lines="5-10 16 21" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}

As the path of each *path operation* has to start with `/`, like in:

Expand Down Expand Up @@ -242,9 +208,7 @@ And we need to get the dependency function from the module `app.dependencies`, t

So we use a relative import with `..` for the dependencies:

```Python hl_lines="3" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}

#### How relative imports work { #how-relative-imports-work }

Expand Down Expand Up @@ -315,9 +279,7 @@ We are not adding the prefix `/items` nor the `tags=["items"]` to each *path ope

But we can still add _more_ `tags` that will be applied to a specific *path operation*, and also some extra `responses` specific to that *path operation*:

```Python hl_lines="30-31" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}

/// tip

Expand All @@ -343,17 +305,13 @@ You import and create a `FastAPI` class as normally.

And we can even declare [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} that will be combined with the dependencies for each `APIRouter`:

```Python hl_lines="1 3 7" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}

### Import the `APIRouter` { #import-the-apirouter }

Now we import the other submodules that have `APIRouter`s:

```Python hl_lines="4-5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}

As the files `app/routers/users.py` and `app/routers/items.py` are submodules that are part of the same Python package `app`, we can use a single dot `.` to import them using "relative imports".

Expand Down Expand Up @@ -416,17 +374,13 @@ the `router` from `users` would overwrite the one from `items` and we wouldn't b

So, to be able to use both of them in the same file, we import the submodules directly:

```Python hl_lines="5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}

### Include the `APIRouter`s for `users` and `items` { #include-the-apirouters-for-users-and-items }

Now, let's include the `router`s from the submodules `users` and `items`:

```Python hl_lines="10-11" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}

/// info

Expand Down Expand Up @@ -466,17 +420,13 @@ It contains an `APIRouter` with some admin *path operations* that your organizat

For this example it will be super simple. But let's say that because it is shared with other projects in the organization, we cannot modify it and add a `prefix`, `dependencies`, `tags`, etc. directly to the `APIRouter`:

```Python hl_lines="3" title="app/internal/admin.py"
{!../../docs_src/bigger_applications/app/internal/admin.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}

But we still want to set a custom `prefix` when including the `APIRouter` so that all its *path operations* start with `/admin`, we want to secure it with the `dependencies` we already have for this project, and we want to include `tags` and `responses`.

We can declare all that without having to modify the original `APIRouter` by passing those parameters to `app.include_router()`:

```Python hl_lines="14-17" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}

That way, the original `APIRouter` will stay unmodified, so we can still share that same `app/internal/admin.py` file with other projects in the organization.

Expand All @@ -497,9 +447,7 @@ We can also add *path operations* directly to the `FastAPI` app.

Here we do it... just to show that we can 🤷:

```Python hl_lines="21-23" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}

and it will work correctly, together with all the other *path operations* added with `app.include_router()`.

Expand Down
2 changes: 1 addition & 1 deletion docs/en/docs/tutorial/cookie-param-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Your API now has the power to control its own <abbr title="This is a joke, just

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

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

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

Expand Down
Loading