FastAPI framework, alto desempeño, fácil de aprender, rápido de programar, listo para producción
---
**Documentación**: https://fastapi.tiangolo.com
**Código Fuente**: https://github.com/tiangolo/fastapi
---
FastAPI es un web framework moderno y rápido (de alto rendimiento) para construir APIs con Python 3.8+ basado en las anotaciones de tipos estándar de Python.
Sus características principales son:
* **Rapidez**: Alto rendimiento, a la par con **NodeJS** y **Go** (gracias a Starlette y Pydantic). [Uno de los frameworks de Python más rápidos](#rendimiento).
* **Rápido de programar**: Incrementa la velocidad de desarrollo entre 200% y 300%. *
* **Menos errores**: Reduce los errores humanos (de programador) aproximadamente un 40%. *
* **Intuitivo**: Gran soporte en los editores con auto completado en todas partes. Gasta menos tiempo debugging.
* **Fácil**: Está diseñado para ser fácil de usar y aprender. Gastando menos tiempo leyendo documentación.
* **Corto**: Minimiza la duplicación de código. Múltiples funcionalidades con cada declaración de parámetros. Menos errores.
* **Robusto**: Crea código listo para producción con documentación automática interactiva.
* **Basado en estándares**: Basado y totalmente compatible con los estándares abiertos para APIs: OpenAPI (conocido previamente como Swagger) y JSON Schema.
* Esta estimación está basada en pruebas con un equipo de desarrollo interno contruyendo aplicaciones listas para producción.
## Sponsors
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
{% endfor %}
{% endif %}
Otros sponsors
## Opiniones
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
Kabir Khan -
Microsoft (ref)
---
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala -
Uber (ref)
---
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
---
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
---
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
---
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
---
## **Typer**, el FastAPI de las CLIs
Si estás construyendo un app de CLI para ser usada en la terminal en vez de una API web, fíjate en **Typer**.
**Typer** es el hermano menor de FastAPI. La intención es que sea el **FastAPI de las CLIs**. ⌨️ 🚀
## Requisitos
Python 3.8+
FastAPI está sobre los hombros de gigantes:
* Starlette para las partes web.
* Pydantic para las partes de datos.
## Instalación
```console
$ pip install fastapi
---> 100%
```
También vas a necesitar un servidor ASGI para producción cómo Uvicorn o Hypercorn.
```console
$ pip install "uvicorn[standard]"
---> 100%
```
## Ejemplo
### Créalo
* Crea un archivo `main.py` con:
```Python
from fastapi import FastAPI
from typing import Union
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
```
O usa async def
...
Si tu código usa `async` / `await`, usa `async def`:
```Python hl_lines="7 12"
from fastapi import FastAPI
from typing import Union
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
```
**Nota**:
Si no lo sabes, revisa la sección _"¿Con prisa?"_ sobre `async` y `await` en la documentación.
### Córrelo
Corre el servidor con:
```console
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
Sobre el comando uvicorn main:app --reload
...
El comando `uvicorn main:app` se refiere a:
* `main`: el archivo `main.py` (el"modulo" de Python).
* `app`: el objeto creado dentro de `main.py` con la línea `app = FastAPI()`.
* `--reload`: hace que el servidor se reinicie después de cambios en el código. Esta opción solo debe ser usada en desarrollo.
### Revísalo
Abre tu navegador en http://127.0.0.1:8000/items/5?q=somequery.
Verás la respuesta de JSON cómo:
```JSON
{"item_id": 5, "q": "somequery"}
```
Ya creaste una API que:
* Recibe HTTP requests en los _paths_ `/` y `/items/{item_id}`.
* Ambos _paths_ toman operaciones `GET` (también conocido como HTTP _methods_).
* El _path_ `/items/{item_id}` tiene un _path parameter_ `item_id` que debería ser un `int`.
* El _path_ `/items/{item_id}` tiene un `str` _query parameter_ `q` opcional.
### Documentación interactiva de APIs
Ahora ve a http://127.0.0.1:8000/docs.
Verás la documentación automática e interactiva de la API (proveída por Swagger UI):

### Documentación alternativa de la API
Ahora, ve a http://127.0.0.1:8000/redoc.
Ahora verás la documentación automática alternativa (proveída por ReDoc):

## Mejora al ejemplo
Ahora modifica el archivo `main.py` para recibir un body del `PUT` request.
Declara el body usando las declaraciones de tipo estándares de Python gracias a Pydantic.
```Python hl_lines="2 7-10 23-25"
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Union
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
El servidor debería recargar automáticamente (porque añadiste `--reload` al comando `uvicorn` que está más arriba).
### Mejora a la documentación interactiva de APIs
Ahora ve a http://127.0.0.1:8000/docs.
* La documentación interactiva de la API se actualizará automáticamente, incluyendo el nuevo body:

* Haz clíck en el botón de "Try it out" que te permite llenar los parámetros e interactuar directamente con la API:

* Luego haz clíck en el botón de "Execute". La interfaz de usuario se comunicará con tu API, enviará los parámetros y recibirá los resultados para mostrarlos en pantalla:

### Mejora a la documentación alternativa de la API
Ahora, ve a http://127.0.0.1:8000/redoc.
* La documentación alternativa también reflejará el nuevo parámetro de query y el body:

### Resumen
En resumen, declaras los tipos de parámetros, body, etc. **una vez** como parámetros de la función.
Lo haces con tipos modernos estándar de Python.
No tienes que aprender una sintáxis nueva, los métodos o clases de una library específica, etc.
Solo **Python 3.8+** estándar.
Por ejemplo, para un `int`:
```Python
item_id: int
```
o para un modelo más complejo de `Item`:
```Python
item: Item
```
...y con esa única declaración obtienes:
* Soporte del editor incluyendo:
* Auto completado.
* Anotaciones de tipos.
* Validación de datos:
* Errores automáticos y claros cuándo los datos son inválidos.
* Validación, incluso para objetos JSON profundamente anidados.
* Conversión de datos de input: viniendo de la red a datos y tipos de Python. Leyendo desde:
* JSON.
* Path parameters.
* Query parameters.
* Cookies.
* Headers.
* Formularios.
* Archivos.
* Conversión de datos de output: convirtiendo de datos y tipos de Python a datos para la red (como JSON):
* Convertir tipos de Python (`str`, `int`, `float`, `bool`, `list`, etc).
* Objetos `datetime`.
* Objetos `UUID`.
* Modelos de bases de datos.
* ...y muchos más.
* Documentación automática e interactiva incluyendo 2 interfaces de usuario alternativas:
* Swagger UI.
* ReDoc.
---
Volviendo al ejemplo de código anterior, **FastAPI** va a:
* Validar que existe un `item_id` en el path para requests usando `GET` y `PUT`.
* Validar que el `item_id` es del tipo `int` para requests de tipo `GET` y `PUT`.
* Si no lo es, el cliente verá un mensaje de error útil y claro.
* Revisar si existe un query parameter opcional llamado `q` (cómo en `http://127.0.0.1:8000/items/foo?q=somequery`) para requests de tipo `GET`.
* Como el parámetro `q` fue declarado con `= None` es opcional.
* Sin el `None` sería obligatorio (cómo lo es el body en el caso con `PUT`).
* Para requests de tipo `PUT` a `/items/{item_id}` leer el body como JSON:
* Revisar si tiene un atributo requerido `name` que debe ser un `str`.
* Revisar si tiene un atributo requerido `price` que debe ser un `float`.
* Revisar si tiene un atributo opcional `is_offer`, que debe ser un `bool`si está presente.
* Todo esto funcionaría para objetos JSON profundamente anidados.
* Convertir de y a JSON automáticamente.
* Documentar todo con OpenAPI que puede ser usado por:
* Sistemas de documentación interactiva.
* Sistemas de generación automática de código de cliente para muchos lenguajes.
* Proveer directamente 2 interfaces de documentación web interactivas.
---
Hasta ahora, escasamente vimos lo básico pero ya tienes una idea de cómo funciona.
Intenta cambiando la línea a:
```Python
return {"item_name": item.name, "item_id": item_id}
```
...de:
```Python
... "item_name": item.name ...
```
...a:
```Python
... "item_price": item.price ...
```
... y mira como el editor va a auto-completar los atributos y sabrá sus tipos:

Para un ejemplo más completo que incluye más características ve el Tutorial - Guía de Usuario.
**Spoiler alert**: el Tutorial - Guía de Usuario incluye:
* Declaración de **parámetros** en otros lugares diferentes cómo los: **headers**, **cookies**, **formularios** y **archivos**.
* Cómo agregar **requisitos de validación** cómo `maximum_length` o `regex`.
* Un sistema de **Dependency Injection** poderoso y fácil de usar.
* Seguridad y autenticación incluyendo soporte para **OAuth2** con **JWT tokens** y **HTTP Basic** auth.
* Técnicas más avanzadas, pero igual de fáciles, para declarar **modelos de JSON profundamente anidados** (gracias a Pydantic).
* Muchas características extra (gracias a Starlette) como:
* **WebSockets**
* **GraphQL**
* pruebas extremadamente fáciles con HTTPX y `pytest`
* **CORS**
* **Cookie Sessions**
* ...y mucho más.
## Rendimiento
Benchmarks independientes de TechEmpower muestran que aplicaciones de **FastAPI** corriendo con Uvicorn cómo uno de los frameworks de Python más rápidos, únicamente debajo de Starlette y Uvicorn (usados internamente por FastAPI). (*)
Para entender más al respecto revisa la sección Benchmarks.
## Dependencias Opcionales
Usadas por Pydantic:
* email_validator
- para validación de emails.
Usados por Starlette:
* httpx
- Requerido si quieres usar el `TestClient`.
* jinja2
- Requerido si quieres usar la configuración por defecto de templates.
* python-multipart
- Requerido si quieres dar soporte a "parsing" de formularios, con `request.form()`.
* itsdangerous
- Requerido para dar soporte a `SessionMiddleware`.
* pyyaml
- Requerido para dar soporte al `SchemaGenerator` de Starlette (probablemente no lo necesites con FastAPI).
* graphene
- Requerido para dar soporte a `GraphQLApp`.
* ujson
- Requerido si quieres usar `UJSONResponse`.
Usado por FastAPI / Starlette:
* uvicorn
- para el servidor que carga y sirve tu aplicación.
* orjson
- Requerido si quieres usar `ORJSONResponse`.
Puedes instalarlos con `pip install fastapi[all]`.
## Licencia
Este proyecto está licenciado bajo los términos de la licencia del MIT.