With that, the operation IDs would be renamed from things like `items-get_items` to just `get_items`, that way the client generator can generate simpler method names.
* Create a `templates` object that you can re-use later.
* Declare a `Request` parameter in the *path operation* that will return a template.
* Use the `templates` you created to render and return a `TemplateResponse`, passing the `request` as one of the key-value pairs in the Jinja2 "context".
* Use the `templates` you created to render and return a `TemplateResponse`, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.
```Python hl_lines="4 11 15-16"
```Python hl_lines="4 11 15-18"
{!../../../docs_src/templates/tutorial001.py!}
```
!!! note
Notice that you have to pass the `request` as part of the key-value pairs in the context for Jinja2. So, you also have to declare it in your *path operation*.
Before FastAPI 0.108.0, Starlette 0.29.0, the `name` was the first parameter.
Also, before that, in previous versions, the `request` object was passed as part of the key-value pairs in the context for Jinja2.
!!! tip
By declaring `response_class=HTMLResponse` the docs UI will be able to know that the response will be HTML.
@ -58,7 +60,7 @@ It will show the `id` taken from the "context" `dict` you passed:
## Templates and static files
And you can also use `url_for()` inside of the template, and use it, for example, with the `StaticFiles` you mounted.
You can also use `url_for()` inside of the template, and use it, for example, with the `StaticFiles` you mounted.
* ✏️ Fix typo in dependencies with yield source examples. PR [#10847](https://github.com/tiangolo/fastapi/pull/10847) by [@tiangolo](https://github.com/tiangolo).
## 0.108.0
### Upgrades
* ⬆️ Upgrade Starlette to `>=0.29.0,<0.33.0`, update docs and usage of templates with new Starlette arguments. PR [#10846](https://github.com/tiangolo/fastapi/pull/10846) by [@tiangolo](https://github.com/tiangolo).
## 0.107.0
### Upgrades
* ⬆️ Upgrade Starlette to 0.28.0. PR [#9636](https://github.com/tiangolo/fastapi/pull/9636) by [@adriangb](https://github.com/adriangb).
### Docs
* 📝 Add docs: Node.js script alternative to update OpenAPI for generated clients. PR [#10845](https://github.com/tiangolo/fastapi/pull/10845) by [@alejsdev](https://github.com/alejsdev).
* 📝 Restructure Docs section in Contributing page. PR [#10844](https://github.com/tiangolo/fastapi/pull/10844) by [@alejsdev](https://github.com/alejsdev).
## 0.106.0
### Breaking Changes
Using resources from dependencies with `yield` in background tasks is no longer supported.
This change is what supports the new features, read below. 🤓
### Dependencies with `yield`, `HTTPException` and Background Tasks
Dependencies with `yield` now can raise `HTTPException` and other exceptions after `yield`. 🎉
Read the new docs here: [Dependencies with `yield` and `HTTPException`](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-httpexception).
```Python
from fastapi import Depends, FastAPI, HTTPException
raise HTTPException(status_code=404, detail="Item not found")
item = data[item_id]
if item["owner"] != username:
raise OwnerError(username)
return item
```
---
Before FastAPI 0.106.0, raising exceptions after `yield` was not possible, the exit code in dependencies with `yield` was executed *after* the response was sent, so [Exception Handlers](https://fastapi.tiangolo.com/tutorial/handling-errors/#install-custom-exception-handlers) would have already run.
This was designed this way mainly to allow using the same objects "yielded" by dependencies inside of background tasks, because the exit code would be executed after the background tasks were finished.
Nevertheless, as this would mean waiting for the response to travel through the network while unnecessarily holding a resource in a dependency with yield (for example a database connection), this was changed in FastAPI 0.106.0.
Additionally, a background task is normally an independent set of logic that should be handled separately, with its own resources (e.g. its own database connection).
If you used to rely on this behavior, now you should create the resources for background tasks inside the background task itself, and use internally only data that doesn't depend on the resources of dependencies with `yield`.
For example, instead of using the same database session, you would create a new database session inside of the background task, and you would obtain the objects from the database using this new session. And then instead of passing the object from the database as a parameter to the background task function, you would pass the ID of that object and then obtain the object again inside the background task function.
The sequence of execution before FastAPI 0.106.0 was like this diagram:
Time flows from top to bottom. And each column is one of the parts interacting or executing code.
```mermaid
sequenceDiagram
participant client as Client
participant handler as Exception handler
participant dep as Dep with yield
participant operation as Path Operation
participant tasks as Background tasks
Note over client,tasks: Can raise exception for dependency, handled after response is sent
Note over client,operation: Can raise HTTPException and can change the response
client ->> dep: Start request
Note over dep: Run code up to yield
opt raise
dep -->> handler: Raise HTTPException
handler -->> client: HTTP error response
dep -->> dep: Raise other exception
end
dep ->> operation: Run dependency, e.g. DB session
opt raise
operation -->> dep: Raise HTTPException
dep -->> handler: Auto forward exception
handler -->> client: HTTP error response
operation -->> dep: Raise other exception
dep -->> handler: Auto forward exception
end
operation ->> client: Return response to client
Note over client,operation: Response is already sent, can't change it anymore
opt Tasks
operation -->> tasks: Send background tasks
end
opt Raise other exception
tasks -->> dep: Raise other exception
end
Note over dep: After yield
opt Handle other exception
dep -->> dep: Handle exception, can't change response. E.g. close DB session.
end
```
The new execution flow can be found in the docs: [Execution of dependencies with `yield`](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#execution-of-dependencies-with-yield).
### Features
* ✨ Add support for raising exceptions (including `HTTPException`) in dependencies with `yield` in the exit code, do not support them in background tasks. PR [#10831](https://github.com/tiangolo/fastapi/pull/10831) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 👥 Update FastAPI People. PR [#10567](https://github.com/tiangolo/fastapi/pull/10567) by [@tiangolo](https://github.com/tiangolo).
FastAPI supports dependencies that do some <abbrtitle='sometimes also called "exit", "cleanup", "teardown", "close", "context managers", ...'>extra steps after finishing</abbr>.
FastAPI supports dependencies that do some <abbrtitle='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc.'>extra steps after finishing</abbr>.
To do this, use `yield` instead of `return`, and write the extra steps after.
To do this, use `yield` instead of `return`, and write the extra steps (code) after.
!!! tip
Make sure to use `yield` one single time.
@ -21,7 +21,7 @@ To do this, use `yield` instead of `return`, and write the extra steps after.
For example, you could use this to create a database session and close it after finishing.
Only the code prior to and including the `yield` statement is executed before sending a response:
Only the code prior to and including the `yield` statement is executed before creating a response:
```Python hl_lines="2-4"
{!../../../docs_src/dependencies/tutorial007.py!}
@ -40,7 +40,7 @@ The code following the `yield` statement is executed after the response has been
```
!!! tip
You can use `async` or normal functions.
You can use `async` or regular functions.
**FastAPI** will do the right thing with each, the same as with normal dependencies.
@ -114,7 +114,7 @@ And, in turn, `dependency_b` needs the value from `dependency_a` (here named `de
The same way, you could have dependencies with `yield` and `return` mixed.
The same way, you could have some dependencies with `yield` and some other dependencies with `return`, and have some of those depend on some of the others.
And you could have a single dependency that requires several other dependencies with `yield`, etc.
@ -131,24 +131,38 @@ You can have any combinations of dependencies that you want.
You saw that you can use dependencies with `yield` and have `try` blocks that catch exceptions.
It might be tempting to raise an `HTTPException` or similar in the exit code, after the `yield`. But **it won't work**.
The same way, you could raise an `HTTPException` or similar in the exit code, after the `yield`.
The exit code in dependencies with `yield` is executed *after* the response is sent, so [Exception Handlers](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} will have already run. There's nothing catching exceptions thrown by your dependencies in the exit code (after the `yield`).
!!! tip
So, if you raise an `HTTPException` after the `yield`, the default (or any custom) exception handler that catches `HTTPException`s and returns an HTTP 400 response won't be there to catch that exception anymore.
This is a somewhat advanced technique, and in most of the cases you won't really need it, as you can raise exceptions (including `HTTPException`) from inside of the rest of your application code, for example, in the *path operation function*.
This is what allows anything set in the dependency (e.g. a DB session) to, for example, be used by background tasks.
But it's there for you if you need it. 🤓
Background tasks are run *after* the response has been sent. So there's no way to raise an `HTTPException` because there's not even a way to change the response that is *already sent*.
=== "Python 3.9+"
But if a background task creates a DB error, at least you can rollback or cleanly close the session in the dependency with `yield`, and maybe log the error or report it to a remote tracking system.
If you have some code that you know could raise an exception, do the most normal/"Pythonic" thing and add a `try` block in that section of the code.
=== "Python 3.8+"
If you have custom exceptions that you would like to handle *before* returning the response and possibly modifying the response, maybe even raising an `HTTPException`, create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
An alternative you could use to catch exceptions (and possibly also raise another `HTTPException`) is ot create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
## Execution of dependencies with `yield`
The sequence of execution is more or less like this diagram. Time flows from top to bottom. And each column is one of the parts interacting or executing code.
@ -161,34 +175,30 @@ participant dep as Dep with yield
participant operation as Path Operation
participant tasks as Background tasks
Note over client,tasks: Can raise exception for dependency, handled after response is sent
Note over client,operation: Can raise HTTPException and can change the response
Note over client,operation: Can raise exceptions, including HTTPException
client ->> dep: Start request
Note over dep: Run code up to yield
opt raise
dep -->> handler: Raise HTTPException
opt raise Exception
dep -->> handler: Raise Exception
handler -->> client: HTTP error response
dep -->> dep: Raise other exception
end
dep ->> operation: Run dependency, e.g. DB session
dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
dep -->> handler: Auto forward exception
end
handler -->> client: HTTP error response
operation -->> dep: Raise other exception
dep -->> handler: Auto forward exception
end
operation ->> client: Return response to client
Note over client,operation: Response is already sent, can't change it anymore
opt Tasks
operation -->> tasks: Send background tasks
end
opt Raise other exception
tasks -->> dep: Raise other exception
end
Note over dep: After yield
opt Handle other exception
dep -->> dep: Handle exception, can't change response. E.g. close DB session.
tasks -->> tasks: Handle exceptions in the background task code
end
```
@ -198,10 +208,33 @@ participant tasks as Background tasks
After one of those responses is sent, no other response can be sent.
!!! tip
This diagram shows `HTTPException`, but you could also raise any other exception for which you create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
This diagram shows `HTTPException`, but you could also raise any other exception that you catch in a dependency with `yield` or with a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
If you raise any exception, it will be passed to the dependencies with yield, including `HTTPException`, and then **again** to the exception handlers. If there's no exception handler for that exception, it will then be handled by the default internal `ServerErrorMiddleware`, returning a 500 HTTP status code, to let the client know that there was an error in the server.
## Dependencies with `yield`, `HTTPException` and Background Tasks
!!! warning
You most probably don't need these technical details, you can skip this section and continue below.
These details are useful mainly if you were using a version of FastAPI prior to 0.106.0 and used resources from dependencies with `yield` in background tasks.
Before FastAPI 0.106.0, raising exceptions after `yield` was not possible, the exit code in dependencies with `yield` was executed *after* the response was sent, so [Exception Handlers](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} would have already run.
This was designed this way mainly to allow using the same objects "yielded" by dependencies inside of background tasks, because the exit code would be executed after the background tasks were finished.
Nevertheless, as this would mean waiting for the response to travel through the network while unnecessarily holding a resource in a dependency with yield (for example a database connection), this was changed in FastAPI 0.106.0.
!!! tip
Additionally, a background task is normally an independent set of logic that should be handled separately, with its own resources (e.g. its own database connection).
So, this way you will probably have cleaner code.
If you used to rely on this behavior, now you should create the resources for background tasks inside the background task itself, and use internally only data that doesn't depend on the resources of dependencies with `yield`.
For example, instead of using the same database session, you would create a new database session inside of the background task, and you would obtain the objects from the database using this new session. And then instead of passing the object from the database as a parameter to the background task function, you would pass the ID of that object and then obtain the object again inside the background task function.
## Context Managers
### What are "Context Managers"
@ -220,7 +253,7 @@ Underneath, the `open("./somefile.txt")` creates an object that is a called a "C
When the `with` block finishes, it makes sure to close the file, even if there were exceptions.
When you create a dependency with `yield`, **FastAPI** will internally convert it to a context manager, and combine it with some other related tools.
When you create a dependency with `yield`, **FastAPI** will internally create a context manager for it, and combine it with some other related tools.
### Using context managers in dependencies with `yield`