@ -329,7 +329,7 @@ So, about the egg and the chicken, how do you call the first `async` function?
If you are working with **FastAPI** you don't have to worry about that, because that "first" function will be your path operation function, and FastAPI will know how to do the right thing.
If you are working with **FastAPI** you don't have to worry about that, because that "first" function will be your path operation function, and FastAPI will know how to do the right thing.
But if you want to use `async` / `await` without FastAPI, <ahref="https://docs.python.org/3/library/asyncio-task.html#coroutine"target="_blank">check the official Python docs</a>
But if you want to use `async` / `await` without FastAPI, <ahref="https://docs.python.org/3/library/asyncio-task.html#coroutine"target="_blank">check the official Python docs</a>.
### Other forms of asynchronous code
### Other forms of asynchronous code
@ -362,3 +362,39 @@ Let's see the same phrase from above:
That should make more sense now.
That should make more sense now.
All that is what powers FastAPI (through Starlette) and what makes it have such an impressive performance.
All that is what powers FastAPI (through Starlette) and what makes it have such an impressive performance.
## Very Technical Details
!!! warning
You can probably skip this.
These are very technical details of how **FastAPI** works underneath.
If you have quite some technical knowledge (co-routines, threads, blocking, etc) and are curious about how FastAPI handles `async def` vs normal `def`, go ahead.
### Path operation functions
When you declare a *path operation function* with normal `def` instead of `async def`, it is run in an external threadpool that is then awaited, instead of being called directly (as it would block the server).
### Dependencies
The same applies for dependencies. If a dependency is a standard `def` function instead of `async def`, it is run in the external threadpool.
### Sub-dependencies
You can have multiple dependencies and sub-dependencies requiring each other (as parameters of the function definitions), some of them might be created with `async def` and some with normal `def`. It would still work, and the ones created with normal `def` would be called on an external thread instead of being "awaited".
### Other utility functions
Any other utility function that you call directly can be created with normal `def` or `async def` and FastAPI won't affect the way you call it.
This is in contrast to the functions that FastAPI calls for you: *path operation functions* and dependencies.
If your utility funciton is a normal function with `def`, it will be called directly (as you write it in your code), not in a threadpool, if the function is created with `async def` then you should await for that function when you call it in your code.
---
Again, these are very technical details that would probably be useful if you came searching for them.
Otherwise, you should be good with the guidelines from the section above: <ahref="#in-a-hurry">In a hurry?</a>.
@ -130,7 +130,7 @@ This will then give us better editor support inside the path operation function,
{!./src/sql_databases/tutorial001.py!}
{!./src/sql_databases/tutorial001.py!}
```
```
!!! info "Technical Detail"
!!! info "Technical Details"
The parameter `db` is actually of type `SessionLocal`, but this class (created with `sessionmaker()`) is a "proxy" of a SQLAlchemy `Session`, so, the editor doesn't really know what methods are provided.
The parameter `db` is actually of type `SessionLocal`, but this class (created with `sessionmaker()`) is a "proxy" of a SQLAlchemy `Session`, so, the editor doesn't really know what methods are provided.
But by declaring the type as `Session`, the editor now can know the available methods (`.add()`, `.query()`, `.commit()`, etc) and can provide better support (like completion). The type declaration doesn't affect the actual object.
But by declaring the type as `Session`, the editor now can know the available methods (`.add()`, `.query()`, `.commit()`, etc) and can provide better support (like completion). The type declaration doesn't affect the actual object.
@ -247,6 +247,9 @@ Then we should declare the path operation without `async def`, just with a norma
{!./src/sql_databases/tutorial001.py!}
{!./src/sql_databases/tutorial001.py!}
```
```
!!! note "Very Technical Details"
If you are curious and have a deep technical knowledge, you can check <ahref="https://fastapi.tiangolo.com/async/#very-technical-details"target="_blank">the very technical details of how this `async def` vs `def` is handled</a>.
## Migrations
## Migrations
Because we are using SQLAlchemy directly and we don't require any kind of plug-in for it to work with **FastAPI**, we could integrate database <abbrtitle="Automatically updating the database to have any new column we define in our models.">migrations</abbr> with <ahref="https://alembic.sqlalchemy.org"target="_blank">Alembic</a> directly.
Because we are using SQLAlchemy directly and we don't require any kind of plug-in for it to work with **FastAPI**, we could integrate database <abbrtitle="Automatically updating the database to have any new column we define in our models.">migrations</abbr> with <ahref="https://alembic.sqlalchemy.org"target="_blank">Alembic</a> directly.