CoolFace
Apppublic

coder160/backend-directorio-online

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
App README

Directorio Online — Backend (FastAPI + MongoDB)

API REST genérica y fácil de extender para un directorio de negocios organizado por categorías, con items (menús, servicios o productos), reseñas e imágenes. Construida con FastAPI y MongoDB (driver pymongo con su API asíncrona), autenticación JWT (OAuth2) y validación con Pydantic v2.

Modelo de datos y relaciones

Categoria
│   (puede anidarse a sí misma vía parent_id)
└── Negocio (N)

Negocio
├── Item (N)        (tipo: menu | servicio | producto)
├── Reseña (N)
└── Imagen (N)      (embebida)

Item
└── Imagen (N)      (embebida)

Los identificadores son el ObjectId de MongoDB, expuesto siempre como cadena en el campo id de las respuestas.

Estructura del proyecto

app/
├── core/         Configuración FastAPI: settings, seguridad (JWT),
│                 middlewares (CORS), lifespan y manejadores de excepciones.
├── database/     Conexión y cliente de MongoDB, índices y utilidades.
├── exceptions/   Excepciones propias de la aplicación.
├── models/       Modelos de dominio (lo que se guarda en la BD).
├── schemas/      Esquemas de entrada/salida con validaciones
│                 (contrato entre rutas y servicios).
├── services/     Lógica de negocio (CRUD genérico + reglas por entidad).
├── rutas/        Endpoints de comunicación con los clientes.
└── main.py       Punto de entrada (crea la app).

Cómo extender

Añadir una nueva entidad es directo gracias al BaseService (app/services/base.py), que implementa el CRUD genérico:

  1. 1.Define el modelo en models/ y los esquemas en schemas/.
  2. 2.Crea un servicio que herede de BaseService (fija collection_name).
  3. 3.Añade el router en rutas/ e inclúyelo en rutas/__init__.py.
  4. 4.(Opcional) Declara índices en database/indexes.py.

Requisitos

  • —Python 3.11+
  • —MongoDB 4.4+ en ejecución (local o remoto)

Instalación

bash
python -m venv .venv
source .venv/bin/activate        # En Windows: .venv\Scripts\activate
pip install -r requirements.txt

Configuración

Copia .env.example a .env y ajusta los valores:

bash
cp .env.example .env

Genera una clave secreta segura para SECRET_KEY:

bash
python -c "import secrets; print(secrets.token_urlsafe(48))"
VariableDescripciónPor defecto
APP_NAMENombre de la aplicaciónDirectorio Online API
APP_VERSIONVersión1.0.0
APP_DESCRIPTIONDescripción de la API(ver .env.example)
DEBUGModo depuraciónfalse
API_PREFIXPrefijo de las rutas/api/v1
PORTPuerto de escucha del contenedor7860
MONGODB_URIURI de conexión a MongoDBmongodb://localhost:27017
MONGODB_DB_NAMENombre de la base de datosdirectorio_online
SECRET_KEYClave para firmar los JWT (obligatoria)—
ALGORITHMAlgoritmo de firma del JWTHS256
ACCESS_TOKEN_EXPIRE_MINUTESValidez del token de acceso (minutos)60
CORS_ORIGINSOrígenes permitidos (lista por comas o *)*

Ejecución

bash
uvicorn app.main:app --reload
  • —Documentación interactiva (Swagger): http://localhost:8000/docs
  • —Documentación alternativa (ReDoc): http://localhost:8000/redoc
  • —Comprobación de salud: http://localhost:8000/health

Docker

La aplicación se empaqueta con el Dockerfile incluido. El contenedor escucha en el puerto indicado por la variable PORT (por defecto 7860).

bash
# Construir la imagen
docker build -t directorio-online-backend .

# Ejecutar (las variables se pasan con -e o con --env-file)
docker run --rm -p 7860:7860 \
  -e SECRET_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(48))')" \
  -e MONGODB_URI="mongodb+srv://usuario:password@cluster.mongodb.net" \
  -e MONGODB_DB_NAME="directorio_online" \
  directorio-online-backend

La API quedará disponible en http://localhost:7860 (Swagger en /docs).

Despliegue en HuggingFace Spaces (Docker)

El repositorio está listo para desplegarse como un Space de tipo Docker:

  • —El README.md incluye las metadatos del Space en su cabecera YAML (sdk: docker, app_port: 7860).
  • —El Dockerfile ejecuta el contenedor como el usuario UID 1000 (requisito de HuggingFace) y arranca uvicorn en el puerto 7860.

Pasos:

  1. 1.Crea un Space → SDK: Docker → Blank.
  2. 2.Sube este repositorio al Space (o conéctalo a GitHub).
  3. 3.En Settings → Variables and secrets, define las variables del archivo .env.example:
  4. 4.Como Secret: SECRET_KEY y MONGODB_URI.
  5. 5.Como Variable: el resto (MONGODB_DB_NAME, CORS_ORIGINS, etc.).
  6. 6.El Space construye la imagen y la API queda expuesta en la URL del Space (https://<usuario>-<space>.hf.space), con Swagger en /docs.
MongoDB: HuggingFace no provee base de datos, así que MONGODB_URI debe apuntar a una instancia accesible desde internet (p. ej. MongoDB Atlas). El driver ya incluye dnspython (extra pymongo[srv]) para los URIs mongodb+srv://.

Autenticación

  • —La lectura (GET) es pública.
  • —La escritura (POST/PUT/DELETE) requiere un token JWT.
bash
# 1) Registrar un usuario
curl -X POST http://localhost:8000/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","email":"admin@correo.com","password":"supersecreta"}'

# 2) Iniciar sesión (formulario OAuth2; "username" admite usuario o correo)
curl -X POST http://localhost:8000/api/v1/auth/login \
  -d "username=admin&password=supersecreta"

# 3) Usar el token en las operaciones de escritura
curl -X POST http://localhost:8000/api/v1/categorias \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"nombre":"Restaurantes"}'

Endpoints principales

MétodoRutaAuthDescripción
POST/api/v1/auth/register—Registrar usuario
POST/api/v1/auth/login—Iniciar sesión (devuelve JWT)
GET/api/v1/auth/me✓Usuario autenticado
GET/api/v1/categorias—Listar categorías
POST/api/v1/categorias✓Crear categoría
GET/api/v1/categorias/{id}—Obtener categoría
PUT/api/v1/categorias/{id}✓Actualizar categoría
DELETE/api/v1/categorias/{id}✓Eliminar categoría
GET/api/v1/negocios—Listar negocios (filtros)
POST/api/v1/negocios✓Crear negocio
GET/api/v1/negocios/{id}—Obtener negocio
PUT/api/v1/negocios/{id}✓Actualizar negocio
DELETE/api/v1/negocios/{id}✓Eliminar negocio (cascada)
GET/api/v1/items—Listar items (filtros)
POST/api/v1/items✓Crear item
GET/api/v1/items/{id}—Obtener item
PUT/api/v1/items/{id}✓Actualizar item
DELETE/api/v1/items/{id}✓Eliminar item
GET/api/v1/resenas—Listar reseñas (filtros)
POST/api/v1/resenas✓Crear reseña
GET/api/v1/resenas/{id}—Obtener reseña
PUT/api/v1/resenas/{id}✓Actualizar reseña
DELETE/api/v1/resenas/{id}✓Eliminar reseña

Filtros y paginación

Todos los listados aceptan skip (≥0) y limit (1–100) y devuelven una respuesta paginada { total, skip, limit, items }.

  • —GET /negocios?categoria_id=...&activo=true&buscar=pepe
  • —GET /items?negocio_id=...&tipo=menu&activo=true
  • —GET /resenas?negocio_id=...
  • —GET /categorias?parent_id=...

Reglas de negocio

  • —Integridad referencial: al crear un negocio se valida que la categoría exista; al crear items y reseñas se valida que el negocio exista.
  • —Borrado en cascada: eliminar un negocio elimina también sus items y reseñas.
  • —Categorías: no se puede eliminar una categoría que tenga subcategorías o negocios asociados.
  • —Slug único: el slug de la categoría es único; se autogenera a partir del nombre si no se proporciona.

Calidad de código

El código sigue PEP 8 (límite de línea de 99 columnas, configurado en setup.cfg). Para verificarlo:

bash
pip install pycodestyle pyflakes
pyflakes app/
pycodestyle app/