Ir al contenido principal

Guía FastAPI: API de Ejemplo con Documentación

Guía FastAPI: API de Ejemplo con Documentación Automática

¡Nota importante! Este tutorial incluye un API de prueba funcional y muestra cómo aprovechar el sistema de documentación automática de FastAPI desde cero.

1. Instalación y Configuración del Entorno

a) Verificar Python

Asegúrate de tener Python 3.7 o superior instalado:

python --version

b) Crear un directorio para el proyecto

mkdir fastapi-ejemplo
cd fastapi-ejemplo

c) Crear entorno virtual

Es fundamental usar un entorno virtual para evitar conflictos de dependencias:

# Windows
python -m venv venv

# macOS/Linux
python3 -m venv venv

d) Activar el entorno virtual

# Windows
venv\Scripts\activate

# macOS/Linux
source venv/bin/activate
¡Importante! Cuando el entorno virtual esté activo, verás (venv) al inicio de tu prompt. Siempre activa el entorno virtual antes de trabajar en el proyecto.

e) Instalar dependencias

pip install fastapi uvicorn[standard]

Donde:

  • fastapi: El framework principal
  • uvicorn: Servidor ASGI de alto rendimiento
  • [standard]: Incluye dependencias adicionales recomendadas

f) Crear archivo requirements.txt

Para documentar las dependencias del proyecto:

pip freeze > requirements.txt

2. API de Ejemplo Completa

Crea un archivo main.py con endpoints demostrativos:

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

app = FastAPI(
    title="API de Ejemplo",
    description="API demostrativa con documentación automática",
    version="1.0.0"
)

# Modelo Pydantic para validación
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

class ItemResponse(BaseModel):
    id: int
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

# Base de datos ficticia
fake_db = {
    1: {"name": "Laptop", "price": 999.99, "description": "Laptop gamer", "tax": 0.15},
    2: {"name": "Mouse", "price": 25.50, "description": "Mouse inalámbrico", "tax": 0.10}
}

@app.get("/")
async def root():
    """Endpoint raíz que devuelve un mensaje de bienvenida"""
    return {
        "message": "Bienvenido a la API de ejemplo",
        "version": "1.0.0",
        "endpoints": {
            "items": "/items",
            "docs": "/docs o /redoc"
        }
    }

@app.get("/items/", response_model=dict)
async def read_items():
    """Devuelve todos los items de la base de datos ficticia"""
    return fake_db

@app.get("/items/{item_id}", response_model=dict)
async def read_item(item_id: int):
    """
    Devuelve un item específico por ID
    
    - **item_id**: ID del item a buscar (debe existir)
    """
    if item_id not in fake_db:
        raise HTTPException(status_code=404, detail="Item no encontrado")
    return {"id": item_id, **fake_db[item_id]}

@app.post("/items/", response_model=ItemResponse)
async def create_item(item: Item):
    """
    Crea un nuevo item en la base de datos
    
    - **name**: Nombre del item (requerido)
    - **description**: Descripción opcional
    - **price**: Precio (requerido)
    - **tax**: Impuesto opcional
    """
    new_id = max(fake_db.keys()) + 1 if fake_db else 1
    fake_db[new_id] = item.dict()
    return {"id": new_id, **fake_db[new_id]}

@app.put("/items/{item_id}", response_model=ItemResponse)
async def update_item(item_id: int, item: Item):
    """
    Actualiza un item existente
    
    - **item_id**: ID del item a actualizar
    - **item**: Datos del item actualizados
    """
    if item_id not in fake_db:
        raise HTTPException(status_code=404, detail="Item no encontrado")
    
    fake_db[item_id] = item.dict()
    return {"id": item_id, **fake_db[item_id]}

@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    """
    Elimina un item de la base de datos
    
    - **item_id**: ID del item a eliminar
    """
    if item_id not in fake_db:
        raise HTTPException(status_code=404, detail="Item no encontrado")
    
    deleted_item = fake_db.pop(item_id)
    return {"message": "Item eliminado exitosamente", "deleted_item": deleted_item}

@app.get("/health")
async def health_check():
    """Endpoint de salud para verificar que la API está funcionando"""
    return {"status": "healthy", "message": "API funcionando correctamente"}

3. Probando la API

Ejecuta el servidor de desarrollo:

uvicorn main:app --reload

Verás una salida similar a:

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [12345]
INFO:     Started server process [12346]
INFO:     Waiting for application startup.

Endpoints disponibles:

  • GET / - Página de inicio con información de la API
  • GET /items/ - Lista todos los items
  • GET /items/{id} - Obtiene un item específico
  • POST /items/ - Crea un nuevo item
  • PUT /items/{id} - Actualiza un item existente
  • DELETE /items/{id} - Elimina un item
  • GET /health - Verifica el estado de la API

Ejemplo de respuesta (GET /items/1):

{
    "id": 1,
    "name": "Laptop",
    "price": 999.99,
    "description": "Laptop gamer",
    "tax": 0.15
}

4. Documentación Automática

FastAPI genera automáticamente dos tipos de documentación interactiva:

a) Swagger UI (interactiva)

Accede en http://127.0.0.1:8000/docs

  • Permite probar los endpoints directamente desde el navegador
  • Muestra esquemas de request/response
  • Incluye los docstrings como descripciones
  • Validación automática de parámetros

b) ReDoc (documentación estática)

Accede en http://127.0.0.1:8000/redoc

  • Presentación más limpia para lectura
  • Organiza los endpoints por categorías
  • Mejor para documentación formal
¿Cómo funciona? FastAPI usa los estándares OpenAPI y JSON Schema. Toda la documentación se genera automáticamente a partir de:
  • Tipos de parámetros y modelos Pydantic
  • Docstrings en las funciones
  • Parámetros adicionales en la clase FastAPI
  • Decoradores response_model

5. Personalizando la Documentación

Puedes mejorar la documentación con más detalles:

@app.get("/items/{item_id}", 
         summary="Obtener item por ID", 
         response_description="Los datos del item solicitado",
         tags=["items"])
async def read_item(item_id: int):
    """
    Devuelve un item específico por ID
    
    Este endpoint permite obtener la información completa de un item
    utilizando su identificador único.
    
    - **item_id**: ID numérico del item (debe existir en la base de datos)
    - **returns**: Diccionario con id, name, price, description y tax del item
    
    ## Ejemplo de uso:
    ```
    GET /items/1
    ```
    
    ## Respuesta exitosa:
    ```json
    {
        "id": 1,
        "name": "Laptop",
        "price": 999.99,
        "description": "Laptop gamer",
        "tax": 0.15
    }
    ```
    """
    if item_id not in fake_db:
        raise HTTPException(
            status_code=404,
            detail="Item no encontrado",
            headers={"X-Error": "ID inválido"}
        )
    return {"id": item_id, **fake_db[item_id]}

Elementos adicionales para mejorar la documentación:

  • summary: Breve descripción del endpoint
  • response_description: Explicación de la respuesta
  • tags: Agrupación de endpoints en la documentación
  • Docstring en Markdown: Se renderiza en la UI
  • Ejemplos de código y respuestas
  • Errores: Los HTTPException también se documentan

6. Probando con cURL

Ejemplos de cómo probar la API desde la línea de comandos:

# Obtener todos los items
curl http://127.0.0.1:8000/items/

# Obtener un item específico
curl http://127.0.0.1:8000/items/1

# Crear un nuevo item
curl -X POST "http://127.0.0.1:8000/items/" \
     -H "Content-Type: application/json" \
     -d '{
       "name": "Teclado",
       "description": "Teclado mecánico",
       "price": 75.00,
       "tax": 0.12
     }'

# Verificar estado de la API
curl http://127.0.0.1:8000/health

7. Estructura del Proyecto

Tu proyecto debería tener la siguiente estructura:

fastapi-ejemplo/
├── venv/                 # Entorno virtual
├── main.py              # Archivo principal de la API
├── requirements.txt     # Dependencias del proyecto
└── README.md           # Documentación del proyecto (opcional)

8. Siguientes Pasos

Para continuar desarrollando tu API, puedes:

  • Agregar autenticación y autorización
  • Conectar una base de datos real (PostgreSQL, MySQL, etc.)
  • Implementar middleware para logging y CORS
  • Agregar tests unitarios
  • Configurar variables de entorno
  • Desplegar en producción
¡Consejo! La documentación automática es una de las principales ventajas de FastAPI. Siempre escribe buenos docstrings y utiliza modelos Pydantic para obtener documentación de alta calidad automáticamente.

Comentarios

Entradas populares de este blog

Instalación y Configuración de MySQL 5.7 en Ubuntu 24.04 LTS

Instalar MySQL 5.7 en Ubuntu 24.04 1. Descargar e instalar MySQL Copiar mkdir ~/mysql57 cd ~/mysql57 wget https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz sudo mv mysql-5.7.44-linux-glibc2.12-x86_64 /usr/local/mysql sudo ln -s /usr/local/mysql/bin/mysql /usr/local/bin/mysql 2. Instalar dependencias necesarias IMPORTANTE: Se descargan las versiones nuevas de las librerías y se las vincula con las librerías que necesita MySQL. Copiar sudo apt update # Reemplazo de libaio sudo apt install libaio1t64 # Reemplazo de libtinfo y ncurses sudo apt install libtinfo6 libncurses6 Copiar # Crear los enlaces simbólicos sudo ln -sf /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/libaio.so.1 sudo ln -sf /usr/lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5 sudo ln -sf /usr/lib/x86_64-linux-gnu/libncurses.so.6 /usr/lib/x86_64...

Instalar DeepSeek R1 1.5B en Ubuntu 24.04 sin GPU

Instalar DeepSeek en tu sistema sin GPU, pasos: Especificaciones del Entorno de Pruebas Componente Detalle SO Ubuntu Cinnamon 24.04 LTS x86_64 Kernel 6.8.0-51-generic CPU Intel i7-6820HQ (8 núcleos) @ 3.600GHz GPUs AMD ATI Radeon HD 8830M / R7 250 / R7 M465X Intel HD Graphics 530 RAM 15.882 GB (3.716 GB en uso) Resolución 1440x810 Escritorio Cinnamon 6.0.4 1. Instalar Git LFS sudo apt-get install git-lfs git lfs install 2. Clonar el repositorio cd /opt sudo mkdir deepseek && sudo chown $USER:$USER deepseek cd deepseek git clone https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B 3. Crear y activar un entorno virtual python -m ve...

Instalar Jasper Studio 6.21 para Ubuntu 24.04

Instalar js-studiocomm_6.21.3 en Ubuntu 24.4 Para instalar Jaspersoft Studio en Ubuntu 24.4, sigue estos pasos: 1. Descargar Jasper Studio Descarga la versión js-studiocomm_6.21.3 desde el siguiente enlace: Jaspersoft Studio 6.21.3 2. Crear el directorio de instalación mkdir /opt/jasperstudio 3. Mover el archivo descargado mv /dir_descarga/js-studiocomm_6.21.3_linux_x86_64.tgz /opt/jasperstudio/ cd /opt/jasperstudio 4. Extraer el archivo tar -xvzf js-studiocomm_6.21.3_linux_x86_64.tgz cd js-studiocomm_6.21.3 5. Ejecutar Jaspersoft Studio ./Jaspersoft\ Studio 6. Crear acceso directo en el escritorio Para facilitar el acceso, crea un archivo .desktop en el escritorio: gedit ~/Escritorio/jaspersoft-studio.desktop En el archivo jaspersoft-studio.desktop , agrega lo siguiente: [Desktop Entry] Version=1.0 Ty...