From 4450538a194f99243ba2c29d04233499bced7a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 3 Sep 2025 18:45:31 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Revert=20changes=20in=20docs=20f?= =?UTF-8?q?or=20dependencies=20with=20yield=20plus=20tweaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dependencies/dependencies-with-yield.md | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md index 8a94186f4..f48ac0605 100644 --- a/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md +++ b/docs/en/docs/tutorial/dependencies/dependencies-with-yield.md @@ -1,8 +1,8 @@ # Dependencies with yield { #dependencies-with-yield } -FastAPI supports dependencies that do some extra steps after finishing. +FastAPI supports dependencies that do some extra steps after finishing. -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 @@ -27,7 +27,7 @@ In fact, FastAPI uses those two decorators internally. 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: {* ../../docs_src/dependencies/tutorial007.py hl[2:4] *} @@ -35,7 +35,7 @@ The yielded value is what is injected into *path operations* and other dependenc {* ../../docs_src/dependencies/tutorial007.py hl[4] *} -The code following the `yield` statement is executed after creating the response but before sending it: +The code following the `yield` statement is executed after the response: {* ../../docs_src/dependencies/tutorial007.py hl[5:6] *} @@ -51,7 +51,7 @@ You can use `async` or regular functions. If you use a `try` block in a dependency with `yield`, you'll receive any exception that was thrown when using the dependency. -For example, if some code at some point in the middle, in another dependency or in a *path operation*, made a database transaction "rollback" or create any other error, you will receive the exception in your dependency. +For example, if some code at some point in the middle, in another dependency or in a *path operation*, made a database transaction "rollback" or created any other exception, you would receive the exception in your dependency. So, you can look for that specific exception inside the dependency with `except SomeException`. @@ -77,7 +77,7 @@ And, in turn, `dependency_b` needs the value from `dependency_a` (here named `de {* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *} -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. @@ -123,7 +123,7 @@ But it's there for you if you need it. 🤓 {* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *} -An alternative you could use to catch exceptions (and possibly also raise another `HTTPException`) is to create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}. +If you want to catch exceptions and create a custom response based on that, create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}. ## Dependencies with `yield` and `except` { #dependencies-with-yield-and-except } @@ -156,14 +156,12 @@ 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 opt raise @@ -172,20 +170,15 @@ participant tasks as Background tasks dep -->> dep: Can catch exception, raise a new HTTPException, raise other 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 ``` @@ -199,9 +192,7 @@ 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 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`. In most cases you will want to re-raise that same exception or a new one from the dependency with `yield` to make sure it's properly handled. +If you raise any exception in the code from the *path operation function*, it will be passed to the dependencies with yield, including `HTTPException`. In most cases you will want to re-raise that same exception or a new one from the dependency with `yield` to make sure it's properly handled. /// @@ -259,7 +250,7 @@ Underneath, the `open("./somefile.txt")` creates an object that is called a "Con 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` { #using-context-managers-in-dependencies-with-yield }