Laboratorio: Creación de un CMS Monolítico con FastAPI

Objetivo:

Desarrollar un sistema de gestión de contenido (CMS) utilizando la arquitectura monolítica con FastAPI, donde todas las funcionalidades están integradas en una sola aplicación web.

Requisitos Previos:

  1. Conocimientos básicos de Python.
  2. Conocimientos básicos de FastAPI.
  3. Python 3.7 o superior instalado en tu entorno.
  4. Entorno virtual de Python configurado.

Pasos del Laboratorio:

  1. Preparación del Entorno
  • Instalar FastAPI y Uvicorn:
  • Crea un entorno virtual y instala FastAPI junto con Uvicorn para el servidor ASGI.
python -m venv env
source venv/bin/activate  # En Windows usa `venv\Scripts\activate`
pip install fastapi uvicorn[standard] sqlalchemy alembic

Configurar la Estructura del Proyecto:

Crea la estructura básica del proyecto:

cms_project/
├── app/
│   ├── main.py
│   ├── models.py
│   ├── schemas.py
│   ├── crud.py
│   └── database.py
├── alembic.ini
└── migrations/
  1. Desarrollo del CMS

Configurar la Base de Datos:

En app/database.py, configura la conexión a la base de datos usando SQLAlchemy:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

Definir los Modelos:

En app/models.py, define los modelos de datos usando SQLAlchemy:

from sqlalchemy import Column, Integer, String, Text
from app.database import Base

class Post(Base):
    __tablename__ = "posts"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, index=True)
    content = Column(Text)

Definir los Esquemas:

En app/schemas.py, define los esquemas de Pydantic para la validación de datos:

from pydantic import BaseModel

class PostBase(BaseModel):
    title: str
    content: str

class PostCreate(PostBase):
    pass

class Post(PostBase):
    id: int

    class Config:
        orm_mode = True

Implementar las Operaciones CRUD:

En app/crud.py, implementa las operaciones CRUD para los posts:

from sqlalchemy.orm import Session
from . import models, schemas

def create_post(db: Session, post: schemas.PostCreate):
    db_post = models.Post(**post.dict())
    db.add(db_post)
    db.commit()
    db.refresh(db_post)
    return db_post

def get_post(db: Session, post_id: int):
    return db.query(models.Post).filter(models.Post.id == post_id).first()

def get_posts(db: Session, skip: int = 0, limit: int = 10):
    return db.query(models.Post).offset(skip).limit(limit).all()

Crear los Endpoints de la API:

En app/main.py, define los endpoints de la API usando FastAPI:

from typing import List
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session
from . import models, schemas, crud, database


app = FastAPI()

models.Base.metadata.create_all(bind=database.engine)

def get_db():
    db = database.SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/posts/", response_model=schemas.Post)
def create_post(post: schemas.PostCreate, db: Session = Depends(get_db)):
    return crud.create_post(db=db, post=post)

@app.get("/posts/{post_id}", response_model=schemas.Post)
def read_post(post_id: int, db: Session = Depends(get_db)):
    db_post = crud.get_post(db, post_id)
    if db_post is None:
        raise HTTPException(status_code=404, detail="Post not found")
    return db_post

@app.get("/posts/", response_model=List[schemas.Post])
def read_posts(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
    posts = crud.get_posts(db, skip=skip, limit=limit)
    return posts
Tip

Crear el directorio __init__.py en la carpeta app para que Python reconozca la carpeta como un paquete.

  1. Despliegue y Pruebas

Ejecutar la Aplicación:

Usa Uvicorn para ejecutar la aplicación:

uvicorn app.main:app --reload

Pruebas:

  • Accede a http://127.0.0.1:8000/docs para ver y probar la documentación interactiva de la API generada automáticamente por FastAPI.

  • Prueba crear, leer, y listar posts a través de la interfaz de Swagger.
  1. Evaluación

Desarrollo: Evalúa la facilidad de desarrollo y la organización del código.

Rendimiento: Mide el rendimiento de la aplicación al manejar diferentes volúmenes de datos.

Mantenimiento: Considera la facilidad de mantenimiento y extensión de la aplicación a medida que crece.

Recursos:

Este laboratorio te permitirá familiarizarte con FastAPI y la arquitectura monolítica, entendiendo cómo construir una aplicación integral con todas sus funcionalidades en un solo proyecto.

Pruebas

  1. Instalar Thunder Client

Si aún no lo has hecho, primero debes instalar Thunder Client. Es una extensión para Visual Studio Code (VSCode).

  • Abre VSCode.
  • Ve a la pestaña de Extensiones (Ctrl+Shift+X).
  • Busca Thunder Client y haz clic en Instalar.
  1. Configurar Thunder Client

Una vez que Thunder Client esté instalado, puedes comenzar a configurar y probar tus endpoints. Crear una Nueva Solicitud

  • Abre Thunder Client en VSCode. Lo encontrarás en el panel lateral izquierdo como un ícono de rayo.
  • Crea una nueva colección para organizar tus solicitudes. Puedes hacer esto desde el panel principal de Thunder Client haciendo clic en el botón + al lado de “Collections” y luego en “Create Collection”.

Crear una Solicitud en Thunder Client

  • Selecciona la colección en la que deseas agregar la solicitud.
  • Haz clic en el botón + New Request.
  • Elige el método HTTP (GET, POST, PUT, DELETE, etc.) dependiendo del endpoint que deseas probar. Introduce la URL de tu endpoint en el campo correspondiente. Por ejemplo, http://127.0.0.1:8000/posts/.

Configuración de la Solicitud

Para una solicitud POST:

  • Método: POST

  • URL: http://127.0.0.1:8000/posts/

  • Encabezados: Configura los encabezados si es necesario. Para JSON, agrega Content-Type: application/json.

Cuerpo:

Selecciona la pestaña Body.

Elige el tipo de cuerpo como Raw y elige JSON.

Introduce el JSON que deseas enviar. Por ejemplo:

{
    "title": "Test Post",
    "content": "This is a test post."
}

Haz clic en Send para enviar la solicitud y ver la respuesta.

Para una solicitud GET:

Revisar la Respuesta

Una vez que envíes la solicitud, Thunder Client te mostrará la respuesta de la API, que incluye:

  • Código de estado (por ejemplo, 200 OK).
  • Encabezados de la respuesta.
  • Cuerpo de la respuesta, que será el JSON u otro formato que tu API devuelve.
  1. Organizar y Guardar Solicitudes

Puedes guardar tus solicitudes para uso futuro:

  • Después de enviar una solicitud, haz clic en Save.
  • Elige un nombre para la solicitud y, si lo deseas, una descripción.
  • Guarda la solicitud en la colección que creaste anteriormente.
  1. Ejecutar Pruebas en Secuencia

Puedes crear una serie de solicitudes dentro de una colección para probar diferentes aspectos de tu API en secuencia. Esto te permitirá automatizar un flujo de pruebas básico.

Thunder Client es una herramienta poderosa y fácil de usar para probar tus endpoints de FastAPI. Te permite realizar pruebas rápidas y ver los resultados de manera clara. Si necesitas ayuda con una configuración específica o con la interpretación de respuestas, no dudes en preguntar.

Reto

En este laboratorio has aprendido a crear un CMS monolítico con FastAPI. Ahora, te desafiamos a extender la funcionalidad de tu CMS agregando nuevas características, como:

  • Autenticación: Implementa un sistema de autenticación para permitir que los usuarios se registren y accedan a la aplicación.

  • Comentarios: Agrega la capacidad de que los usuarios comenten en los posts.

  • Imágenes: Permite a los usuarios subir imágenes para acompañar sus posts.

  • Búsqueda: Implementa una función de búsqueda para que los usuarios puedan buscar posts por título o contenido.

  • Temas: Permite a los usuarios clasificar los posts por temas o categorías.

Estos son solo algunos ejemplos de cómo puedes extender tu CMS.

¡Sé creativo y diviértete desarrollando nuevas funcionalidades!