mirror of
https://github.com/PaiGramTeam/sqlmodel.git
synced 2024-11-26 17:51:06 +00:00
199 lines
6.8 KiB
Markdown
199 lines
6.8 KiB
Markdown
|
# Session with FastAPI Dependency
|
||
|
|
||
|
Before we keep adding things, let's change a bit how we get the session for each request to simplify our life later.
|
||
|
|
||
|
## Current Sessions
|
||
|
|
||
|
Up to now, we have been creating a session in each *path operation*, in a `with` block.
|
||
|
|
||
|
```Python hl_lines="5"
|
||
|
# Code above omitted 👆
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/delete/tutorial001.py[ln:50-57]!}
|
||
|
|
||
|
# Code below omitted 👇
|
||
|
```
|
||
|
|
||
|
<details>
|
||
|
<summary>👀 Full file preview</summary>
|
||
|
|
||
|
```Python
|
||
|
{!./docs_src/tutorial/fastapi/delete/tutorial001.py!}
|
||
|
```
|
||
|
|
||
|
</details>
|
||
|
|
||
|
That's perfectly fine, but in many use cases we would want to use <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI Dependencies</a>, for example to **verify** that the client is **logged in** and get the **current user** before executing any other code in the *path operation*.
|
||
|
|
||
|
These dependencies are also very useful during **testing**, because we can **easily replace them**, and then, for example, use a new database for our tests, or put some data before the tests, etc.
|
||
|
|
||
|
So, let's refactor these sessions to use **FastAPI Dependencies**.
|
||
|
|
||
|
## Create a **FastAPI** Dependency
|
||
|
|
||
|
A **FastAPI** dependency is very simple, it's just a function that returns a value.
|
||
|
|
||
|
It could use `yield` instead of `return`, and in that case **FastAPI** will make sure it executes all the code **after** the `yield`, once it is done with the request.
|
||
|
|
||
|
```Python hl_lines="3-5"
|
||
|
# Code above omitted 👆
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:42-44]!}
|
||
|
|
||
|
# Code below omitted 👇
|
||
|
```
|
||
|
|
||
|
<details>
|
||
|
<summary>👀 Full file preview</summary>
|
||
|
|
||
|
```Python
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!}
|
||
|
```
|
||
|
|
||
|
</details>
|
||
|
|
||
|
## Use the Dependency
|
||
|
|
||
|
Now let's make FastAPI execute a dependency and get its value in the *path operation*.
|
||
|
|
||
|
We import `Depends()` from `fastapi`. Then we use it in the *path operation function* in a **parameter**, the same way we declared parameters to get JSON bodies, path parameters, etc.
|
||
|
|
||
|
```Python hl_lines="3 15"
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:1-4]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:42-44]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:55-61]!}
|
||
|
|
||
|
# Code below omitted 👇
|
||
|
```
|
||
|
|
||
|
<details>
|
||
|
<summary>👀 Full file preview</summary>
|
||
|
|
||
|
```Python
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!}
|
||
|
```
|
||
|
|
||
|
</details>
|
||
|
|
||
|
!!! tip
|
||
|
Here's a tip about that `*,` thing in the parameters.
|
||
|
|
||
|
Here we are passing the parameter `session` that has a "default value" of `Depends(get_session)` before the parameter `hero`, that doesn't have any default value.
|
||
|
|
||
|
Python would normally complain about that, but we can use the initial "parameter" `*,` to mark all the rest of the parameters as "keyword only", which solves the problem.
|
||
|
|
||
|
You can read more about it in the FastAPI documentation <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need-tricks" class="external-link" target="_blank">Path Parameters and Numeric Validations - Order the parameters as you need, tricks</a>
|
||
|
|
||
|
The value of a dependency will **only be used for one request**, FastAPI will call it right before calling your code, and will give you the value from that dependency.
|
||
|
|
||
|
If it had `yield`, then it will continue the rest of the execution once you are done sending the response. In the case of the **session**, it will finish the cleanup code from the `with` block, closing the session, etc.
|
||
|
|
||
|
Then FastAPI will call it again for the **next request**.
|
||
|
|
||
|
Because it is called **once per request**, we will still get a **single session per request** as we should, so we are still fine with that. ✅
|
||
|
|
||
|
And because dependencies can use `yield`, FastAPI will make sure to run the code **after** the `yield` once it is done, including all the **cleanup code** at the end of the `with` block. So we are also fine with that. ✅
|
||
|
|
||
|
## The `with` Block
|
||
|
|
||
|
This means that in the main code of the *path operation function*, it will work equivalently to the previous version with the explicit `with` block.
|
||
|
|
||
|
```Python hl_lines="16-20"
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:1-4]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:42-44]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:55-61]!}
|
||
|
|
||
|
# Code below omitted 👇
|
||
|
```
|
||
|
|
||
|
<details>
|
||
|
<summary>👀 Full file preview</summary>
|
||
|
|
||
|
```Python
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!}
|
||
|
```
|
||
|
|
||
|
</details>
|
||
|
|
||
|
In fact, you could think that all that block of code inside of the `create_hero()` function is still inside a `with` block for the **session**, because this is more or less what's happening behind the scenes.
|
||
|
|
||
|
But now, the `with` block is not explicitly in the function, but in the dependency above:
|
||
|
|
||
|
```Python hl_lines="9-10"
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:1-4]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:42-44]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:55-61]!}
|
||
|
|
||
|
# Code below omitted 👇
|
||
|
```
|
||
|
|
||
|
<details>
|
||
|
<summary>👀 Full file preview</summary>
|
||
|
|
||
|
```Python
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!}
|
||
|
```
|
||
|
|
||
|
</details>
|
||
|
|
||
|
We will see how this is very useful when testing the code later. ✅
|
||
|
|
||
|
## Update the Path Operations to Use the Dependency
|
||
|
|
||
|
Now we can update the rest of the *path operations* to use the new dependency.
|
||
|
|
||
|
We just declare the dependency in the parameters of the function, with:
|
||
|
|
||
|
```Python
|
||
|
session: Session = Depends(get_session)
|
||
|
```
|
||
|
|
||
|
And then we remove the previous `with` block with the old **session**.
|
||
|
|
||
|
```Python hl_lines="15 26 35 44 59"
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:1-4]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:42-44]!}
|
||
|
|
||
|
# Code here omitted 👈
|
||
|
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:55-107]!}
|
||
|
```
|
||
|
|
||
|
<details>
|
||
|
<summary>👀 Full file preview</summary>
|
||
|
|
||
|
```Python
|
||
|
{!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!}
|
||
|
```
|
||
|
|
||
|
</details>
|
||
|
|
||
|
## Recap
|
||
|
|
||
|
You just learned how to use **FastAPI dependencies** to handle the database session. This will come in handy later when testing the code.
|
||
|
|
||
|
And you will see how much these dependencies can help the more you work with FastAPI, to handle **permissions**, **authentication**, resources like database **sessions**, etc. 🚀
|
||
|
|
||
|
If you want to learn more about dependencies, checkout the <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI docs about Dependencies</a>.
|