mirror of
				https://github.com/fastapi/sqlmodel.git
				synced 2025-11-04 22:56:21 +08: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>.
 |