8. Documentación automática de FastAPI
📚 8.1 Swagger UI
Section titled “📚 8.1 Swagger UI”Qué es Swagger UI
Section titled “Qué es Swagger UI”Swagger UI es una interfaz web interactiva que permite explorar y probar tu API directamente desde el navegador. FastAPI la genera automáticamente sin configuración adicional.
| Característica | Descripción |
|---|---|
| URL | /docs |
| Interactiva | Permite probar endpoints |
| Automática | Se genera del código |
| Estándar | Basada en OpenAPI |
Acceder a Swagger UI
Section titled “Acceder a Swagger UI”from fastapi import FastAPI
app = FastAPI()
@app.get("/")def inicio(): return {"mensaje": "Hola"}
@app.get("/usuarios")def listar_usuarios(): return []
# Ejecutar: uvicorn main:app --reload# Acceder a: http://localhost:8000/docsFuncionalidades de Swagger UI
Section titled “Funcionalidades de Swagger UI”- Ver todos los endpoints: Lista completa de rutas disponibles
- Try it out: Botón para probar cada endpoint
- Ver parámetros: Muestra qué parámetros acepta cada ruta
- Ver respuestas: Muestra el formato de respuesta esperado
- Ejecutar peticiones: Envía peticiones reales a la API
Ejemplo: Probar endpoint en Swagger
Section titled “Ejemplo: Probar endpoint en Swagger”# 1. Ir a http://localhost:8000/docs# 2. Buscar el endpoint GET /usuarios# 3. Hacer clic en "Try it out"# 4. Completar los parámetros si los hay# 5. Hacer clic en "Execute"# 6. Ver la respuesta en "Response body"
# Swagger muestra:# - Curl command: cómo ejecutar desde terminal# - Request URL: la URL completa# - Response body: el JSON de respuesta# - Response headers: cabeceras HTTP📖 8.2 ReDoc
Section titled “📖 8.2 ReDoc”Qué es ReDoc
Section titled “Qué es ReDoc”ReDoc es una alternativa a Swagger UI con un diseño más limpio y orientado a documentación. Es ideal para compartir con usuarios de tu API.
| Característica | Descripción |
|---|---|
| URL | /redoc |
| Diseño | Limpio y profesional |
| Navegación | Menú lateral |
| Solo lectura | No permite probar endpoints |
Acceder a ReDoc
Section titled “Acceder a ReDoc”from fastapi import FastAPI
app = FastAPI( title="Mi API", description="API de ejemplo", version="1.0.0")
@app.get("/productos")def listar_productos(): """Obtiene la lista de todos los productos disponibles.""" return []
# Acceder a: http://localhost:8000/redocDiferencias entre Swagger y ReDoc
Section titled “Diferencias entre Swagger y ReDoc”| Aspecto | Swagger UI | ReDoc |
|---|---|---|
| URL | /docs | /redoc |
| Probar endpoints | Sí | No |
| Diseño | Funcional | Elegante |
| Uso ideal | Desarrollo | Documentación |
🔗 8.3 Cómo acceder a la documentación automática
Section titled “🔗 8.3 Cómo acceder a la documentación automática”URLs por defecto
Section titled “URLs por defecto”from fastapi import FastAPI
app = FastAPI()
# URLs de documentación automáticas:# Swagger UI: http://localhost:8000/docs# ReDoc: http://localhost:8000/redoc# OpenAPI JSON: http://localhost:8000/openapi.jsonPersonalizar URLs de documentación
Section titled “Personalizar URLs de documentación”from fastapi import FastAPI
app = FastAPI( docs_url="/documentacion", # Cambiar URL de Swagger redoc_url="/redoc-docs", # Cambiar URL de ReDoc openapi_url="/api/openapi.json" # Cambiar URL del JSON)
# Nuevas URLs:# Swagger: http://localhost:8000/documentacion# ReDoc: http://localhost:8000/redoc-docs# OpenAPI: http://localhost:8000/api/openapi.jsonDeshabilitar documentación
Section titled “Deshabilitar documentación”from fastapi import FastAPI
# Deshabilitar Swagger UIapp = FastAPI(docs_url=None)
# Deshabilitar ReDocapp = FastAPI(redoc_url=None)
# Deshabilitar ambos (producción)app = FastAPI( docs_url=None, redoc_url=None, openapi_url=None)📝 8.4 Descripción de endpoints
Section titled “📝 8.4 Descripción de endpoints”Agregar descripciones
Section titled “Agregar descripciones”FastAPI usa los docstrings de las funciones para documentar los endpoints.
from fastapi import FastAPI
app = FastAPI()
@app.get("/usuarios")def listar_usuarios(): """ Obtiene la lista de todos los usuarios registrados.
Retorna una lista de usuarios con su información básica. """ return []
@app.get("/usuarios/{usuario_id}")def obtener_usuario(usuario_id: int): """ Obtiene un usuario específico por su ID.
- **usuario_id**: ID único del usuario a buscar """ return {"id": usuario_id}
@app.post("/usuarios")def crear_usuario(): """ Crea un nuevo usuario en el sistema.
Requiere los siguientes campos: - **nombre**: Nombre completo del usuario - **email**: Correo electrónico válido - **password**: Contraseña (mínimo 8 caracteres) """ return {"mensaje": "Usuario creado"}Usar parámetros del decorador
Section titled “Usar parámetros del decorador”from fastapi import FastAPI
app = FastAPI()
@app.get( "/productos", summary="Listar productos", description="Obtiene todos los productos disponibles en el catálogo", response_description="Lista de productos con precio y stock", tags=["Productos"])def listar_productos(): return []
@app.post( "/productos", summary="Crear producto", description="Agrega un nuevo producto al catálogo", response_description="Producto creado con su ID asignado", tags=["Productos"], status_code=201)def crear_producto(): return {"id": 1}Organizar con tags
Section titled “Organizar con tags”from fastapi import FastAPI
app = FastAPI()
# Endpoints de usuarios@app.get("/usuarios", tags=["Usuarios"])def listar_usuarios(): """Lista todos los usuarios.""" return []
@app.post("/usuarios", tags=["Usuarios"])def crear_usuario(): """Crea un nuevo usuario.""" return {}
# Endpoints de productos@app.get("/productos", tags=["Productos"])def listar_productos(): """Lista todos los productos.""" return []
@app.post("/productos", tags=["Productos"])def crear_producto(): """Crea un nuevo producto.""" return {}
# En Swagger, los endpoints se agrupan por tags💡 8.5 Agregar ejemplos a los modelos
Section titled “💡 8.5 Agregar ejemplos a los modelos”Ejemplos en modelos Pydantic
Section titled “Ejemplos en modelos Pydantic”from fastapi import FastAPIfrom pydantic import BaseModel, Field
app = FastAPI()
class Producto(BaseModel): nombre: str = Field(..., example="Laptop Gaming") precio: float = Field(..., example=1299.99) stock: int = Field(0, example=50) categoria: str = Field(..., example="Electrónica")
@app.post("/productos")def crear_producto(producto: Producto): return producto
# En Swagger, el ejemplo aparece automáticamente en "Example Value"Usar Config con schema_extra
Section titled “Usar Config con schema_extra”from fastapi import FastAPIfrom pydantic import BaseModel
app = FastAPI()
class Usuario(BaseModel): nombre: str email: str edad: int
class Config: schema_extra = { "example": { "nombre": "Ana García", "email": "ana@email.com", "edad": 28 } }
@app.post("/usuarios")def crear_usuario(usuario: Usuario): return usuarioMúltiples ejemplos
Section titled “Múltiples ejemplos”from fastapi import FastAPI, Bodyfrom pydantic import BaseModel
app = FastAPI()
class Producto(BaseModel): nombre: str precio: float categoria: str
@app.post("/productos")def crear_producto( producto: Producto = Body( ..., examples={ "laptop": { "summary": "Ejemplo de laptop", "description": "Un producto de electrónica", "value": { "nombre": "Laptop Pro", "precio": 1499.99, "categoria": "Electrónica" } }, "libro": { "summary": "Ejemplo de libro", "description": "Un producto de librería", "value": { "nombre": "Python para todos", "precio": 29.99, "categoria": "Libros" } } } )): return producto
# En Swagger aparece un dropdown para elegir entre ejemplos🎨 8.6 Mejorar la documentación de la API
Section titled “🎨 8.6 Mejorar la documentación de la API”Configurar metadatos de la API
Section titled “Configurar metadatos de la API”from fastapi import FastAPI
app = FastAPI( title="API de E-Commerce", description=""" ## API para gestión de tienda en línea
Esta API permite: * **Gestionar productos** - CRUD completo * **Gestionar usuarios** - Registro y autenticación * **Procesar pedidos** - Crear y seguir pedidos
### Autenticación Algunos endpoints requieren token JWT en el header. """, version="2.0.0", terms_of_service="https://miapi.com/terminos", contact={ "name": "Soporte API", "url": "https://miapi.com/soporte", "email": "soporte@miapi.com" }, license_info={ "name": "MIT", "url": "https://opensource.org/licenses/MIT" })Describir tags
Section titled “Describir tags”from fastapi import FastAPI
tags_metadata = [ { "name": "Usuarios", "description": "Operaciones con usuarios. Registro, login y perfil.", }, { "name": "Productos", "description": "Gestión del catálogo de productos.", "externalDocs": { "description": "Documentación externa", "url": "https://docs.miapi.com/productos" } }, { "name": "Pedidos", "description": "Crear y gestionar pedidos de compra.", }]
app = FastAPI( title="Mi API", openapi_tags=tags_metadata)
@app.get("/usuarios", tags=["Usuarios"])def listar_usuarios(): return []
@app.get("/productos", tags=["Productos"])def listar_productos(): return []Ejemplo completo de API documentada
Section titled “Ejemplo completo de API documentada”from fastapi import FastAPI, HTTPException, Path, Queryfrom pydantic import BaseModel, Field, EmailStrfrom typing import List, Optionalfrom enum import Enum
# Metadatos de tagstags_metadata = [ { "name": "Usuarios", "description": "Gestión de usuarios del sistema" }, { "name": "Productos", "description": "Catálogo de productos disponibles" }]
# Crear aplicación con metadatosapp = FastAPI( title="API Demo", description="API de demostración con documentación completa", version="1.0.0", openapi_tags=tags_metadata)
# Modelos con ejemplosclass Usuario(BaseModel): nombre: str = Field(..., min_length=2, example="Ana García") email: EmailStr = Field(..., example="ana@email.com")
class UsuarioRespuesta(BaseModel): id: int = Field(..., example=1) nombre: str = Field(..., example="Ana García") email: str = Field(..., example="ana@email.com")
class Producto(BaseModel): nombre: str = Field(..., example="Laptop Gaming") precio: float = Field(..., gt=0, example=1299.99) stock: int = Field(0, ge=0, example=50)
# Endpoints documentados@app.get( "/usuarios", response_model=List[UsuarioRespuesta], tags=["Usuarios"], summary="Listar usuarios", description="Obtiene la lista completa de usuarios registrados")def listar_usuarios( activo: Optional[bool] = Query(None, description="Filtrar por estado activo")): """ Retorna todos los usuarios del sistema.
- **activo**: Filtro opcional para usuarios activos/inactivos """ return []
@app.post( "/usuarios", response_model=UsuarioRespuesta, tags=["Usuarios"], summary="Crear usuario", description="Registra un nuevo usuario en el sistema", status_code=201)def crear_usuario(usuario: Usuario): """ Crea un nuevo usuario con los datos proporcionados.
El email debe ser único en el sistema. """ return {"id": 1, **usuario.dict()}
@app.get( "/productos", response_model=List[Producto], tags=["Productos"], summary="Listar productos")def listar_productos( categoria: Optional[str] = Query(None, description="Filtrar por categoría"), precio_max: Optional[float] = Query(None, description="Precio máximo", gt=0)): """Obtiene todos los productos del catálogo.""" return []📝 Resumen
Section titled “📝 Resumen”
🐝