- 👤 Andrés Cruz
Ver Listado »La Guía Definitiva de Desarrollo en Python: De Cero a API REST con FastAPI
Python se ha consolidado como uno de los lenguajes de programación más influyentes y de más rápido crecimiento en el mundo. Su sintaxis limpia, su vasta biblioteca estándar y un ecosistema que abarca desde el desarrollo web y la ciencia de datos hasta la automatización y la inteligencia artificial, lo convierten en una herramienta indispensable para cualquier desarrollador.
En este SUPER post, te ofrezco un recorrido completo que te llevará desde los fundamentos del lenguaje y la configuración de un entorno de desarrollo profesional, hasta la construcción de APIs web de alto rendimiento con FastAPI, uno de los frameworks más modernos y eficientes del ecosistema. Abordaremos la configuración inicial, la gestión de entornos virtuales, los principios del desarrollo de APIs, la validación de datos con Pydantic, la autenticación, las pruebas y, finalmente, el despliegue de tu aplicación en la nube.
Prepárate para dominar las herramientas y técnicas que definen al desarrollo moderno en Python. Ya sea que estés comenzando tu viaje en la programación o que busques modernizar tus habilidades en el desarrollo de backend, esta guía te proporcionará el conocimiento práctico y detallado que necesitas para tener éxito.
Sección 1: Primeros Pasos con Python
Antes de construir aplicaciones complejas, es crucial dominar los fundamentos. Esta sección te guiará a través de la instalación de Python, la configuración de tu entorno de desarrollo y la comprensión de por qué los entornos virtuales son una práctica no negociable para cualquier proyecto profesional.
¿Por qué Python? El Lenguaje que Domina el Desarrollo Moderno
Python es un lenguaje de programación interpretado, multiplataforma y orientado a objetos que ha experimentado un crecimiento masivo en los últimos años. Su popularidad no es una casualidad; se debe a una combinación de simplicidad, poder y versatilidad.
Un Ecosistema para Todo
Python no se limita a un solo dominio. Su flexibilidad te permite construir:
- Aplicaciones Web: Utilizando frameworks robustos como Django, o microframeworks ágiles como Flask y FastAPI.
- Aplicaciones de Escritorio: Creando software multiplataforma que funciona en Windows, macOS y Linux.
- Ciencia de Datos y Machine Learning: Con librerías como NumPy, Pandas, Scikit-learn y TensorFlow, Python es el lenguaje de facto en este campo.
- Automatización y Scripting: Su sintaxis sencilla lo hace perfecto para automatizar tareas repetitivas.
Más de 127,000 Librerías
El Python Package Index (PyPI) alberga un repositorio masivo de librerías que puedes instalar y usar en tus proyectos con una simple línea de comando (pip install). Esto significa que rara vez tendrás que "reinventar la rueda".
Simplicidad y Productividad
Python fue diseñado para ser legible y expresivo. Permite a los desarrolladores escribir menos código para lograr los mismos resultados que en otros lenguajes, lo que se traduce en un desarrollo más rápido y un mantenimiento más sencillo.
Si estás buscando un lenguaje para aprender que sea demandado, potente y aplicable a casi cualquier problema que puedas imaginar, Python es, sin duda, la elección correcta.
Conoce más sobre la instalación y configuración inicial en nuestro artículo: Empezando con Python: ¿Porqué Python?, instalación y configuración.
Fundamentos Esenciales para Iniciar en Python
Aunque esta guía no es una introducción a la programación desde cero, un repaso de las herramientas básicas y conceptos de Python es esencial antes de sumergirnos en el desarrollo web.
La Consola Interactiva de Python
Una vez que tienes Python instalado y configurado en tu PATH, puedes acceder a su consola interactiva simplemente escribiendo python en tu terminal. Verás el prompt,, que indica que está listo para recibir comandos. Esta consola es una herramienta invaluable para probar pequeños fragmentos de código, explorar la funcionalidad de un objeto o realizar cálculos rápidos sin tener que crear un archivo .py.
Variables y Tipos de Datos
Python es un lenguaje de tipado dinámico, lo que significa que no necesitas declarar el tipo de una variable. El intérprete lo infiere en tiempo de ejecución.
# Cadenas de texto (string)
mi_string = "Hola, Mundo"
otro_string = 'También con comillas simples'
# Números enteros (int)
mi_entero = 10
# Números de punto flotante (float)
mi_float = 3.1416
# Booleanos (bool)
es_verdadero = True
es_falso = False
# Listas (list) - mutables y ordenadas
mi_lista = [1, "dos", 3.0, True]
# Tuplas (tuple) - inmutables y ordenadas
mi_tupla = (1, "dos", 3.0)
# Diccionarios (dict) - pares clave-valor
mi_diccionario = {"nombre": "Andres", "edad": 30}Estructuras de Control
Como en otros lenguajes, Python utiliza if, elif y else para condicionales, y for y while para bucles. La indentación es sintácticamente significativa; define los bloques de código.
# Condicionales
if mi_entero > 5:
print("Es mayor que 5")
elif mi_entero == 5:
print("Es igual a 5")
else:
print("Es menor que 5")
# Bucle for
for elemento in mi_lista:
print(elemento)
# Bucle while
contador = 0
while contador < 3:
print(f"Contador: {contador}")
contador += 1Funciones
Las funciones se definen con la palabra clave def. Pueden aceptar argumentos y devolver valores.
def saludar(nombre):
return f"Hola, {nombre}!"
mensaje = saludar("DesarrolloLibre")
print(mensaje) # Imprime "Hola, DesarrolloLibre!"Estos son los bloques de construcción sobre los cuales construiremos aplicaciones mucho más complejas.
Para un repaso más detallado, visita: Todo lo que necesitas saber para iniciar en Python.
Entornos Virtuales: La Herramienta Profesional Indispensable
Cuando comencé a desarrollar con Python, me encontré con un problema muy común: el "infierno de las dependencias". El Proyecto A necesitaba la versión 1.2 de una librería, mientras que el Proyecto B requería la versión 2.0 de la misma. Instalar una rompía la otra. La solución a este caos son los entornos virtuales.
Un entorno virtual es una herramienta que crea un directorio aislado que contiene una instalación de Python y todas las librerías y dependencias que tu proyecto necesita, separadas de la instalación global de Python y de otros proyectos.
¿Por qué son tan importantes?
- Aislamiento: Evita conflictos de versiones entre proyectos.
- Reproducibilidad: Permite recrear el mismo entorno en otra máquina (o en producción) con las versiones exactas de cada paquete, generalmente a través de un archivo requirements.txt.
- Limpieza: Mantiene tu instalación global de Python limpia, conteniendo solo las herramientas esenciales.
Creación y Activación de un Entorno Virtual con venv
venv es el módulo estándar de Python para crear entornos virtuales. El proceso es sencillo:
# 1. Navega a la carpeta de tu proyecto
cd mi-proyecto-python
# 2. Crea el entorno virtual (comúnmente llamado 'venv')
# En Windows
python -m venv venv
# En macOS/Linux
python3 -m venv venv
# 3. Activa el entorno virtual
# En Windows (PowerShell)
.\venv\Scripts\Activate.ps1
# En macOS/Linux
source venv/bin/activateUna vez activado, tu prompt de la terminal cambiará, usualmente prefijado con (venv), indicando que cualquier paquete que instales con pip se instalará dentro de este entorno aislado.
Manejando Dependencias con requirements.txt
Dentro de un entorno activado, puedes instalar las dependencias de tu proyecto. Es una buena práctica listarlas en un archivo requirements.txt.
# Instalar un paquete
pip install fastapi
# Generar el archivo requirements.txt con las dependencias actuales
pip freeze > requirements.txt
# En otra máquina (o en producción), instalar todas las dependencias del archivo
pip install -r requirements.txtNunca empieces un proyecto de Python sin crear y activar primero un entorno virtual. Es la base de un flujo de trabajo profesional y reproducible.
Domina la creación de entornos y la clonación de proyectos en nuestras guías: Crear entornos virtuales en Python y Clona un proyecto de GitHub y crea tu entorno virtual.
Sección 2: Construyendo APIs de Alto Rendimiento con FastAPI
Una vez dominados los fundamentos de Python y la gestión de entornos, es hora de construir algo para la web. Mientras que Django es un framework "con baterías incluidas", los microframeworks como Flask y FastAPI ofrecen un enfoque más ligero y flexible, ideal para la creación de APIs. En esta sección, nos sumergiremos de lleno en FastAPI, un framework moderno que destaca por su increíble rendimiento y su facilidad de uso.
¿Qué es FastAPI?
FastAPI es un framework más moderno diseñado para crear y diseñar APIs con Python web y es que no hay framework más rápido para hacer APIs y poder consumirlas con otras tecnologías, por supuesto, también podemos convertir en un framework más de propósito general como Flask en caso de que sea necesario.
Aunque, en definitiva, es un framework diseñado para crear APIs, así que, aquí puedes ir viendo la diferencia entre ambos frameworks.
Ventajas
- FastAPI es un framework muy rápido debido a su naturaleza asíncrona; fácilmente, podemos definir funciones de este tipo.
- Documentación automática: Genera automáticamente documentación para tus APIs, por lo tanto, podemos ver y probar los recursos que creemos directamente del navegador.
- Validación de datos: Ofrece validación automática de tipos y datos en la API, nuevamente, es un framework creado para crear APIs principalmente.
¿Cuánto tiempo se tarda en aprender Flask y FastAPI?
Ambos frameworks son más sencillos de iniciar que el todo poderoso Django, son microframeworks, lo que significa, que podemos crear nuestra aplicación con pocas líneas de código, y cuando digo pocas son pocas:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'El código anterior representa a una aplicación en Flask, si, una aplicación COMPLETA con todas las letras, la cual, se ejecuta en un solo archivo, a diferencia de Django que tenemos un montón de archivos y carpetas que representan a nuestro proyecto, y es que ambos frameworks aunque sean de tipo web, siguen filosofías distintas como comentamos antes, Flask y FastAPI son microframework y Django uno con todo incluido.
Por lo tanto, al poder ir agregando código y automáticamente poder ver en tiempo real lo que representa ese código, si es una nueva ruta, si es una página HTML, si arruinaste la aplicación… Así que, si quieres iniciar en el desarrollo web con Python, estos son tus frameworks recomendados.
¿Por qué FastAPI? Una Comparación con Flask
Tanto Flask como FastAPI son microframeworks, lo que significa que proporcionan un núcleo minimalista y te dan la libertad de elegir las herramientas y librerías que quieres usar. Sin embargo, FastAPI introduce varias ventajas clave que lo hacen especialmente adecuado para el desarrollo de APIs modernas.
Flask: Simplicidad y Madurez
Flask ha sido durante mucho tiempo el microframework de referencia. Es extremadamente simple de aprender, flexible y cuenta con una gran comunidad y una vasta colección de extensiones. Es una opción excelente y sólida, especialmente para aplicaciones web tradicionales.
FastAPI: Rendimiento y Características Modernas
FastAPI, aunque más nuevo, está construido sobre dos pilares que le dan una ventaja competitiva:
- Rendimiento Asíncrono: FastAPI está construido sobre Starlette y Uvicorn, lo que le permite manejar peticiones de forma asíncrona (usando async y await). Esto se traduce en un rendimiento a la par con frameworks de Node.js y Go, ideal para aplicaciones con alta concurrencia.
- Validación de Datos con Pydantic: FastAPI utiliza type hints de Python y la librería Pydantic para validar, serializar y deserializar datos automáticamente. Esto no solo reduce drásticamente el código repetitivo, sino que también previene una gran cantidad de errores.
- Documentación Automática e Interactiva: Basándose en los type hints y la validación de Pydantic, FastAPI genera automáticamente documentación interactiva para tu API (usando los estándares OpenAPI y Swagger UI). Puedes probar tus endpoints directamente desde el navegador, lo cual es una ventaja inmensa para el desarrollo y para los consumidores de tu API.
A lo que me refiero con la frase anterior, es que, Flask está pensado para aplicaciones más específicas o sencillas, no es que no puedas hacer aplicaciones completas, complejas y grandes, claro que puedes, lo mismo aplica para frameworks como CodeIgniter, pero, te tocaría implementar funcionalidades que probablemente se encuentran más desarrolladas en frameworks más grandes como lo son Laravel y Django.
Por ejemplo, si quieres crear una API Rest con protección por tokens y sesión, lo puedes hacer en Flask , pero, en Django es mucho más fácil y rápido al emplear DRF; entonces, el propósito de ser desarrollador es saber cuando tienes que emplear una tecnología y cuando tienes que emplear otra tecnología, viendo sus ventajas, desventajas y adecuandolo lo mejor posible al proyecto que quieres llevar a cabo.
Siguiendo hablando de las Rest Apis, Si tu proyecto qué quieres crear es una RestApi, entonces, FastAPI es para tí, que como indica su nombre, está pensado para crear APIs, al proveer una documentación automática por cada recurso que crees, lo convierten en un gran candidato para tal fin.
Entonces, cuál elegir
Habiendo comentado lo anterior, al ser de propósito más general querer crear una aplicación web tipo blog, foros… en lugar de una API Rest y cuando estamos aprendiendo usualmente primero comenzamos a crear aplicaciones webs sencillas empleando templates en HTML.
Mi elección sería que primero aprender Flask, aparte de que FastAPI maneja algunas implementaciones que pueden ser un poco abstractas como la documentación automática Pydentic para las validaciones de los modelos, inyección de dependencias… que ojo todo esto es excelente, pero para nuevos desarrolladores webs en Python y sobre todo si vienes de PHP o Node, pienso que puede ser un poco difícil de digerir, si lo comparamos con Flask, el cual tiene una estructura mucho más similar a otros tipos de frameworks webs basados en PHP o JavaScript.
En resumen, si bien Flask es una opción fantástica y versátil, las características nativas de FastAPI para el desarrollo asíncrono, la validación de datos y la auto-documentación lo convierten en la opción superior para construir APIs RESTful robustas y de alto rendimiento en Python hoy en día.
¿Qué debo conocer antes de trabajar con Flask o FastAPI?
Ya este punto te lo respondí un poco antes en esta y otras publicaciones, pero, si Flask es tu primer framework web, ya sea que vienes de otros o es el primero con el cual trabajas, si, te lo recomiendo enormemente, es un framework evolutivo, en el cual cada cambio que hacemos lo puedes ver reflejado por pantalla lo cual es excelente para aprender a programar.
También, al igual que en Django, a la final, estamos usando Python con TODAS las ventajas que esto nos da familiarizarse con el lenguaje para que luego puedes abordar temas que son propios del framework y con esto, no sentirte perdido, revisa la documentación oficial y ve si te vez programando en esta maravilla.
Por supuesto, debes de conocer la trilogía del mal de HTML, CSS y JavaScript, sobre todo las dos primeras, ya que de poco sirve si hacemos la mejor app administrativa pero nadie la usa porqué luce horrenda.
¿Por qué aprender Flask/FastAPI? o ¿Vale la pena aprender Flask/FastAPI?, qué habilidades debo de tener
Flask es un framework multipropósito y tambien FastAPI (aunque como comentamos más de propósito específico para crear APIs) si quieres aprender Python web, siempre considero que es necesario aprender al menos dos frameworks webs para tener una visión más amplia sobre cómo funcionan y poder tener una mente crítica sobre cuales son las ventajas y desventajas de cada framework y seleccionar el mejor según la situación, aunque esto suene a mucho trabajo, al a final, los frameworks webs tienen más similitudes que diferencias en lo que se refiere su organización, que es lo más importante para entenderlos.
Y si, un rotundo sí que vale la pena aprender Flask o FastAPI, primeramente, considero mejor Flask al ser de propósito general y FastAPI pudieras tomarlo para aprenderlo después de Flask/Django.
Flask es un framework con muchas características que permiten al igual que Django, crear cualquier aplicación y podrás dominarlo en pocas semanas.
Quieres un proyecto funcional en unas pocas semanas, USA DJANGO, al tener tantas funcionalidades, podrás crear tu proyecto de ensueño en poco tiempo.
Si estás aprendiendo a crear aplicaciones webs con Python, entonces Flask será más fácil de manejar que Django.
Lo malo de Flask/FastAPI
Como todo en la vida, hay cositas que se pueden complicar que aunque no es un problema del framework en sí, si lo es del paradigma que emplea que es el de un microframework y es que Flask es un framework muy moldeable, es decir que podemos hacer lo mismo de varias formas lo cual es bueno y malo al mismo tiempo, bueno porqué no nos vemos limitados pero malo al momento de empezar ya que rápidamente podemos seguir malas prácticas en el desarrollo con Flask lo cual no es bueno al momento de empezar; de una vez aprovecho y te comento de que cuento con mucho material tanto gratuito como de pago para desarrollar en Flask en el cual, te enseño Flask desde cero, desde sus bases hasta tener un buen nivel en el mismo.
Este comentario anterior, también lo puedes aplicar a FastAPI que en resumen, sería el segundo framework que te recomendaría aprender o ir directamente a Django.
Otro aspecto negatívo de Flask, es que, en comparación a Django, se siente un poco abandonado por los desarrolladores, no hacen actualizaciones constantes y sobre todo muchas de las extensiones se encuentran desactualizadas-
Un aspecto negativo de FastAPI si lo comparamos con Flask, es que FastAPI aunque puedes crear más que simples APIs por ejemplo, una API Rest, para configurar un app tradicional con un manejador de templates como Jinja y SQLAlchemy, requiere de mayores configuraciones si lo comparamos con Flask que por ejemplo, al instalar Flask ya viene con el motor de plantillas de Jinja listo para emplear.
Por qué pasé hay personas que pasan de Django a Flask/Fast API
Django es un framework web Python de alto nivel que fomenta un desarrollo rápido y un diseño limpio y pragmático.
FastAPI es un framework web moderno, rápido (de alto rendimiento) para crear API
Flask es un microframework para poder realizar apps completamente personalizables, no digo que Django sea malo, de Python web, es mi framework favorito, pero es siempre bueno tener perspectivas, te comento una historia:
Cuando se usaba solo Django, sin ningún equipo o compañero de trabajo, era rápido pero a veces complejo. Django es bueno para crear cosas tipo MVP, pero cuando quieres construir e implementar cosas a gran escala, se vuelve difícil construir y terminar solo. Y su Rest API, Django Rest Framework es genial para cosas CRUD que son mucho más simples cuando quieres usar todos los aspectos de Rest Api y tienes la flexibilidad que lleva algo de tiempo profundizar en la documentación y la comunidad.
Al unirme a una startup como Backend Developer éramos solo 3 personas y tuve que cambiar códigos PHP a Python y agregar nuevas funcionalidades. Y el código PHP era monolítico como lo es Django por estructura y decidimos que lo brindaremos localmente en el futuro y que cada página o lógica del sistema principal debería tener sus propios microservicios para escalar y desactivar para nuestro uso y el uso de los clientes en sus servidores. . Luego comenzamos a pensar y decidimos que usar Flask sería más rápido para la producción y escalable y mantenible para Rest API y tenía casos de uso muy interesantes para nuestro proyecto.
Diferencias
Las principales diferencias que nos gustaron en Flask fueron las que consolidaron nuestro trabajo.
- Flask es liviano y fácil de comenzar si conoce bien Python y el desarrollo web.
- Dispone de documentación muy amplia y estructura de proyectos en la web como casos de uso.
- Es fácil adoptar e iniciar pequeñas tareas.
- Django es más complejo (baterias incluidas, todo tiene ventajas y desventajas en la vida) en una arquitectura de microservicios. Porque tienes que escalar y administrar cada servicio y Django es pesado y no muy escalable en el entorno de Kubernetes porque tiene muchos paquetes precargados.
- En aquel entonces no tenía soporte asíncrono y Flask tampoco, es por eso que Django no tuvo una victoria para nosotros.
- Flask era mejor para el entorno de desarrollo, se podía ejecutar en la ventana acoplable muy rápido sin mucha configuración y Gunicorn era mucho más liviano.
- Aquí no digo que Flask/Fast API sea mejor que Django, pero creo que Flask/Fastapi es fácil y mucho más manejable, escalable para startups y equipos con muchos ingenieros de backend.
- Además, para aquellos que quieran brindar un servicio local, pueden cambiar cualquiera de los servicios de CPU y RAM sin estar conectados a un Big Monolith.
"Hola Mundo" en FastAPI: De la Instalación al Primer Endpoint
Empezar con FastAPI es sorprendentemente rápido. Siguiendo las buenas prácticas, lo haremos dentro de un entorno virtual.
1. Instalación de Dependencias
Necesitamos dos paquetes principales: fastapi y un servidor ASGI como uvicorn para ejecutar nuestra aplicación.
# Activa tu entorno virtual primero
$ pip install fastapi uvicorn[standard]2. Creando el Primer Endpoint
Crea un archivo llamado api.py con el siguiente contenido:
from fastapi import FastAPI
# 1. Crea una instancia de la aplicación FastAPI
app = FastAPI()
# 2. Define un "decorador de ruta" para el endpoint raíz ("/") con el método GET
@app.get("/")
def hello_world():
# 3. La función que se ejecuta cuando se accede a la ruta
# FastAPI convierte automáticamente los diccionarios de Python a JSON
return {"hello": "world"}Analicemos el código:
- Importamos la clase
FastAPI. - Creamos una instancia
appque será el núcleo de nuestra API. - Usamos el decorador
@app.get("/")para asociar la funciónhello_worlda las peticiones GET en la ruta raíz. FastAPI tiene decoradores para todos los métodos HTTP estándar (@app.post,@app.put,@app.delete, etc.). - La función devuelve un diccionario, y FastAPI se encarga de serializarlo a una respuesta JSON con el Content-Type adecuado.
3. Ejecutando el Servidor de Desarrollo
Desde la terminal, en la misma carpeta donde está api.py, ejecuta el servidor Uvicorn:
$ uvicorn api:app --reloadapi: Es el nombre de tu archivo Python (api.py).app: Es el nombre de la instancia de FastAPI que creaste dentro del archivo.--reload: Es una bandera muy útil que reinicia el servidor automáticamente cada vez que guardas cambios en el código.
Ahora, si abres tu navegador y vas a http://127.0.0.1:8000, verás la respuesta JSON: {"hello":"world"}.
La Magia de la Documentación Automática
Pero eso no es todo. FastAPI ya ha generado la documentación para ti. Ve a:
- http://127.0.0.1:8000/docs: Verás la interfaz interactiva de Swagger UI.
- http://127.0.0.1:8000/redoc: Verás una interfaz de documentación alternativa con ReDoc.
Desde Swagger UI, puedes ver tus endpoints, sus parámetros, sus respuestas y ¡probarlos en vivo! Este es el poder de FastAPI desde el primer minuto.
Sigue los pasos iniciales en nuestras guías: Instalación de Paquetes y Hola Mundo en FastAPI.
Validación de Datos con Pydantic
Una de las características más potentes de FastAPI es su integración nativa con Pydantic para la validación de datos. Pydantic utiliza los type hints de Python para definir modelos de datos, y FastAPI los usa para:
- Validar los datos de las peticiones entrantes (cuerpos JSON, parámetros de consulta, etc.).
- Convertir los datos al tipo de Python correcto.
- Generar errores de validación claros y detallados si los datos no cumplen con el modelo.
- Serializar los datos de respuesta al modelo definido.
- Generar los esquemas JSON que alimentan la documentación automática de OpenAPI.
Migrando de Pydantic V1 a V2: Conceptos Clave
Con la llegada de Pydantic V2, reescrito en Rust para un rendimiento aún mayor, cambiaron algunas sintaxis. Entender estos cambios es entender cómo funciona Pydantic hoy en día.
Definimos nuestros modelos de datos creando clases que heredan de pydantic.BaseModel.
from pydantic import BaseModel
class Task(BaseModel):
id: int
name: str
description: str | None = None # Un campo opcionalCambios en la Configuración del Modelo
Anteriormente, la configuración del modelo se hacía en una subclase anidada llamada Config. En Pydantic V2, se renombró a ConfigDict y los valores se definen en un diccionario.
Un cambio crucial fue orm_mode, que permitía a Pydantic crear modelos a partir de objetos de un ORM como SQLAlchemy. Ahora se llama from_attributes.
# Pydantic V1
class Task(BaseModel):
...
class Config:
orm_mode = True
# Pydantic V2
from pydantic import ConfigDict
class Task(BaseModel):
model_config = ConfigDict(from_attributes=True)
...Otro cambio fue schema_extra, usado para proveer datos de ejemplo para la documentación. Ahora se llama json_schema_extra.
# Pydantic V1
class Config:
schema_extra = {"example": {"name": "Mi Tarea", "description": "Hacer algo"}}
# Pydantic V2
model_config = ConfigDict(
json_schema_extra={"examples": [{"name": "Mi Tarea", "description": "Hacer algo"}]}
)Al usar estos modelos en tus endpoints, FastAPI hace la magia por ti:
@app.post("/tasks/")
async def create_task(task: Task):
# 'task' aquí es una instancia de la clase Task de Pydantic.
# FastAPI ya ha validado que el JSON de la petición
# cumple con la estructura y tipos definidos.
return taskSi envías un JSON sin el campo name o con un id que no es un entero, FastAPI devolverá automáticamente un error 422 Unprocessable Entity con un detalle del problema.
Conoce los detalles de la migración y las mejores prácticas en: Migrando una aplicación en FastAPI de Pydantic V1 a V2 y Datos de Ejemplo del Request FastAPI.
Renderizando HTML con Jinja2
Aunque FastAPI está optimizado para APIs, también puede servir páginas HTML, convirtiéndose en una alternativa viable a Flask o Django para aplicaciones web tradicionales. La forma más común de hacerlo es usando el motor de plantillas Jinja2.
Configuración de Jinja2
Primero, instala Jinja2:
$ pip install jinja2Luego, en tu aplicación, crea una instancia de Jinja2Templates, especificando el directorio donde guardarás tus plantillas HTML.
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
app = FastAPI()
# Apunta al directorio 'templates'
templates = Jinja2Templates(directory="templates")
@app.get("/")
async def read_root(request: Request):
# El "contexto" son los datos que pasas a la plantilla
context = {"request": request, "titulo": "Guía de FastAPI", "items": ["Manzana", "Pera", "Naranja"]}
return templates.TemplateResponse("index.html", context)El objeto request es obligatorio en el contexto. TemplateResponse renderizará la plantilla index.html con los datos proporcionados.
Sintaxis de la Plantilla Jinja2
Crea una carpeta templates y dentro un archivo index.html.
<!DOCTYPE html>
<html>
<head>
<title>{{ titulo }}</title> <!-- Imprime una variable -->
</head>
<body>
<h1>{{ titulo }}</h1>
<ul>
{% for item in items %}<!-- Estructura de control: bucle for -->
<li>{{ item }}</li>
{% endfor %}
</ul>
{% if items|length > 2 %}<!-- Condicional y filtro -->
<p>¡Hay más de dos ítems!</p>
{% endif %}
</body>
</html>Jinja2 utiliza:
{{ ... }}para imprimir variables.{% ... %}para estructuras de control como bucles y condicionales.- Filtros (
|length) para transformar datos dentro de la plantilla.
Esta separación de la lógica (Python) y la presentación (HTML) es una práctica fundamental en el desarrollo web.
Aprende a integrar Jinja2 en tu proyecto en: Primeros pasos con Jinja y FastAPI.
Autenticación y Seguridad con Tokens
Rara vez una API estará completamente abierta. Proteger los endpoints es crucial. Un método común y robusto es la autenticación basada en tokens, como OAuth2 con Bearer Tokens.
FastAPI proporciona herramientas de seguridad que se integran perfectamente con la documentación automática.
Esquema de Seguridad Básico
Podemos definir un esquema de seguridad que le indique a FastAPI (y a la documentación de Swagger) que esperamos un token en la cabecera Authorization.
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
app = FastAPI()
async def get_current_user(token: str = Depends(oauth2_scheme)):
# Aquí iría la lógica para validar el token:
# 1. Decodificar el token (si es un JWT).
# 2. Buscar al usuario en la base de datos con la info del token.
# 3. Si el token es inválido o el usuario no existe, lanzar una excepción.
user = fake_users_db.get(token) # Lógica de ejemplo
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
return user
@app.get("/users/me")
async def read_users_me(current_user: dict = Depends(get_current_user)):
# Si la petición llega aquí, 'get_current_user' se ejecutó exitosamente.
# El token es válido y tenemos los datos del usuario.
return current_userLa clave es Depends(get_current_user). FastAPI ejecutará esta función "dependencia" antes de llamar a la función de la ruta. La dependencia valida el token y devuelve los datos del usuario. Si la validación falla, la dependencia lanza una excepción HTTP y la ejecución de la ruta se detiene.
Generación de Tokens (Endpoint de Login)
Necesitarás un endpoint (ej. /token o /login) donde el usuario envía su usuario y contraseña para obtener un token válido.
from fastapi.security import OAuth2PasswordRequestForm
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
# 1. Validar usuario y contraseña (form_data.username, form_data.password)
user = authenticate_user(fake_users_db, form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=400, detail="Incorrect username or password")
# 2. Crear el token de acceso
access_token = create_access_token(data={"sub": user["username"]})
return {"access_token": access_token, "token_type": "bearer"}OAuth2PasswordRequestForm es una dependencia que parsea el cuerpo de la petición esperando username y password. La función create_access_token generaría el token (usualmente un JSON Web Token - JWT).
Esta integración no solo protege tu API, sino que también añade una interfaz de "Authorize" en Swagger UI, permitiendo a los desarrolladores autenticarse y probar los endpoints protegidos fácilmente.
Implementa un sistema de autenticación completo en: Autenticación mediante Tokens en FastAPI.
Pruebas Unitarias con Pytest y TestClient
Las pruebas automáticas son esenciales para garantizar que tu API funcione como se espera y para prevenir regresiones cuando añades nuevas características. FastAPI se integra a la perfección con Pytest, y proporciona una clase TestClient para realizar peticiones a tu API en un entorno de prueba.
Configuración del Entorno de Pruebas
Primero, instala pytest y requests (necesario para TestClient).
$ pip install pytest requestsEscribiendo Pruebas
Crea un archivo test_api.py. TestClient funciona como la librería requests, pero llama a tu aplicación FastAPI directamente.
from fastapi.testclient import TestClient
from .api import app # Importa tu instancia de FastAPI
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"hello": "world"}
def test_create_task_success():
response = client.post(
"/tasks/",
json={"id": 1, "name": "Tarea de prueba"},
)
assert response.status_code == 200
data = response.json()
assert data["name"] == "Tarea de prueba"
assert data["description"] is None
def test_create_task_invalid_data():
# Probar un request sin el campo 'name' requerido
response = client.post(
"/tasks/",
json={"id": 2, "description": "Falta el nombre"},
)
# FastAPI/Pydantic debería devolver un error 422
assert response.status_code == 422Para ejecutar las pruebas, simplemente corre pytest en tu terminal.
pytestpytest descubrirá y ejecutará automáticamente los archivos y funciones que sigan sus convenciones de nombrado (archivos test_*.py, funciones test_*).
Con TestClient, puedes simular peticiones a todos tus endpoints, incluyendo cabeceras, cuerpos JSON y parámetros de consulta, y hacer aserciones sobre el código de estado y la respuesta, garantizando la fiabilidad de tu API.
Aprende a configurar tu suite de pruebas en: Pruebas/Testing en FastAPI con Pytest.
Sección 3: Conceptos Avanzados y Despliegue
Una vez que has construido y probado tu aplicación, los siguientes pasos son entender conceptos más profundos del lenguaje y llevar tu creación al mundo real. Esta sección cubre un tema avanzado de la programación orientada a objetos en Python y te guía a través del proceso de despliegue en una plataforma en la nube moderna.
Herencia Múltiple y el Orden de Resolución de Métodos (MRO)
Python es uno de los pocos lenguajes populares que soporta herencia múltiple de forma nativa. Esto significa que una clase puede heredar atributos y métodos de más de una clase padre, lo que permite una composición de comportamientos muy potente (similar a los mixins o traits en otros lenguajes).
class Lector:
def leer(self):
print("Leyendo...")
class Escritor:
def escribir(self):
print("Escribiendo...")
class LectorEscritor(Lector, Escritor):
pass
mi_objeto = LectorEscritor()
mi_objeto.leer() # Heredado de Lector
mi_objeto.escribir() # Heredado de EscritorEl "Problema del Diamante" y el MRO
La herencia múltiple introduce un problema potencial: ¿qué pasa si múltiples clases padre tienen un método con el mismo nombre? ¿Cuál se ejecuta? Esto se conoce como el "problema del diamante".
Python resuelve esta ambigüedad usando un algoritmo determinista llamado C3 linearization, que genera un Method Resolution Order (MRO). El MRO es una lista ordenada de las clases que se consultarán para encontrar un método. Siempre puedes inspeccionar el MRO de una clase usando el atributo __mro__.
print(LectorEscritor.__mro__)
# Salida:
# (<class '__main__.LectorEscritor'>,
# <class '__main__.Lector'>,
# <class '__main__.Escritor'>,
# <class 'object'>)Esto nos dice que si llamamos a un método en LectorEscritor, Python lo buscará primero en LectorEscritor, luego en Lector, luego en Escritor, y finalmente en la clase base object.
El Caso del Constructor __init__
El MRO es especialmente importante al llamar a constructores de clases padre usando super().__init__(). En una cadena de herencia múltiple, super() no llama necesariamente al __init__ de la clase padre directa, sino al __init__ de la *siguiente clase en el MRO*.
Esto puede ser confuso. A veces, para tener un control explícito sobre qué constructor se llama, es más claro llamarlo directamente por el nombre de la clase padre, pasando self explícitamente.
class BasePayment(PaymentPaypalClient, PaymentStripeClient):
def __init__(self):
# En lugar de super(), que seguiría el MRO...
# super().__init__()
# Llamamos explícitamente al constructor que nos interesa
PaymentPaypalClient.__init__(self)Comprender el MRO es clave para depurar comportamientos inesperados en jerarquías de clases complejas y para usar la herencia múltiple de manera efectiva.
Explora un caso práctico de este concepto en un sistema de pagos en: Herencia múltiple en Python y el MRO.
Despliegue de Aplicaciones Python con Railway
Escribir el código es solo la mitad del trabajo. Para que el mundo pueda usar tu aplicación, necesitas desplegarla en un servidor. Plataformas como Railway han simplificado enormemente este proceso, ofreciendo una experiencia similar a la del difunto plan gratuito de Heroku.
Railway es una plataforma de despliegue en la nube que toma tu código fuente (generalmente desde un repositorio de GitHub), detecta el lenguaje y el framework, y automáticamente construye y despliega tu aplicación en un contenedor.
Características Clave de Railway
- Despliegue desde GitHub: Simplemente conecta tu repositorio. Railway detectará los push a tu rama principal y redesplegará automáticamente.
- Detección Automática: Si encuentra un archivo requirements.txt, sabe que es una aplicación Python e instalará las dependencias. Si ve un package.json, lo tratará como Node.js.
- Variables de Entorno: Proporciona una interfaz gráfica para gestionar secretos y configuraciones, como claves de API o credenciales de base de datos.
- Bases de Datos y Servicios: Puedes aprovisionar bases de datos (PostgreSQL, MySQL, Redis, etc.) con un solo clic y se conectarán automáticamente a tu aplicación.
- Dominio Público: Genera automáticamente una URL pública para tu aplicación, y permite configurar dominios personalizados.
Proceso de Despliegue Típico
- Prepara tu aplicación: Asegúrate de que tienes un archivo requirements.txt. Para una aplicación FastAPI, también necesitarás un Procfile, un archivo de texto que le dice a la plataforma cómo ejecutar tu aplicación.
# Procfile
web: uvicorn api.main:app --host 0.0.0.0 --port $PORT$PORT es una variable de entorno que Railway proporcionará dinámicamente.
- Crea un proyecto en Railway: Inicia sesión, crea un nuevo proyecto y elige "Deploy from GitHub repo".
- Selecciona tu Repositorio: Railway lo analizará y comenzará el proceso de construcción.
- Configura Variables de Entorno: Añade cualquier clave de API o configuración que tu aplicación necesite.
- ¡Listo! Railway construirá tu aplicación en un contenedor Docker, la desplegará y te dará una URL para acceder a ella.
Plataformas como Railway eliminan gran parte de la complejidad de la administración de sistemas (DevOps), permitiendo a los desarrolladores centrarse en lo que mejor saben hacer: escribir código.
Descubre cómo desplegar tus proyectos paso a paso en: Railway, deploy de tus aplicaciones como en Heroku GRATIS.
Conclusión: El Ecosistema Moderno de Python
Hemos completado un viaje exhaustivo a través del desarrollo moderno con Python. Empezamos con los cimientos, entendiendo por qué Python es tan dominante y cómo configurar un entorno de trabajo profesional con entornos virtuales. Luego, nos sumergimos de lleno en la construcción de APIs de alto rendimiento con FastAPI, cubriendo desde el primer "Hola Mundo" hasta temas cruciales como la validación de datos, la autenticación basada en tokens y la importancia de las pruebas automatizadas.
Finalmente, exploramos conceptos más profundos del lenguaje como la herencia múltiple y cerramos el ciclo de desarrollo aprendiendo a desplegar nuestra aplicación en la nube con plataformas como Railway. Este recorrido demuestra que Python, lejos de ser solo un lenguaje de scripting, es un ecosistema completo y robusto, capaz de llevar una idea desde su concepción hasta una aplicación global, segura y escalable.
El desarrollo de software es un campo en constante evolución. Las herramientas que hemos explorado aquí —FastAPI, Pydantic, Pytest— representan el estado del arte en el desarrollo de backend con Python. Te animamos a seguir explorando, construyendo y profundizando en estos conceptos. El poder y la elegancia de Python están a tu disposición para crear la próxima gran aplicación.