* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbrtitle="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Intuitive**: Great editor support. <dfntitle="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
@ -371,7 +371,7 @@ item: Item
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* Path parameters.
* Query parameters.
@ -379,7 +379,7 @@ item: Item
* Headers.
* Forms.
* Files.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
@ -442,7 +442,7 @@ For a more complete example including more features, see the <a href="https://fa
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbrtitle="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** 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.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <ahref="https://strawberry.rocks"class="external-link"target="_blank">Strawberry</a> and other libraries.
@ -527,7 +527,7 @@ Used by Starlette:
* <ahref="https://www.python-httpx.org"target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <ahref="https://jinja.palletsprojects.com"target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbrtitle="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <dfntitle="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <abbrtitle="converted from some plain format, like bytes, into Python objects">parsed</abbr> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <dfntitle="converted from some plain format, like bytes, into Python objects">parsed</dfn> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
Nevertheless, we can declare the expected schema for the request body.
One of the main features needed by API systems is data "<abbrtitle="also called marshalling, conversion">serialization</abbr>" which is taking data from the code (Python) and converting it into something that can be sent through the network. For example, converting an object containing data from a database into a JSON object. Converting `datetime` objects into strings, etc.
One of the main features needed by API systems is data "<dfntitle="also called marshalling, conversion">serialization</dfn>" which is taking data from the code (Python) and converting it into something that can be sent through the network. For example, converting an object containing data from a database into a JSON object. Converting `datetime` objects into strings, etc.
Another big feature needed by APIs is data validation, making sure that the data is valid, given certain parameters. For example, that some field is an `int`, and not some random string. This is especially useful for incoming data.
@ -145,7 +145,7 @@ Without a data validation system, you would have to do all the checks by hand, i
These features are what Marshmallow was built to provide. It is a great library, and I have used it a lot before.
But it was created before there existed Python type hints. So, to define every <abbrtitle="the definition of how data should be formed">schema</abbr> you need to use specific utils and classes provided by Marshmallow.
But it was created before there existed Python type hints. So, to define every <dfntitle="the definition of how data should be formed">schema</dfn> you need to use specific utils and classes provided by Marshmallow.
/// check | Inspired **FastAPI** to
@ -155,7 +155,7 @@ Use code to define "schemas" that provide data types and validation, automatical
Starlette is a lightweight <abbrtitle="The new standard for building asynchronous Python web applications">ASGI</abbr> framework/toolkit, which is ideal for building high-performance asyncio services.
Starlette is a lightweight <dfntitle="The new standard for building asynchronous Python web applications">ASGI</dfn> framework/toolkit, which is ideal for building high-performance asyncio services.
It is very simple and intuitive. It's designed to be easily extensible, and have modular components.
@ -454,7 +454,7 @@ Without using containers, making applications run on startup and with restarts c
## Replication - Number of Processes { #replication-number-of-processes }
If you have a <abbrtitle="A group of machines that are configured to be connected and work together in some way.">cluster</abbr> of machines with **Kubernetes**, Docker Swarm Mode, Nomad, or another similar complex system to manage distributed containers on multiple machines, then you will probably want to **handle replication** at the **cluster level** instead of using a **process manager** (like Uvicorn with workers) in each container.
If you have a <dfntitle="A group of machines that are configured to be connected and work together in some way.">cluster</dfn> of machines with **Kubernetes**, Docker Swarm Mode, Nomad, or another similar complex system to manage distributed containers on multiple machines, then you will probably want to **handle replication** at the **cluster level** instead of using a **process manager** (like Uvicorn with workers) in each container.
One of those distributed container management systems like Kubernetes normally has some integrated way of handling **replication of containers** while still supporting **load balancing** for the incoming requests. All at the **cluster level**.
@ -65,7 +65,7 @@ Here's an example of how an HTTPS API could look like, step by step, paying atte
It would probably all start by you **acquiring** some **domain name**. Then, you would configure it in a DNS server (possibly your same cloud provider).
You would probably get a cloud server (a virtual machine) or something similar, and it would have a <abbrtitle="That doesn't change">fixed</abbr>**public IP address**.
You would probably get a cloud server (a virtual machine) or something similar, and it would have a <dfntitle="Doesn't change over time. Not dynamic.">fixed</dfn>**public IP address**.
In the DNS server(s) you would configure a record (an "`A record`") to point **your domain** to the public **IP address of your server**.
### Based on open standards { #based-on-open-standards }
* <ahref="https://github.com/OAI/OpenAPI-Specification"class="external-link"target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <abbrtitle="also known as: endpoints, routes">path</abbr><abbrtitle="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</abbr>, parameters, request bodies, security, etc.
* <ahref="https://github.com/OAI/OpenAPI-Specification"class="external-link"target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <dfntitle="also known as: endpoints, routes">path</dfn><dfntitle="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</dfn>, parameters, request bodies, security, etc.
* Automatic data model documentation with <ahref="https://json-schema.org/"class="external-link"target="_blank"><strong>JSON Schema</strong></a> (as OpenAPI itself is based on JSON Schema).
* Designed around these standards, after a meticulous study. Instead of an afterthought layer on top.
* This also allows using automatic **client code generation** in many languages.
@ -136,7 +136,7 @@ All built as reusable tools and components that are easy to integrate with your
FastAPI includes an extremely easy to use, but extremely powerful <abbrtitle='also known as "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></abbr> system.
FastAPI includes an extremely easy to use, but extremely powerful <dfntitle='also known as "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></dfn> system.
* Even dependencies can have dependencies, creating a hierarchy or **"graph" of dependencies**.
* All **automatically handled** by the framework.
@ -153,8 +153,8 @@ Any integration is designed to be so simple to use (with dependencies) that you
### Tested { #tested }
* 100% <abbrtitle="The amount of code that is automatically tested">test coverage</abbr>.
* 100% <abbrtitle="Python type annotations, with this your editor and external tools can give you better support">type annotated</abbr> code base.
* 100% <dfntitle="The amount of code that is automatically tested">test coverage</dfn>.
* 100% <dfntitle="Python type annotations, with this your editor and external tools can give you better support">type annotated</dfn> code base.
* Used in production applications.
## Starlette features { #starlette-features }
@ -190,7 +190,7 @@ With **FastAPI** you get all of **Pydantic**'s features (as FastAPI is based on
* **No brainfuck**:
* No new schema definition micro-language to learn.
* If you know Python types you know how to use Pydantic.
* Plays nicely with your **<abbrtitle="Integrated Development Environment: similar to a code editor">IDE</abbr>/<abbrtitle="A program that checks for code errors">linter</abbr>/brain**:
* Plays nicely with your **<abbrtitle="Integrated Development Environment: similar to a code editor">IDE</abbr>/<dfntitle="A program that checks for code errors">linter</dfn>/brain**:
* Because pydantic data structures are just instances of classes you define; auto-completion, linting, mypy and your intuition should all work properly with your validated data.
* Validate **complex structures**:
* Use of hierarchical Pydantic models, Python `typing`’s `List` and `Dict`, etc.
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbrtitle="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Intuitive**: Great editor support. <dfntitle="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
@ -368,7 +368,7 @@ item: Item
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* Path parameters.
* Query parameters.
@ -376,7 +376,7 @@ item: Item
* Headers.
* Forms.
* Files.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
@ -439,7 +439,7 @@ For a more complete example including more features, see the <a href="https://fa
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbrtitle="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** 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.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <ahref="https://strawberry.rocks"class="external-link"target="_blank">Strawberry</a> and other libraries.
@ -524,7 +524,7 @@ Used by Starlette:
* <ahref="https://www.python-httpx.org"target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <ahref="https://jinja.palletsprojects.com"target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbrtitle="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <dfntitle="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.
Python has support for optional "type hints" (also called "type annotations").
These **"type hints"** or annotations are a special syntax that allow declaring the <abbrtitle="for example: str, int, float, bool">type</abbr> of a variable.
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.
By declaring types for your variables, editors and tools can give you better support.
@ -34,7 +34,7 @@ The function does the following:
* Takes a `first_name` and `last_name`.
* Converts the first letter of each one to upper case with `title()`.
* <abbrtitle="Puts them together, as one. With the contents of one after the other.">Concatenates</abbr> them with a space in the middle.
* <dfntitle="Puts them together, as one. With the contents of one after the other.">Concatenates</dfn> them with a space in the middle.
@ -222,7 +222,7 @@ You can declare that a variable can be any of **several types**, for example, an
In Python 3.6 and above (including Python 3.10) you can use the `Union` type from `typing` and put inside the square brackets the possible types to accept.
In Python 3.10 there's also a **new syntax** where you can put the possible types separated by a <abbrtitle='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr>.
In Python 3.10 there's also a **new syntax** where you can put the possible types separated by a <dfntitle='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</dfn>.
//// tab | Python 3.10+
@ -336,7 +336,7 @@ And the same as with previous Python versions, from the `typing` module:
* `Optional`
* ...and others.
In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the <abbrtitle='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> to declare unions of types, that's a lot better and simpler.
In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the <dfntitle='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</dfn> to declare unions of types, that's a lot better and simpler.
////
@ -411,7 +411,7 @@ Pydantic has a special behavior when you use `Optional` or `Union[Something, Non
## Type Hints with Metadata Annotations { #type-hints-with-metadata-annotations }
Python also has a feature that allows putting **additional <abbr title="Data about the data, in this case, information about the type, e.g. a description.">metadata</abbr>** in these type hints using `Annotated`.
Python also has a feature that allows putting **additional <dfn title="Data about the data, in this case, information about the type, e.g. a description.">metadata</dfn>** in these type hints using `Annotated`.
Since Python 3.9, `Annotated` is a part of the standard library, so you can import it from `typing`.
@ -46,7 +46,7 @@ But even if you **fill the data** and click "Execute", because the docs UI works
In some special use cases (probably not very common), you might want to **restrict** the cookies that you want to receive.
Your API now has the power to control its own <abbrtitle="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</abbr>. 🤪🍪
Your API now has the power to control its own <dfntitle="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</dfn>. 🤪🍪
You can use Pydantic's model configuration to `forbid` any `extra` fields:
@ -54,9 +54,9 @@ You can use Pydantic's model configuration to `forbid` any `extra` fields:
If a client tries to send some **extra cookies**, they will receive an **error** response.
Poor cookie banners with all their effort to get your consent for the <abbrtitle="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API to reject it</abbr>. 🍪
Poor cookie banners with all their effort to get your consent for the <dfntitle="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API to reject it</dfn>. 🍪
For example, if the client tries to send a `santa_tracker` cookie with a value of `good-list-please`, the client will receive an **error** response telling them that the `santa_tracker`<abbrtitle="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">cookie is not allowed</abbr>:
For example, if the client tries to send a `santa_tracker` cookie with a value of `good-list-please`, the client will receive an **error** response telling them that the `santa_tracker`<dfntitle="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">cookie is not allowed</dfn>:
```json
{
@ -73,4 +73,4 @@ For example, if the client tries to send a `santa_tracker` cookie with a value o
## Summary { #summary }
You can use **Pydantic models** to declare <abbrtitle="Have a last cookie before you go. 🍪">**cookies**</abbr> in **FastAPI**. 😎
You can use **Pydantic models** to declare <dfntitle="Have a last cookie before you go. 🍪">**cookies**</dfn> in **FastAPI**. 😎
# Dependencies with yield { #dependencies-with-yield }
FastAPI supports dependencies that do some <abbrtitle='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc.'>extra steps after finishing</abbr>.
FastAPI supports dependencies that do some <dfntitle='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc.'>extra steps after finishing</dfn>.
To do this, use `yield` instead of `return`, and write the extra steps (code) after.
**FastAPI** has a very powerful but intuitive **<abbrtitle="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
**FastAPI** has a very powerful but intuitive **<dfntitle="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
It is designed to be very simple to use, and to make it very easy for any developer to integrate other components with **FastAPI**.
If one of your dependencies is declared multiple times for the same *path operation*, for example, multiple dependencies have a common sub-dependency, **FastAPI** will know to call that sub-dependency only once per request.
And it will save the returned value in a <abbrtitle="A utility/system to store computed/generated values, to reuse them instead of computing them again.">"cache"</abbr> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
And it will save the returned value in a <dfntitle="A utility/system to store computed/generated values, to reuse them instead of computing them again.">"cache"</dfn> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter `use_cache=False` when using `Depends`:
@ -56,7 +56,7 @@ You can add a `summary` and `description`:
## Description from docstring { #description-from-docstring }
As descriptions tend to be long and cover multiple lines, you can declare the *path operation* description in the function <abbrtitle="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation">docstring</abbr> and **FastAPI** will read it from there.
As descriptions tend to be long and cover multiple lines, you can declare the *path operation* description in the function <dfntitle="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation">docstring</dfn> and **FastAPI** will read it from there.
You can write <ahref="https://en.wikipedia.org/wiki/Markdown"class="external-link"target="_blank">Markdown</a> in the docstring, it will be interpreted and displayed correctly (taking into account docstring indentation).
@ -90,7 +90,7 @@ So, if you don't provide one, **FastAPI** will automatically generate one of "Su
## Deprecate a *path operation* { #deprecate-a-path-operation }
If you need to mark a *path operation* as <abbrtitle="obsolete, recommended not to use it">deprecated</abbr>, but without removing it, pass the parameter `deprecated`:
If you need to mark a *path operation* as <dfntitle="obsolete, recommended not to use it">deprecated</dfn>, but without removing it, pass the parameter `deprecated`:
@ -26,7 +26,7 @@ This will give you editor support inside of your function, with error checks, co
///
## Data <abbrtitle="also known as: serialization, parsing, marshalling">conversion</abbr> { #data-conversion }
## Data <dfntitle="also known as: serialization, parsing, marshalling">conversion</dfn> { #data-conversion }
If you run this example and open your browser at <ahref="http://127.0.0.1:8000/items/3"class="external-link"target="_blank">http://127.0.0.1:8000/items/3</a>, you will see a response of:
@ -38,7 +38,7 @@ If you run this example and open your browser at <a href="http://127.0.0.1:8000/
Notice that the value your function received (and returned) is `3`, as a Python `int`, not a string `"3"`.
So, with that type declaration, **FastAPI** gives you automatic request <abbrtitle="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
So, with that type declaration, **FastAPI** gives you automatic request <dfntitle="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>.
///
@ -144,7 +144,7 @@ Then create class attributes with fixed values, which will be the available vali
/// tip
If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine Learning <abbrtitle="Technically, Deep Learning model architectures">models</abbr>.
If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine Learning <dfntitle="Technically, Deep Learning model architectures">models</dfn>.
///
@ -242,7 +242,7 @@ In that case, the URL would be: `/files//home/johndoe/myfile.txt`, with a double
With **FastAPI**, by using short, intuitive and standard Python type declarations, you get:
* Editor support: error checks, autocompletion, etc.
* Data "<abbrtitle="converting the string that comes from an HTTP request into Python data">parsing</abbr>"
* Data "<dfntitle="converting the string that comes from an HTTP request into Python data">parsing</dfn>"
## Alternative (old): `Query` as the default value { #alternative-old-query-as-the-default-value }
Previous versions of FastAPI (before <abbrtitle="before 2023-03">0.95.0</abbr>) required you to use `Query` as the default value of your parameter, instead of putting it in `Annotated`, there's a high chance that you will see code using it around, so I'll explain it to you.
Previous versions of FastAPI (before <dfntitle="before 2023-03">0.95.0</dfn>) required you to use `Query` as the default value of your parameter, instead of putting it in `Annotated`, there's a high chance that you will see code using it around, so I'll explain it to you.
/// tip
@ -192,7 +192,7 @@ You can also add a parameter `min_length`:
You can define a <abbrtitle="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr>`pattern` that the parameter should match:
You can define a <dfntitle="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</dfn>`pattern` that the parameter should match:
@ -372,7 +372,7 @@ Then you can declare an `alias`, and that alias is what will be used to find the
Now let's say you don't like this parameter anymore.
You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <abbrtitle="obsolete, recommended not to use it">deprecated</abbr>.
You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <dfntitle="obsolete, recommended not to use it">deprecated</dfn>.
Then pass the parameter `deprecated=True` to `Query`:
@ -402,7 +402,7 @@ Pydantic also has <a href="https://docs.pydantic.dev/latest/concepts/validators/
///
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbrtitle="ISBN means International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbrtitle="IMDB (Internet Movie Database) is a website with information about movies">IMDB</abbr> movie URL ID:
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbrtitle="International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbrtitle="Internet Movie Database: a website with information about movies">IMDB</abbr> movie URL ID:
@ -436,7 +436,7 @@ Did you notice? a string using `value.startswith()` can take a tuple, and it wil
#### A Random Item { #a-random-item }
With `data.items()` we get an <abbrtitle="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</abbr> with tuples containing the key and value for each dictionary item.
With `data.items()` we get an <dfntitle="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</dfn> with tuples containing the key and value for each dictionary item.
We convert this iterable object into a proper `list` with `list(data.items())`.
@ -28,7 +28,7 @@ Create form parameters the same way you would for `Body` or `Query`:
For example, in one of the ways the OAuth2 specification can be used (called "password flow") it is required to send a `username` and `password` as form fields.
The <abbrtitle="specification">spec</abbr> requires the fields to be exactly named `username` and `password`, and to be sent as form fields, not JSON.
The <dfntitle="specification">spec</dfn> requires the fields to be exactly named `username` and `password`, and to be sent as form fields, not JSON.
With `Form` you can declare the same configurations as with `Body` (and `Query`, `Path`, `Cookie`), including validation, examples, an alias (e.g. `user-name` instead of `username`), etc.
@ -201,7 +201,7 @@ This will also work because `RedirectResponse` is a subclass of `Response`, and
But when you return some other arbitrary object that is not a valid Pydantic type (e.g. a database object) and you annotate it like that in the function, FastAPI will try to create a Pydantic response model from that type annotation, and will fail.
The same would happen if you had something like a <abbrtitle='A union between multiple types means "any of these types".'>union</abbr> between different types where one or more of them are not valid Pydantic types, for example this would fail 💥:
The same would happen if you had something like a <dfntitle='A union between multiple types means "any of these types".'>union</dfn> between different types where one or more of them are not valid Pydantic types, for example this would fail 💥:
@ -74,7 +74,7 @@ You can of course also pass multiple `examples`:
When you do this, the examples will be part of the internal **JSON Schema** for that body data.
Nevertheless, at the <abbrtitle="2023-08-26">time of writing this</abbr>, Swagger UI, the tool in charge of showing the docs UI, doesn't support showing multiple examples for the data in **JSON Schema**. But read below for a workaround.
Nevertheless, at the <dfntitle="2023-08-26">time of writing this</dfn>, Swagger UI, the tool in charge of showing the docs UI, doesn't support showing multiple examples for the data in **JSON Schema**. But read below for a workaround.
## Create a Virtual Environment { #create-a-virtual-environment }
When you start working on a Python project **for the first time**, create a virtual environment **<abbrtitle="there are other options, this is a simple guideline">inside your project</abbr>**.
When you start working on a Python project **for the first time**, create a virtual environment **<dfntitle="there are other options, this is a simple guideline">inside your project</dfn>**.