Guía Completa de FastAPI para Biblioteca Personal
📚 Introducción a FastAPI
FastAPI es un framework web moderno y rápido para construir APIs con Python. Su principal ventaja es
la generación automática de documentación y la validación de datos.
🛠️ Configuración Inicial en Jupyter Notebook
Instalación de Dependencias
python
# Ejecutar en una celda de Jupyter
!pip install fastapi uvicorn nest-asyncio
Setup Básico para Jupyter
python
import fastapi
import uvicorn
import nest_asyncio
from fastapi import FastAPI, HTTPException
from typing import Optional, List
# Permitir que uvicorn funcione en Jupyter
nest_asyncio.apply()
# Crear la aplicación FastAPI
app = FastAPI(
title="Biblioteca Personal API",
description="API para gestionar una biblioteca personal",
version="1.0.0"
)
🏗️ Funciones y Conceptos Fundamentales
1. Crear la Aplicación FastAPI
python
app = FastAPI()
¿Para qué sirve?
Crea la instancia principal de tu aplicación
Define metadatos como título, descripción y versión
Es el objeto que contendrá todos tus endpoints
¿Cómo usarla correctamente?
Siempre crear una sola instancia por aplicación
Agregar metadatos descriptivos para documentación automática
2. Decoradores de Endpoints
@app.get() - Obtener Datos
python
@app.get("/")
def root():
return {"mensaje": "Bienvenido a la Biblioteca Personal"}
@app.get("/libros")
def obtener_libros():
return libros_biblioteca
¿Para qué sirve?
Define endpoints que obtienen información
Equivale al método GET de HTTP
Usado para consultas que no modifican datos
¿Cómo usarla correctamente?
Para operaciones de lectura únicamente
Nombres de funciones descriptivos
Rutas claras y coherentes
@app.post() - Crear Datos
python
@app.post("/libros")
def agregar_libro(titulo: str, autor: str, año: Optional[int] = None):
nuevo_libro = {
"id": len(libros_biblioteca) + 1,
"titulo": titulo,
"autor": autor,
"año": año,
"leido": False,
"rating": None
}
libros_biblioteca.append(nuevo_libro)
return {"mensaje": "Libro agregado exitosamente", "libro": nuevo_libro}
¿Para qué sirve?
Crea nuevos recursos en tu API
Recibe datos del cliente para procesarlos
Equivale al método POST de HTTP
¿Cómo usarla correctamente?
Para operaciones que crean nuevos elementos
Validar datos de entrada
Retornar confirmación de la operación
@app.put() - Actualizar Datos
python
@app.put("/libros/{libro_id}/leido")
def marcar_como_leido(libro_id: int, leido: bool = True):
for libro in libros_biblioteca:
if libro["id"] == libro_id:
libro["leido"] = leido
return {"mensaje": f"Libro {'marcado' if leido else 'desmarcado'} como leído"}
raise HTTPException(status_code=404, detail="Libro no encontrado")
¿Para qué sirve?
Actualiza recursos existentes
Modifica datos específicos
Equivale al método PUT de HTTP
¿Cómo usarla correctamente?
Para modificar elementos existentes
Validar que el recurso existe
Manejar errores apropiadamente
@app.delete() - Eliminar Datos
python
@app.delete("/libros/{libro_id}")
def eliminar_libro(libro_id: int):
for i, libro in enumerate(libros_biblioteca):
if libro["id"] == libro_id:
libro_eliminado = libros_biblioteca.pop(i)
return {"mensaje": "Libro eliminado", "libro": libro_eliminado}
raise HTTPException(status_code=404, detail="Libro no encontrado")
¿Para qué sirve?
Elimina recursos de tu API
Equivale al método DELETE de HTTP
¿Cómo usarla correctamente?
Para operaciones de eliminación únicamente
Confirmar que el recurso existe antes de eliminar
Retornar información sobre lo eliminado
3. Parámetros de Ruta (Path Parameters)
python
@app.get("/libros/{libro_id}")
def obtener_libro(libro_id: int):
for libro in libros_biblioteca:
if libro["id"] == libro_id:
return libro
raise HTTPException(status_code=404, detail="Libro no encontrado")
¿Para qué sirve?
Captura valores específicos de la URL
Permite acceder a recursos individuales
Se definen con {nombre_parametro} en la ruta
¿Cómo usarla correctamente?
Usar tipos específicos (int, str, etc.)
Validar que el parámetro sea válido
Nombres descriptivos y consistentes
4. Parámetros de Consulta (Query Parameters)
python
@app.get("/libros/buscar")
def buscar_libros(titulo: Optional[str] = None, autor: Optional[str] = None, leido: Optional[bo
resultados = libros_biblioteca
if titulo:
resultados = [libro for libro in resultados if titulo.lower() in libro["titulo"].lower(
if autor:
resultados = [libro for libro in resultados if autor.lower() in libro["autor"].lower()]
if leido is not None:
resultados = [libro for libro in resultados if libro["leido"] == leido]
return resultados
¿Para qué sirve?
Filtrar y personalizar respuestas
Añadir opciones a las consultas
Se pasan como ?parametro=valor en la URL
¿Cómo usarla correctamente?
Usar Optional para parámetros no obligatorios
Proporcionar valores por defecto
Validar tipos de datos
5. Manejo de Errores con HTTPException
python
from fastapi import HTTPException
def obtener_libro_por_id(libro_id: int):
for libro in libros_biblioteca:
if libro["id"] == libro_id:
return libro
raise HTTPException(
status_code=404,
detail=f"Libro con ID {libro_id} no encontrado"
)
¿Para qué sirve?
Devuelve errores HTTP apropiados
Proporciona mensajes descriptivos
Mantiene la API profesional
¿Cómo usarla correctamente?
Usar códigos de estado HTTP correctos (404, 400, 500, etc.)
Mensajes de error claros y útiles
Validar datos antes de procesarlos
6. Validación de Tipos
python
from typing import Optional, List
@app.post("/libros")
def agregar_libro(
titulo: str,
autor: str,
año: Optional[int] = None,
rating: Optional[int] = None
):
# FastAPI automáticamente valida los tipos
if rating and (rating < 1 or rating > 5):
raise HTTPException(status_code=400, detail="Rating debe estar entre 1 y 5")
# Resto de la lógica...
¿Para qué sirve?
FastAPI valida automáticamente los tipos
Genera documentación basada en tipos
Previene errores de datos
¿Cómo usarla correctamente?
Especificar tipos para todos los parámetros
Usar Optional para parámetros opcionales
Agregar validaciones adicionales cuando sea necesario
🚀 Ejecutar la API en Jupyter
python
# En una celda separada, ejecutar:
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8001)
Importante para Jupyter:
La API se ejecutará en http://localhost:8001
La documentación automática estará en http://localhost:8001/docs
Para detener el servidor, interrumpir la celda (Ctrl+C)
📊 Estructura de Datos para la Biblioteca
python
# Lista para almacenar libros (base de datos temporal)
libros_biblioteca = []
# Estructura de un libro
libro_ejemplo = {
"id": 1,
"titulo": "Cien años de soledad",
"autor": "Gabriel García Márquez",
"año": 1967,
"genero": "Realismo mágico",
"leido": True,
"rating": 5,
"descripcion": "Una obra maestra de la literatura latinoamericana",
"fecha_lectura": "2024-01-15"
}
🔧 Funciones Auxiliares Importantes
Función para Precargar Datos
python
def precargar_biblioteca():
"""Precarga la biblioteca con libros de ejemplo"""
libros_ejemplo = [
{
"id": 1,
"titulo": "Cien años de soledad",
"autor": "Gabriel García Márquez",
"año": 1967,
"leido": True,
"rating": 5
},
{
"id": 2,
"titulo": "1984",
"autor": "George Orwell",
"año": 1949,
"leido": False,
"rating": None
}
# Agregar más libros...
]
libros_biblioteca.extend(libros_ejemplo)
# Llamar al inicio de la aplicación
precargar_biblioteca()
Función de Estadísticas
python
@app.get("/estadisticas")
def obtener_estadisticas():
total_libros = len(libros_biblioteca)
libros_leidos = len([libro for libro in libros_biblioteca if libro["leido"]])
libros_con_rating = [libro for libro in libros_biblioteca if libro["rating"]]
rating_promedio = sum(libro["rating"] for libro in libros_con_rating) / len(libros_con_rati
return {
"total_libros": total_libros,
"libros_leidos": libros_leidos,
"libros_pendientes": total_libros - libros_leidos,
"rating_promedio": round(rating_promedio, 2)
}
📝 Mejores Prácticas
1. Nombres de Funciones y Rutas
Usar verbos descriptivos: obtener_libros , agregar_libro
Rutas coherentes: /libros , /libros/{id} , /libros/buscar
2. Manejo de Errores
Siempre validar que los recursos existen
Usar códigos de estado HTTP apropiados
Proporcionar mensajes de error útiles
3. Documentación Automática
FastAPI genera documentación automáticamente
Usar docstrings en las funciones
Especificar tipos para mejor documentación
4. Validación de Datos
Aprovechar la validación automática de tipos
Agregar validaciones personalizadas cuando sea necesario
Usar Optional para parámetros opcionales
🎯 Checklist para tu Proyecto
Día 1: API básica funcionando con endpoints / y /info
Día 2: Estructura de datos y endpoints POST/GET para libros
Día 3: Endpoints completos (PUT, DELETE) y búsqueda
Día 4: Validaciones, manejo de errores y estadísticas
Día 5: Datos de ejemplo y documentación detallada
Día 6: Preparación de presentación y demo
Día 7: Práctica final y backup
💡 Consejos para Jupyter Notebook
1. Organizar en celdas separadas:
Una celda para imports y setup
Una celda por grupo de endpoints relacionados
Una celda para ejecutar el servidor
2. Reiniciar cuando sea necesario:
Si cambias la estructura, reinicia el kernel
Vuelve a ejecutar todas las celdas en orden
3. Documentar tu código:
Agregar comentarios explicativos
Usar markdown para explicaciones entre celdas
¡Con esta guía tienes todo lo necesario para completar tu proyecto de biblioteca personal con FastAPI!
🚀