@ -8,7 +8,7 @@ It will use the default status code or the one you set in your *path operation*.
If you want to return additional status codes apart from the main one, you can do that by returning a `Response` directly, like a `JSONResponse`, and set the additional status code directly.
If you want to return additional status codes apart from the main one, you can do that by returning a `Response` directly, like a `JSONResponse`, and set the additional status code directly.
For example, let's say that you want to have a *path operation* that allows to update items, and returns HTTP status codes of 200 "OK" when successful.
For example, let's say that you want to have a *path operation* that allows updating items, and returns HTTP status codes of 200 "OK" when successful.
But you also want it to accept new items. And when the items didn't exist before, it creates them, and returns an HTTP status code of 201 "Created".
But you also want it to accept new items. And when the items didn't exist before, it creates them, and returns an HTTP status code of 201 "Created".
@ -4,7 +4,7 @@ If your app needs to receive and send JSON data, but you need to include binary
## Base64 vs Files { #base64-vs-files }
## Base64 vs Files { #base64-vs-files }
Consider first if you can use [Request Files](../tutorial/request-files.md) for uploading binary data and [Custom Response - FileResponse](./custom-response.md#fileresponse--fileresponse-) for sending binary data, instead of encoding it in JSON.
Consider first if you can use [Request Files](../tutorial/request-files.md) for uploading binary data and [Custom Response - FileResponse](./custom-response.md#fileresponse) for sending binary data, instead of encoding it in JSON.
JSON can only contain UTF-8 encoded strings, so it can't contain raw bytes.
JSON can only contain UTF-8 encoded strings, so it can't contain raw bytes.
@ -173,7 +173,7 @@ Now use the parameter `callbacks` in *your API's path operation decorator* to pa
/// tip
/// tip
Notice that you are not passing the router itself (`invoices_callback_router`) to `callback=`, but the attribute `.routes`, as in `invoices_callback_router.routes`.
Notice that you are not passing the router itself (`invoices_callback_router`) to `callbacks=`, but the attribute `.routes`, as in `invoices_callback_router.routes`.
@ -194,7 +194,7 @@ For this, we use `security_scopes.scopes`, that contains a `list` with all these
Let's review again this dependency tree and the scopes.
Let's review again this dependency tree and the scopes.
As the `get_current_active_user` dependency has as a sub-dependency on `get_current_user`, the scope `"me"` declared at `get_current_active_user` will be included in the list of required scopes in the `security_scopes.scopes` passed to `get_current_user`.
As the `get_current_active_user` dependency has `get_current_user` as a sub-dependency, the scope `"me"` declared at `get_current_active_user` will be included in the list of required scopes in the `security_scopes.scopes` passed to `get_current_user`.
The *path operation* itself also declares a scope, `"items"`, so this will also be in the list of `security_scopes.scopes` passed to `get_current_user`.
The *path operation* itself also declares a scope, `"items"`, so this will also be in the list of `security_scopes.scopes` passed to `get_current_user`.
@ -14,7 +14,7 @@ To understand environment variables you can read [Environment Variables](../envi
## Types and validation { #types-and-validation }
## Types and validation { #types-and-validation }
These environment variables can only handle text strings, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, as Linux, Windows, macOS).
These environment variables can only handle text strings, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, such as Linux, Windows, and macOS).
That means that any value read in Python from an environment variable will be a `str`, and any conversion to a different type or any validation has to be done in code.
That means that any value read in Python from an environment variable will be a `str`, and any conversion to a different type or any validation has to be done in code.
You could use this if you want to stream pure strings, for example directly from the output of an **AI LLM** service.
You could use this if you want to stream pure strings, for example directly from the output of an **AI LLM** service.
You could also use it to stream **large binary files**, where you stream each chunk of data as you read it, without having to read it all in memory at once.
You could also use it to stream **large binary files**, where you stream each chunk of data as you read it, without having to read it all into memory at once.
You could also stream **video** or **audio** this way, it could even be generated as you process and send it.
You could also stream **video** or **audio** this way, it could even be generated as you process and send it.
Django REST framework was created to be a flexible toolkit for building Web APIs using Django underneath, to improve its API capabilities.
Django REST Framework was created to be a flexible toolkit for building Web APIs using Django underneath, to improve its API capabilities.
It is used by many companies including Mozilla, Red Hat and Eventbrite.
It is used by many companies including Mozilla, Red Hat and Eventbrite.
@ -345,7 +345,7 @@ Hug was created by Timothy Crosley, the same creator of [`isort`](https://github
Hug inspired parts of APIStar, and was one of the tools I found most promising, alongside APIStar.
Hug inspired parts of APIStar, and was one of the tools I found most promising, alongside APIStar.
Hug helped inspiring**FastAPI** to use Python type hints to declare parameters, and to generate a schema defining the API automatically.
Hug helped inspire**FastAPI** to use Python type hints to declare parameters, and to generate a schema defining the API automatically.
Hug inspired **FastAPI** to declare a `response` parameter in functions to set headers and cookies.
Hug inspired **FastAPI** to declare a `response` parameter in functions to set headers and cookies.
@ -380,7 +380,7 @@ Now APIStar is a set of tools to validate OpenAPI specifications, not a web fram
APIStar was created by Tom Christie. The same guy that created:
APIStar was created by Tom Christie. The same guy that created:
* Django REST Framework
* Django REST Framework
* Starlette (in which **FastAPI** is based)
* Starlette (on which **FastAPI** is based)
* Uvicorn (used by Starlette and **FastAPI**)
* Uvicorn (used by Starlette and **FastAPI**)
///
///
@ -393,7 +393,7 @@ The idea of declaring multiple things (data validation, serialization and docume
And after searching for a long time for a similar framework and testing many different alternatives, APIStar was the best option available.
And after searching for a long time for a similar framework and testing many different alternatives, APIStar was the best option available.
Then APIStar stopped to exist as a server and Starlette was created, and was a new better foundation for such a system. That was the final inspiration to build **FastAPI**.
Then APIStar stopped existing as a server and Starlette was created, and was a new better foundation for such a system. That was the final inspiration to build **FastAPI**.
I consider **FastAPI** a "spiritual successor" to APIStar, while improving and increasing the features, typing system, and other parts, based on the learnings from all these previous tools.
I consider **FastAPI** a "spiritual successor" to APIStar, while improving and increasing the features, typing system, and other parts, based on the learnings from all these previous tools.
@ -70,7 +70,7 @@ Asynchronous code just means that the language 💬 has a way to tell the comput
So, during that time, the computer can go and do some other work, while "slow-file" 📝 finishes.
So, during that time, the computer can go and do some other work, while "slow-file" 📝 finishes.
Then the computer / program 🤖 will come back every time it has a chance because it's waiting again, or whenever it 🤖 finished all the work it had at that point. And it 🤖 will see if any of the tasks it was waiting for have already finished, doing whatever it had to do.
Then the computer / program 🤖 will come back every time it has a chance because it's waiting again, or whenever it 🤖 finishes all the work it had at that point. And it 🤖 will see if any of the tasks it was waiting for have already finished, doing whatever it had to do.
Next, it 🤖 takes the first task to finish (let's say, our "slow-file" 📝) and continues whatever it had to do with it.
Next, it 🤖 takes the first task to finish (let's say, our "slow-file" 📝) and continues whatever it had to do with it.
@ -78,7 +78,7 @@ That "wait for something else" normally refers to <abbr title="Input and Output"
* the data from the client to be sent through the network
* the data from the client to be sent through the network
* the data sent by your program to be received by the client through the network
* the data sent by your program to be received by the client through the network
* the contents of a file in the disk to be read by the system and given to your program
* the contents of a file on the disk to be read by the system and given to your program
* the contents your program gave to the system to be written to disk
* the contents your program gave to the system to be written to disk
* a remote API operation
* a remote API operation
* a database operation to finish
* a database operation to finish
@ -257,7 +257,7 @@ And as you can have parallelism and asynchronicity at the same time, you get hig
Nope! That's not the moral of the story.
Nope! That's not the moral of the story.
Concurrency is different than parallelism. And it is better on **specific** scenarios that involve a lot of waiting. Because of that, it generally is a lot better than parallelism for web application development. But not for everything.
Concurrency is different than parallelism. And it is better in **specific** scenarios that involve a lot of waiting. Because of that, it generally is a lot better than parallelism for web application development. But not for everything.
So, to balance that out, imagine the following short story:
So, to balance that out, imagine the following short story:
@ -267,7 +267,7 @@ So, to balance that out, imagine the following short story:
---
---
There's no waiting 🕙 anywhere, just a lot of work to be done, on multiple places of the house.
There's no waiting 🕙 anywhere, just a lot of work to be done, in multiple places of the house.
You could have turns as in the burgers example, first the living room, then the kitchen, but as you are not waiting 🕙 for anything, just cleaning and cleaning, the turns wouldn't affect anything.
You could have turns as in the burgers example, first the living room, then the kitchen, but as you are not waiting 🕙 for anything, just cleaning and cleaning, the turns wouldn't affect anything.
@ -296,7 +296,7 @@ With **FastAPI** you can take advantage of concurrency that is very common for w
But you can also exploit the benefits of parallelism and multiprocessing (having multiple processes running in parallel) for **CPU bound** workloads like those in Machine Learning systems.
But you can also exploit the benefits of parallelism and multiprocessing (having multiple processes running in parallel) for **CPU bound** workloads like those in Machine Learning systems.
That, plus the simple fact that Python is the main language for **Data Science**, Machine Learning and especially Deep Learning, make FastAPI a very good match for Data Science / Machine Learning web APIs and applications (among many others).
That, plus the simple fact that Python is the main language for **Data Science**, Machine Learning and especially Deep Learning, makes FastAPI a very good match for Data Science / Machine Learning web APIs and applications (among many others).
To see how to achieve this parallelism in production see the section about [Deployment](deployment/index.md).
To see how to achieve this parallelism in production see the section about [Deployment](deployment/index.md).
@ -340,7 +340,7 @@ burgers = get_burgers(2)
---
---
So, if you are using a library that tells you that you can call it with `await`, you need to create the *path operation functions* that uses it with `async def`, like in:
So, if you are using a library that tells you that you can call it with `await`, you need to create the *path operation functions* that use it with `async def`, like in:
```Python hl_lines="2-3"
```Python hl_lines="2-3"
@app.get('/burgers')
@app.get('/burgers')
@ -435,7 +435,7 @@ Any other utility function that you call directly can be created with normal `de
This is in contrast to the functions that FastAPI calls for you: *path operation functions* and dependencies.
This is in contrast to the functions that FastAPI calls for you: *path operation functions* and dependencies.
If your utility function 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.
If your utility function 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` that function when you call it in your code.
There's an important trick in this `Dockerfile`, we first copy the **file with the dependencies alone**, not the rest of the code. Let me tell you why is that.
There's an important trick in this `Dockerfile`, we first copy the **file with the dependencies alone**, not the rest of the code. Let me tell you why that is.
The file with the package requirements **won't change frequently**. So, by copying only that file, Docker will be able to **use the cache** for that step.
The file with the package requirements **won't change frequently**. So, by copying only that file, Docker will be able to **use the cache** for that step.
And then, Docker will be able to **use the cache for the next step** that downloads and install those dependencies. And here's where we **save a lot of time**. ✨ ...and avoid boredom waiting. 😪😆
And then, Docker will be able to **use the cache for the next step** that downloads and installs those dependencies. And here's where we **save a lot of time**. ✨ ...and avoid boredom waiting. 😪😆
Downloading and installing the package dependencies **could take minutes**, but using the **cache** would **take seconds** at most.
Downloading and installing the package dependencies **could take minutes**, but using the **cache** would **take seconds** at most.
@ -488,7 +488,7 @@ And normally this **load balancer** would be able to handle requests that go to
In this type of scenario, you probably would want to have **a single (Uvicorn) process per container**, as you would already be handling replication at the cluster level.
In this type of scenario, you probably would want to have **a single (Uvicorn) process per container**, as you would already be handling replication at the cluster level.
So, in this case, you **would not** want to have a multiple workers in the container, for example with the `--workers` command line option. You would want to have just a **single Uvicorn process** per container (but probably multiple containers).
So, in this case, you **would not** want to have multiple workers in the container, for example with the `--workers` command line option. You would want to have just a **single Uvicorn process** per container (but probably multiple containers).
Having another process manager inside the container (as would be with multiple workers) would only add **unnecessary complexity** that you are most probably already taking care of with your cluster system.
Having another process manager inside the container (as would be with multiple workers) would only add **unnecessary complexity** that you are most probably already taking care of with your cluster system.
@ -544,7 +544,7 @@ If you run **a single process per container** you will have a more or less well-
And then you can set those same memory limits and requirements in your configurations for your container management system (for example in **Kubernetes**). That way it will be able to **replicate the containers** in the **available machines** taking into account the amount of memory needed by them, and the amount available in the machines in the cluster.
And then you can set those same memory limits and requirements in your configurations for your container management system (for example in **Kubernetes**). That way it will be able to **replicate the containers** in the **available machines** taking into account the amount of memory needed by them, and the amount available in the machines in the cluster.
If your application is **simple**, this will probably **not be a problem**, and you might not need to specify hard memory limits. But if you are **using a lot of memory** (for example with **machine learning** models), you should check how much memory you are consuming and adjust the **number of containers** that runs in **each machine** (and maybe add more machines to your cluster).
If your application is **simple**, this will probably **not be a problem**, and you might not need to specify hard memory limits. But if you are **using a lot of memory** (for example with **machine learning** models), you should check how much memory you are consuming and adjust the **number of containers** that run on **each machine** (and maybe add more machines to your cluster).
If you run **multiple processes per container** you will have to make sure that the number of processes started doesn't **consume more memory** than what is available.
If you run **multiple processes per container** you will have to make sure that the number of processes started doesn't **consume more memory** than what is available.
When using a proxy to handle HTTPS, your **application server** (for example Uvicorn via FastAPI CLI) doesn't known anything about the HTTPS process, it communicates with plain HTTP with the **TLS Termination Proxy**.
When using a proxy to handle HTTPS, your **application server** (for example Uvicorn via FastAPI CLI) doesn't know anything about the HTTPS process, it communicates with plain HTTP with the **TLS Termination Proxy**.
This **proxy** would normally set some HTTP headers on the fly before transmitting the request to the **application server**, to let the application server know that the request is being **forwarded** by the proxy.
This **proxy** would normally set some HTTP headers on the fly before transmitting the request to the **application server**, to let the application server know that the request is being **forwarded** by the proxy.
@ -20,4 +20,4 @@ By default, the extension will automatically discover FastAPI applications in yo
- **Deploy to FastAPI Cloud** - One-click deployment of your app to [FastAPI Cloud](https://fastapicloud.com/).
- **Deploy to FastAPI Cloud** - One-click deployment of your app to [FastAPI Cloud](https://fastapicloud.com/).
- **Stream Application Logs** - Real-time log streaming from your FastAPI Cloud-deployed application with level filtering and text search.
- **Stream Application Logs** - Real-time log streaming from your FastAPI Cloud-deployed application with level filtering and text search.
If you'd like to familiarize yourself with the extension's features, you can checkout the extension walkthrough by opening the Command Palette (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or on macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>) and selecting "Welcome: Open walkthrough..." and then choosing the "Get started with FastAPI" walkthrough.
If you'd like to familiarize yourself with the extension's features, you can checkout the extension walkthrough by opening the Command Palette (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or on macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>) and selecting "Welcome: Open walkthrough..." and then choosing the "Get started with FastAPI" walkthrough.
@ -159,7 +159,7 @@ You can read more about it at [The Twelve-Factor App: Config](https://12factor.n
## Types and Validation { #types-and-validation }
## Types and Validation { #types-and-validation }
These environment variables can only handle **text strings**, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, as Linux, Windows, macOS).
These environment variables can only handle **text strings**, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, such as Linux, Windows, and macOS).
That means that **any value** read in Python from an environment variable **will be a `str`**, and any conversion to a different type or any validation has to be done in code.
That means that **any value** read in Python from an environment variable **will be a `str`**, and any conversion to a different type or any validation has to be done in code.
They have different levels of involvement and permissions, they can perform [repository management tasks](./management-tasks.md) and together we [manage the FastAPI repository](./management.md).
They have different levels of involvement and permissions, they can perform [repository management tasks](./management-tasks.md) and together we [manage the FastAPI repository](./management.md).
@ -73,11 +73,11 @@ Pass the keys and values of the `second_user_data` dict directly as key-value ar
### Editor support { #editor-support }
### Editor support { #editor-support }
All the framework was designed to be easy and intuitive to use, all the decisions were tested on multiple editors even before starting development, to ensure the best development experience.
The whole framework was designed to be easy and intuitive to use, all the decisions were tested on multiple editors even before starting development, to ensure the best development experience.
In the Python developer surveys, it's clear [that one of the most used features is "autocompletion"](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features).
In the Python developer surveys, it's clear [that one of the most used features is "autocompletion"](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features).
The whole **FastAPI** framework is based to satisfy that. Autocompletion works everywhere.
The whole **FastAPI** framework is designed to satisfy that. Autocompletion works everywhere.
You will rarely need to come back to the docs.
You will rarely need to come back to the docs.
@ -147,7 +147,7 @@ FastAPI includes an extremely easy to use, but extremely powerful <dfn title='al
### Unlimited "plug-ins" { #unlimited-plug-ins }
### Unlimited "plug-ins" { #unlimited-plug-ins }
Or in other way, no need for them, import and use the code you need.
Or, in other words, no need for them, import and use the code you need.
Any integration is designed to be so simple to use (with dependencies) that you can create a "plug-in" for your application in 2 lines of code using the same structure and syntax used for your *path operations*.
Any integration is designed to be so simple to use (with dependencies) that you can create a "plug-in" for your application in 2 lines of code using the same structure and syntax used for your *path operations*.
@ -179,7 +179,7 @@ With **FastAPI** you get all of **Starlette**'s features (as FastAPI is just Sta
**FastAPI** is fully compatible with (and based on) [**Pydantic**](https://docs.pydantic.dev/). So, any additional Pydantic code you have, will also work.
**FastAPI** is fully compatible with (and based on) [**Pydantic**](https://docs.pydantic.dev/). So, any additional Pydantic code you have, will also work.
Including external libraries also based on Pydantic, as <abbrtitle="Object-Relational Mapper">ORM</abbr>s,<abbrtitle="Object-Document Mapper">ODM</abbr>s for databases.
Including external libraries also based on Pydantic, such as <abbrtitle="Object-Relational Mapper">ORM</abbr>s and<abbrtitle="Object-Document Mapper">ODM</abbr>s for databases.
This also means that in many cases you can pass the same object you get from a request **directly to the database**, as everything is validated automatically.
This also means that in many cases you can pass the same object you get from a request **directly to the database**, as everything is validated automatically.
@ -26,7 +26,7 @@ You can follow **FastAPI** online in several places:
You can "star" FastAPI in GitHub (clicking the star button at the top right): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). ⭐️
You can "star" FastAPI in GitHub (clicking the star button at the top right): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). ⭐️
By adding a star, other users will be able to find it more easily and see that it has been already useful for others.
By adding a star, other users will be able to find it more easily and see that it has already been useful for others.
## Watch the GitHub repository for releases { #watch-the-github-repository-for-releases }
## Watch the GitHub repository for releases { #watch-the-github-repository-for-releases }
These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.
These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.
If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need.
If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override the whole Swagger UI *path operation* and manually write any JavaScript you need.
@ -130,6 +130,6 @@ First try with `bump-pydantic`, if your tests pass and that works, then you're d
If `bump-pydantic` doesn't work for your use case, you can use the support for both Pydantic v1 and v2 models in the same app to do the migration to Pydantic v2 gradually.
If `bump-pydantic` doesn't work for your use case, you can use the support for both Pydantic v1 and v2 models in the same app to do the migration to Pydantic v2 gradually.
You could fist upgrade Pydantic to use the latest version 2, and change the imports to use `pydantic.v1` for all your models.
You could first upgrade Pydantic to use the latest version 2, and change the imports to use `pydantic.v1` for all your models.
Then, you can start migrating your models from Pydantic v1 to v2 in groups, in gradual steps. 🚶
Then, you can start migrating your models from Pydantic v1 to v2 in groups, in gradual steps. 🚶
@ -46,7 +46,7 @@ If you interact with the docs and check the response, even though the code didn'
This means that it will **always have a value**, it's just that sometimes the value could be `None` (or `null` in JSON).
This means that it will **always have a value**, it's just that sometimes the value could be `None` (or `null` in JSON).
That means that, clients using your API don't have to check if the value exists or not, they can **assume the field will always be there**, but just that in some cases it will have the default value of `None`.
That means that clients using your API don't have to check if the value exists or not, they can **assume the field will always be there**, but just that in some cases it will have the default value of `None`.
The way to describe this in OpenAPI, is to mark that field as **required**, because it will always be there.
The way to describe this in OpenAPI, is to mark that field as **required**, because it will always be there.
@ -477,13 +477,13 @@ For a more complete example including more features, see the <a href="https://fa
**Spoiler alert**: the tutorial - user guide includes:
**Spoiler alert**: the tutorial - user guide includes:
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* Declaration of **parameters** from other different places such as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* How to set **validation constraints**such as `maximum_length` or `regex`.
* A very powerful and easy to use **<dfntitle="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
* A very powerful and easy to use **<dfntitle="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with [Strawberry](https://strawberry.rocks) and other libraries.
* **GraphQL** integration with [Strawberry](https://strawberry.rocks) and other libraries.
* Many extra features (thanks to Starlette) as:
* Many extra features (thanks to Starlette) such as:
* **WebSockets**
* **WebSockets**
* extremely easy tests based on HTTPX and `pytest`
* extremely easy tests based on HTTPX and `pytest`
# Full Stack FastAPI Template { #full-stack-fastapi-template }
# Full Stack FastAPI Template { #full-stack-fastapi-template }
Templates, while typically come with a specific setup, are designed to be flexible and customizable. This allows you to modify and adapt them to your project's requirements, making them an excellent starting point. 🏁
Templates, while they typically come with a specific setup, are designed to be flexible and customizable. This allows you to modify and adapt them to your project's requirements, making them an excellent starting point. 🏁
You can use this template to get started, as it includes a lot of the initial setup, security, database and some API endpoints already done for you.
You can use this template to get started, as it includes a lot of the initial setup, security, database and some API endpoints already done for you.
Python has support for optional "type hints" (also called "type annotations").
Python has support for optional "type hints" (also called "type annotations").
These **"type hints"** or annotations are a special syntax that allow declaring the <dfntitle="for example: str, int, float, bool">type</dfn> of a variable.
These **"type hints"** or annotations are a special syntax that allows declaring the <dfntitle="for example: str, int, float, bool">type</dfn> of a variable.
By declaring types for your variables, editors and tools can give you better support.
By declaring types for your variables, editors and tools can give you better support.
@ -44,7 +44,7 @@ It's a very simple program.
But now imagine that you were writing it from scratch.
But now imagine that you were writing it from scratch.
At some point you would have started the definition of the function, you had the parameters ready...
At some point you start defining the function, and you have the parameters ready...
But then you have to call "that method that converts the first letter to upper case".
But then you have to call "that method that converts the first letter to upper case".
It can be convenient to quickly access HTTP (and WebSocket) status codes in your app, using autocompletion for the name without having to remember the integer status codes by memory.
It can be convenient to quickly access HTTP (and WebSocket) status codes in your app, using autocompletion for the name without having to memorize the integer status codes.
Read more about it in the [FastAPI docs about Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
Read more about it in the [FastAPI docs about Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
* ✨ Add support for streaming JSON Lines and binary data with `yield`. PR [#15022](https://github.com/fastapi/fastapi/pull/15022) by [@tiangolo](https://github.com/tiangolo).
* ✨ Add support for streaming JSON Lines and binary data with `yield`. PR [#15022](https://github.com/fastapi/fastapi/pull/15022) by [@tiangolo](https://github.com/tiangolo).
* This also upgrades Starlette from `>=0.40.0` to `>=0.46.0`, as it's needed to properly unrwap and re-raise exceptions from exception groups.
* This also upgrades Starlette from `>=0.40.0` to `>=0.46.0`, as it's needed to properly unwrap and re-raise exceptions from exception groups.
* New docs: [Stream JSON Lines](https://fastapi.tiangolo.com/tutorial/stream-json-lines/).
* New docs: [Stream JSON Lines](https://fastapi.tiangolo.com/tutorial/stream-json-lines/).
* And new docs: [Stream Data](https://fastapi.tiangolo.com/advanced/stream-data/).
* And new docs: [Stream Data](https://fastapi.tiangolo.com/advanced/stream-data/).
@ -3115,7 +3115,7 @@ def my_dep():
### Security fixes
### Security fixes
* ⬆️ Upgrade minimum version of `python-multipart` to `>=0.0.7` to fix a vulnerability when using form data with a ReDos attack. You can also simply upgrade `python-multipart`.
* ⬆️ Upgrade minimum version of `python-multipart` to `>=0.0.7` to fix a vulnerability when using form data with a ReDoS attack. You can also simply upgrade `python-multipart`.
Read more in the [advisory: Content-Type Header ReDoS](https://github.com/tiangolo/fastapi/security/advisories/GHSA-qf9m-vfgh-m389).
Read more in the [advisory: Content-Type Header ReDoS](https://github.com/tiangolo/fastapi/security/advisories/GHSA-qf9m-vfgh-m389).
Most of these settings are now supported in `APIRouter`, which normally lives closer to the related code, so it is recommended to use `APIRouter` when possible.
Most of these settings are now supported in `APIRouter`, which normally lives closer to the related code, so it is recommended to use `APIRouter` when possible.
But `include_router` is still useful to, for example, adding options (like `dependencies`, `prefix`, and `tags`) when including a third party router, or a generic router that is shared between several projects.
But `include_router` is still useful to, for example, add options (like `dependencies`, `prefix`, and `tags`) when including a third party router, or a generic router that is shared between several projects.
This PR allows setting the (mostly new) parameters (additionally to the already existing parameters):
This PR allows setting the (mostly new) parameters (additionally to the already existing parameters):
@ -5956,7 +5956,7 @@ Note: all the previous parameters are still there, so it's still possible to dec
* Fix typo in docs for query parameters. PR [#1832](https://github.com/tiangolo/fastapi/pull/1832) by [@ycd](https://github.com/ycd).
* Fix typo in docs for query parameters. PR [#1832](https://github.com/tiangolo/fastapi/pull/1832) by [@ycd](https://github.com/ycd).
* Add docs about [Async Tests](https://fastapi.tiangolo.com/advanced/async-tests/). PR [#1619](https://github.com/tiangolo/fastapi/pull/1619) by [@empicano](https://github.com/empicano).
* Add docs about [Async Tests](https://fastapi.tiangolo.com/advanced/async-tests/). PR [#1619](https://github.com/tiangolo/fastapi/pull/1619) by [@empicano](https://github.com/empicano).
* Raise an exception when using form data (`Form`, `File`) without having `python-multipart` installed.
* Raise an exception when using form data (`Form`, `File`) without having `python-multipart` installed.
* Up to now the application would run, and raise an exception only when receiving a request with form data, the new behavior, raising early, will prevent from deploying applications with broken dependencies.
* Up to now the application would run, and raise an exception only when receiving a request with form data, the new behavior, raising early, will prevent deploying applications with broken dependencies.
* It also detects if the correct package `python-multipart` is installed instead of the incorrect `multipart` (both importable as `multipart`).
* It also detects if the correct package `python-multipart` is installed instead of the incorrect `multipart` (both importable as `multipart`).
* PR [#1851](https://github.com/tiangolo/fastapi/pull/1851) based on original PR [#1627](https://github.com/tiangolo/fastapi/pull/1627) by [@chrisngyn](https://github.com/chrisngyn), [@YKo20010](https://github.com/YKo20010), [@kx-chen](https://github.com/kx-chen).
* PR [#1851](https://github.com/tiangolo/fastapi/pull/1851) based on original PR [#1627](https://github.com/tiangolo/fastapi/pull/1627) by [@chrisngyn](https://github.com/chrisngyn), [@YKo20010](https://github.com/YKo20010), [@kx-chen](https://github.com/kx-chen).
@ -6512,7 +6512,7 @@ Note: all the previous parameters are still there, so it's still possible to dec
* When declaring a `response_model` it is used directly to generate the response content, from whatever was returned from the *path operation function*.
* When declaring a `response_model` it is used directly to generate the response content, from whatever was returned from the *path operation function*.
* Before this, the return content was first passed through `jsonable_encoder` to ensure it was a "jsonable" object, like a `dict`, instead of an arbitrary object with attributes (like an ORM model). That's why you should make sure to update your Pydantic models for objects with attributes to use `orm_mode = True`.
* Before this, the return content was first passed through `jsonable_encoder` to ensure it was a "jsonable" object, like a `dict`, instead of an arbitrary object with attributes (like an ORM model). That's why you should make sure to update your Pydantic models for objects with attributes to use `orm_mode = True`.
* If you don't have a `response_model`, the return object will still be passed through `jsonable_encoder` first.
* If you don't have a `response_model`, the return object will still be passed through `jsonable_encoder` first.
* When a `response_model` is declared, the same `response_model` type declaration won't be used as is, it will be "cloned" to create an new one (a cloned Pydantic `Field` with all the submodels cloned as well).
* When a `response_model` is declared, the same `response_model` type declaration won't be used as is, it will be "cloned" to create a new one (a cloned Pydantic `Field` with all the submodels cloned as well).
* This avoids/fixes a potential security issue: as the returned object is passed directly to Pydantic, if the returned object was a subclass of the `response_model` (e.g. you return a `UserInDB` that inherits from `User` but contains extra fields, like `hashed_password`, and `User` is used in the `response_model`), it would still pass the validation (because `UserInDB` is a subclass of `User`) and the object would be returned as-is, including the `hashed_password`. To fix this, the declared `response_model` is cloned, if it is a Pydantic model class (or contains Pydantic model classes in it, e.g. in a `List[Item]`), the Pydantic model class(es) will be a different one (the "cloned" one). So, an object that is a subclass won't simply pass the validation and returned as-is, because it is no longer a sub-class of the cloned `response_model`. Instead, a new Pydantic model object will be created with the contents of the returned object. So, it will be a new object (made with the data from the returned one), and will be filtered by the cloned `response_model`, containing only the declared fields as normally.
* This avoids/fixes a potential security issue: as the returned object is passed directly to Pydantic, if the returned object was a subclass of the `response_model` (e.g. you return a `UserInDB` that inherits from `User` but contains extra fields, like `hashed_password`, and `User` is used in the `response_model`), it would still pass the validation (because `UserInDB` is a subclass of `User`) and the object would be returned as-is, including the `hashed_password`. To fix this, the declared `response_model` is cloned, if it is a Pydantic model class (or contains Pydantic model classes in it, e.g. in a `List[Item]`), the Pydantic model class(es) will be a different one (the "cloned" one). So, an object that is a subclass won't simply pass the validation and returned as-is, because it is no longer a sub-class of the cloned `response_model`. Instead, a new Pydantic model object will be created with the contents of the returned object. So, it will be a new object (made with the data from the returned one), and will be filtered by the cloned `response_model`, containing only the declared fields as normally.
@ -96,7 +96,7 @@ Again, doing just that declaration, with **FastAPI** you get:
Apart from normal singular types like `str`, `int`, `float`, etc. you can use more complex singular types that inherit from `str`.
Apart from normal singular types like `str`, `int`, `float`, etc. you can use more complex singular types that inherit from `str`.
To see all the options you have, checkout [Pydantic's Type Overview](https://docs.pydantic.dev/latest/concepts/types/). You will see some examples in the next chapter.
To see all the options you have, checkout [Pydantic's Type Overview](https://docs.pydantic.dev/latest/concepts/types/). You will see some examples in the next chapter.
For example, as in the `Image` model we have a `url` field, we can declare it to be an instance of Pydantic's `HttpUrl` instead of a `str`:
For example, as in the `Image` model we have a `url` field, we can declare it to be an instance of Pydantic's `HttpUrl` instead of a `str`:
@ -234,6 +234,7 @@ participant operation as Path Operation
Dependencies with `yield` have evolved over time to cover different use cases and fix some issues.
Dependencies with `yield` have evolved over time to cover different use cases and fix some issues.
If you want to see what has changed in different versions of FastAPI, you can read more about it in the advanced guide, in [Advanced Dependencies - Dependencies with `yield`, `HTTPException`, `except` and Background Tasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
If you want to see what has changed in different versions of FastAPI, you can read more about it in the advanced guide, in [Advanced Dependencies - Dependencies with `yield`, `HTTPException`, `except` and Background Tasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
## Context Managers { #context-managers }
## Context Managers { #context-managers }
### What are "Context Managers" { #what-are-context-managers }
### What are "Context Managers" { #what-are-context-managers }
@ -36,7 +36,7 @@ Here are some of the additional data types you can use:
* `datetime.timedelta`:
* `datetime.timedelta`:
* A Python `datetime.timedelta`.
* A Python `datetime.timedelta`.
* In requests and responses will be represented as a `float` of total seconds.
* In requests and responses will be represented as a `float` of total seconds.
* Pydantic also allows representing it as a "ISO 8601 time diff encoding", [see the docs for more info](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers).
* Pydantic also allows representing it as an "ISO 8601 time diff encoding", [see the docs for more info](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers).
* `frozenset`:
* `frozenset`:
* In requests and responses, treated the same as a `set`:
* In requests and responses, treated the same as a `set`:
* In requests, a list will be read, eliminating duplicates and converting it to a `set`.
* In requests, a list will be read, eliminating duplicates and converting it to a `set`.
@ -142,7 +142,7 @@ The supporting additional functions `fake_password_hasher` and `fake_save_user`
Reducing code duplication is one of the core ideas in **FastAPI**.
Reducing code duplication is one of the core ideas in **FastAPI**.
As code duplication increments the chances of bugs, security issues, code desynchronization issues (when you update in one place but not in the others), etc.
As code duplication increases the chances of bugs, security issues, code desynchronization issues (when you update in one place but not in the others), etc.
And these models are all sharing a lot of the data and duplicating attribute names and types.
And these models are all sharing a lot of the data and duplicating attribute names and types.
@ -208,4 +208,4 @@ In this case, you can use `dict`:
Use multiple Pydantic models and inherit freely for each case.
Use multiple Pydantic models and inherit freely for each case.
You don't need to have a single data model per entity if that entity must be able to have different "states". As the case with the user "entity" with a state including `password`, `password_hash` and no password.
You don't need to have a single data model per entity if that entity must be able to have different "states". The **user** "entity" is an example, with states that include `password`, `password_hash`, or no password.
@ -108,7 +108,7 @@ OpenAPI defines an API schema for your API. And that schema includes definitions
#### Check the `openapi.json` { #check-the-openapi-json }
#### Check the `openapi.json` { #check-the-openapi-json }
If you are curious about how the raw OpenAPI schema looks like, FastAPI automatically generates a JSON (schema) with the descriptions of all your API.
If you are curious about what the raw OpenAPI schema looks like, FastAPI automatically generates a JSON (schema) with the descriptions of all your API.
You can see it directly at: [http://127.0.0.1:8000/openapi.json](http://127.0.0.1:8000/openapi.json).
You can see it directly at: [http://127.0.0.1:8000/openapi.json](http://127.0.0.1:8000/openapi.json).
Since before **JSON Schema** supported `examples` OpenAPI had support for a different field also called `examples`.
Since before **JSON Schema** supported `examples`, OpenAPI had support for a different field also called `examples`.
This **OpenAPI-specific**`examples` goes in another section in the OpenAPI specification. It goes in the **details for each *path operation***, not inside each JSON Schema.
This **OpenAPI-specific**`examples` goes in another section in the OpenAPI specification. It goes in the **details for each *path operation***, not inside each JSON Schema.
@ -124,7 +124,7 @@ This ensures the endpoint takes roughly the same amount of time to respond wheth
/// note
/// note
If you check the new (fake) database `fake_users_db`, you will see how the hashed password looks like now: `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
If you check the new (fake) database `fake_users_db`, you will see what the hashed password looks like now: `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
This command will install pip if it is not already installed and also ensures that the installed version of pip is at least as recent as the one available in `ensurepip`.
This command will install pip if it is not already installed and also ensure that the installed version of pip is at least as recent as the one available in `ensurepip`.
///
///
@ -447,7 +447,7 @@ Now you're ready to start working on your project.
/// tip
/// tip
Do you want to understand what's all that above?
Do you want to understand what all that above is?
Continue reading. 👇🤓
Continue reading. 👇🤓
@ -548,7 +548,7 @@ Also, depending on your operating system (e.g. Linux, Windows, macOS), it could
## Where are Packages Installed { #where-are-packages-installed }
## Where are Packages Installed { #where-are-packages-installed }
When you install Python, it creates some directories with some files in your computer.
When you install Python, it creates some directories with some files on your computer.
Some of these directories are the ones in charge of having all the packages you install.
Some of these directories are the ones in charge of having all the packages you install.
@ -568,7 +568,7 @@ That will download a compressed file with the FastAPI code, normally from [PyPI]
It will also **download** files for other packages that FastAPI depends on.
It will also **download** files for other packages that FastAPI depends on.
Then it will **extract** all those files and put them in a directory in your computer.
Then it will **extract** all those files and put them in a directory on your computer.
By default, it will put those files downloaded and extracted in the directory that comes with your Python installation, that's the **global environment**.
By default, it will put those files downloaded and extracted in the directory that comes with your Python installation, that's the **global environment**.
@ -846,7 +846,7 @@ This is a simple guide to get you started and teach you how everything works **u
There are many **alternatives** to managing virtual environments, package dependencies (requirements), projects.
There are many **alternatives** to managing virtual environments, package dependencies (requirements), projects.
Once you are ready and want to use a tool to **manage the entire project**, packages dependencies, virtual environments, etc. I would suggest you try [uv](https://github.com/astral-sh/uv).
Once you are ready and want to use a tool to **manage the entire project**, package dependencies, virtual environments, etc. I would suggest you try [uv](https://github.com/astral-sh/uv).