Saltar a contenido

FastAPI

FastAPI

FastAPI framework, alto desempe√Īo, f√°cil de aprender, r√°pido de programar, listo para producci√≥n

Test Coverage Package version


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.6+ 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.

  • 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

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!"

Brian Okken - Python Bytes podcast host (ref)

"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."

Timothy Crosley - Hug creator (ref)

"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 [...]"

Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)

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.6+

FastAPI est√° sobre los hombros de gigantes:

Instalación

$ pip install fastapi

---> 100%

También vas a necesitar un servidor ASGI para producción cómo Uvicorn o Hypercorn.

$ pip install uvicorn[standard]

---> 100%

Ejemplo

Créalo

  • Crea un archivo main.py con:
from fastapi import FastAPI
from typing import Optional

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}

O usa async def...

Si tu código usa async / await, usa async def:

from fastapi import FastAPI
from typing import Optional

app = FastAPI()


@app.get("/")
async def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = 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:

$ 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:

{"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):

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):

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.

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float
    is_offer: Optional[bool] = None


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = 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:

Swagger UI

  • Haz cl√≠ck en el bot√≥n de "Try it out" que te permite llenar los par√°metros e interactuar directamente con la API:

Swagger UI interaction

  • 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:

Swagger UI interaction

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:

ReDoc

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.6+ est√°ndar.

Por ejemplo, para un int:

item_id: int

o para un modelo m√°s complejo de Item:

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 boolsi 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:

    return {"item_name": item.name, "item_id": item_id}

...de:

        ... "item_name": item.name ...

...a:

        ... "item_price": item.price ...

... y mira como el editor va a auto-completar los atributos y sabr√° sus tipos:

soporte de editor

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 requests 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:

  • ujson - para "parsing" de JSON m√°s r√°pido.
  • email_validator - para validaci√≥n de emails.

Usados por Starlette:

  • requests - Requerido si quieres usar el TestClient.
  • aiofiles - Requerido si quieres usar FileResponse o StaticFiles.
  • 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.