IF0100 - Programación OO II

Unidad 3: Desarrollo Web con FastAPI

Clase 1: Introducción a FastAPI

Martes, 24 de marzo de 2026 Semana 9 - Martes (120 minutos) 60 min Teoría 60 min Práctica

E3: Prototipo Web - Entrega 26/03/2026

Objetivos de Aprendizaje

Al finalizar esta clase, serás capaz de:

  • Entender qué es FastAPI y sus ventajas
  • Instalar FastAPI y uvicorn
  • Crear tu primera API REST (Representational State Transfer)
  • Definir rutas GET, POST, PUT, DELETE
  • Usar parámetros de ruta y query
  • Probar la API con Swagger UI
Video Recomendado

Curso completo de FastAPI en español:

Ver "Curso FastAPI con Python" Duración: 5:06:45 | DesarrolloLibre

¿Qué es FastAPI? (10 min)

FastAPI es un framework moderno y rápido para construir APIs (Application Programming Interface / Interfaz de Programación de Aplicaciones) con Python.

Ventajas

  • Rápido: Uno de los frameworks más rápidos de Python
  • Fácil: Menos código, menos bugs
  • Validación automática: Usa Pydantic para validar datos
  • Documentación automática: Swagger UI y ReDoc incluidos
  • Type hints: Usa anotaciones de tipo de Python
Comparación: FastAPI es más moderno que Flask y más simple que Django para APIs.

Instalación (10 min)

# Crear entorno virtual (recomendado)
python -m venv venv

# Activar en Windows
venv\Scripts\activate

# Activar en macOS/Linux
source venv/bin/activate

# Instalar FastAPI y servidor
pip install fastapi uvicorn

# Verificar instalación
pip list | grep fastapi

Estructura del Proyecto

miprojecto/
├── main.py          # Archivo principal
├── requirements.txt # Dependencias
└── venv/           # Entorno virtual

Tu Primera API (20 min)

Archivo main.py

# main.py
from fastapi import FastAPI

# Crear instancia de la aplicación
app = FastAPI(
    title="Mi Primera API",
    description="API de ejemplo con FastAPI",
    version="1.0.0"
)

# Ruta GET básica
@app.get("/")
def read_root():
    """Ruta raíz de la API."""
    return {"message": "¡Hola, mundo!"}

# Ruta con parámetro
@app.get("/items/{item_id}")
def read_item(item_id: int):
    """Obtener un item por ID."""
    return {"item_id": item_id, "name": f"Item {item_id}"}

# Ruta con query parameter
@app.get("/users/")
def read_users(skip: int = 0, limit: int = 10):
    """Obtener usuarios con paginación."""
    return {"skip": skip, "limit": limit, "users": []}

Ejecutar el Servidor

# Ejecutar con recarga automática (desarrollo)
uvicorn main:app --reload

# Ejecutar sin recarga (producción)
uvicorn main:app --host 0.0.0.0 --port 8000

# Acceder a:
# - API: http://localhost:8000
# - Documentación: http://localhost:8000/docs (Swagger UI)
# - Documentación alternativa: http://localhost:8000/redoc
--reload: Recarga automática al cambiar el código (solo en desarrollo).

Métodos HTTP (20 min)

MétodoOperaciónUso típico
GETLeerObtener datos
POSTCrearCrear nuevo recurso
PUTActualizarActualizar recurso completo
DELETEEliminarEliminar recurso

Ejemplo CRUD Completo

# main.py
from fastapi import FastAPI, HTTPException
from typing import List, Optional

app = FastAPI()

# Base de datos simulada
usuarios_db = [
    {"id": 1, "nombre": "Juan", "email": "juan@email.com"},
    {"id": 2, "nombre": "Ana", "email": "ana@email.com"}
]

# GET - Obtener todos los usuarios
@app.get("/usuarios", response_model=List[dict])
def obtener_usuarios():
    return usuarios_db

# GET - Obtener usuario por ID
@app.get("/usuarios/{usuario_id}")
def obtener_usuario(usuario_id: int):
    for usuario in usuarios_db:
        if usuario["id"] == usuario_id:
            return usuario
    raise HTTPException(status_code=404, detail="Usuario no encontrado")

# POST - Crear usuario
@app.post("/usuarios", status_code=201)
def crear_usuario(nombre: str, email: str):
    nuevo_id = max(u["id"] for u in usuarios_db) + 1
    nuevo_usuario = {"id": nuevo_id, "nombre": nombre, "email": email}
    usuarios_db.append(nuevo_usuario)
    return nuevo_usuario

# PUT - Actualizar usuario
@app.put("/usuarios/{usuario_id}")
def actualizar_usuario(usuario_id: int, nombre: str, email: str):
    for usuario in usuarios_db:
        if usuario["id"] == usuario_id:
            usuario["nombre"] = nombre
            usuario["email"] = email
            return usuario
    raise HTTPException(status_code=404, detail="Usuario no encontrado")

# DELETE - Eliminar usuario
@app.delete("/usuarios/{usuario_id}")
def eliminar_usuario(usuario_id: int):
    for i, usuario in enumerate(usuarios_db):
        if usuario["id"] == usuario_id:
            del usuarios_db[i]
            return {"message": "Usuario eliminado"}
    raise HTTPException(status_code=404, detail="Usuario no encontrado")

Probar con curl o HTTPie

# Obtener todos los usuarios
curl http://localhost:8000/usuarios

# Obtener usuario específico
curl http://localhost:8000/usuarios/1

# Crear usuario
curl -X POST "http://localhost:8000/usuarios?nombre=Carlos&email=carlos@email.com"

# Actualizar usuario
curl -X PUT "http://localhost:8000/usuarios/1?nombre=Juan%20Pérez&email=juan.perez@email.com"

# Eliminar usuario
curl -X DELETE http://localhost:8000/usuarios/3

Ejercicio: API de Tareas (10 min)

Crea una API para gestionar tareas del proyecto TaskFlow.

Requisitos

  • GET /tareas - Listar todas las tareas
  • GET /tareas/{id} - Obtener tarea específica
  • POST /tareas - Crear nueva tarea (título, descripción)
  • PUT /tareas/{id} - Actualizar tarea
  • DELETE /tareas/{id} - Eliminar tarea
# tareas_api.py
from fastapi import FastAPI, HTTPException
from typing import List

app = FastAPI(title="TaskFlow API")

# Base de datos en memoria
tareas = []
contador_id = 1

@app.get("/tareas")
def listar_tareas():
    return tareas

@app.get("/tareas/{tarea_id}")
def obtener_tarea(tarea_id: int):
    for tarea in tareas:
        if tarea["id"] == tarea_id:
            return tarea
    raise HTTPException(status_code=404, detail="Tarea no encontrada")

@app.post("/tareas", status_code=201)
def crear_tarea(titulo: str, descripcion: str = ""):
    global contador_id
    tarea = {
        "id": contador_id,
        "titulo": titulo,
        "descripcion": descripcion,
        "completada": False
    }
    tareas.append(tarea)
    contador_id += 1
    return tarea

@app.put("/tareas/{tarea_id}")
def actualizar_tarea(tarea_id: int, titulo: str, descripcion: str, completada: bool):
    for tarea in tareas:
        if tarea["id"] == tarea_id:
            tarea["titulo"] = titulo
            tarea["descripcion"] = descripcion
            tarea["completada"] = completada
            return tarea
    raise HTTPException(status_code=404, detail="Tarea no encontrada")

@app.delete("/tareas/{tarea_id}")
def eliminar_tarea(tarea_id: int):
    for i, tarea in enumerate(tareas):
        if tarea["id"] == tarea_id:
            del tareas[i]
            return {"message": "Tarea eliminada"}
    raise HTTPException(status_code=404, detail="Tarea no encontrada")
Conexión con TaskFlow: Esta es la base de la API del proyecto. En las siguientes clases agregaremos: validación con Pydantic, dependencias, y persistencia en base de datos.

Resumen

  • FastAPI: Framework rápido y moderno para APIs
  • Instalación: pip install fastapi uvicorn
  • Ejecutar: uvicorn main:app --reload
  • GET: Leer datos
  • POST: Crear datos
  • PUT: Actualizar datos
  • DELETE: Eliminar datos
  • Documentación: /docs (Swagger UI)
Práctica: Crea una API de "Productos" con los mismos endpoints (GET, POST, PUT, DELETE) y pruébala en Swagger UI.
← Anterior: DDD
Clase 11 de 25
Siguiente: Pydantic →