La misma API en cincuenta líneas, diez veces más rápida serializando, y el error de validación que te devuelve la contraseña que acabas de rechazar.
⏱ 16 min de lectura
Empieza el último bloque del curso. FastAPI es la otra forma de escribir una API en Python, y lleva unos años siendo la que todo el mundo recomienda.
Las comparaciones que se leen por ahí son de dos tipos: las que dicen que es diez veces más rápido y las que dicen que eso no importa. Vamos a medirlo, y vamos a ver que las dos tienen parte de razón y ninguna dice lo que de verdad decide la elección.
Esta es entera, con tres puntos de acceso, validación y documentación:
python
from datetime import date
from decimal import Decimal
from enum import Enum
from fastapi import FastAPI, HTTPException, Query
from pydantic import BaseModel, Field
app = FastAPI(title='API del catálogo', version='1.0.0')classEstado(str, Enum):
borrador ='borrador'
publicado ='publicado'
descatalogado ='descatalogado'classLibroEntrada(BaseModel):
titulo:str= Field(max_length=200)
isbn:str= Field(max_length=17)
precio: Decimal = Field(max_digits=7, decimal_places=2)
paginas:int= Field(default=0, ge=0)
estado: Estado = Estado.borrador
publicado_en: date |None=NoneclassLibro(LibroEntrada):id:int@app.get('/api/libros/')deflistar(estado: Estado |None=None,
limite:int= Query(default=20, le=100))->list[Libro]:
libros =[l for l in LIBROS.values()if estado isNoneor l.estado == estado]return libros[:limite]@app.get('/api/libros/{libro_id}')defobtener(libro_id:int)-> Libro:if libro_id notin LIBROS:raise HTTPException(404,'No existe ese libro.')return LIBROS[libro_id]@app.post('/api/libros/', status_code=201)defcrear(datos: LibroEntrada)-> Libro:
nuevo = Libro(id=len(LIBROS)+1,**datos.model_dump())
LIBROS[nuevo.id]= nuevo
return nuevo
Cincuenta líneas, sin ficheros de ajustes ni de rutas. Se arranca con:
bash
fastapi dev app/main.py
Y la idea central es esta: las anotaciones de tipo de Python son la especificación. Ese libro_id: int de la ruta hace cuatro cosas a la vez:
Convierte el texto de la dirección a entero.
Valida, devolviendo un error si no es un número.
Documenta, apareciendo en el esquema OpenAPI como entero.
Y ayuda al editor, porque es una anotación normal.
Es la misma idea que la lección 21 pedía a mano con un decorador para arreglar la documentación, aquí llevada al centro del diseño. Nada de esto es un invento de FastAPI: es Python estándar, y por eso no hay que aprender un lenguaje de declaración aparte.
Un cliente de un servicio comercial de nube, un sistema de informes de errores y dos detectores que miran cómo instalaste el paquete. Nada de eso hace falta para servir una API, y en un contenedor de producción son megabytes y superficie de ataque que nadie pidió.
La recomendación práctica: instala lo que necesites y no el ramo entero.
bash
pip install fastapi uvicorn[standard]
Es la misma disciplina que la lección 22 del módulo 2 pedía con las dependencias, y aquí se nota más porque el corchete parece inofensivo.
Primera: FastAPI no trae base de datos. Ni ORM, ni migraciones, ni panel de administración, ni sistema de usuarios, ni correo. Eso se elige y se monta, normalmente con SQLAlchemy y Alembic, y es la lección 26.
Para un proyecto que necesita todo eso, Django ya lo tiene resuelto y probado, y montarlo pieza a pieza son semanas. Para un servicio que habla con otra cosa y no tiene modelos propios, el armazón de Django es peso muerto.
Segunda: la asincronía es de primera clase. FastAPI la soporta de verdad porque nació así; Django la ha ido añadiendo y el ORM asíncrono aún tiene esquinas. Es la lección 26 y es el argumento técnico real.
Tercera: los errores son distintos, y hay que verlo.
400 Bad Request
{"titulo": ["Este campo es requerido."],
"isbn": ["Este campo es requerido."]}
Tres diferencias. El código es 422 y no 400, que es correcto según el estándar y lo usa casi nadie, así que quien consuma tu API tendrá que tratarlo aparte. La forma es una lista de objetos en vez de un diccionario por campo, más informativa y más incómoda de pintar en un formulario. Y están en inglés, sin traducción incluida, al revés que DRF.
Las tres se pueden cambiar con un manejador propio, y conviene hacerlo el primer día, porque cambiar el formato de los errores después es de los cambios que rompen, según la tabla de la lección 22.