Files
GenExam-IA/README.md
T
Mireya Cueto Garrido d06b961a73 Use Sinbad2 production ports 8068 (backend) and 8069 (frontend).
Apache ProxyPass targets host port 8069; update compose, CI, CORS defaults, deployment docs, and production .env files for https://sinbad2.ujaen.es/generadorexamenesllm/.
2026-06-03 12:13:02 +02:00

5.2 KiB

GenExamenes IA

Backend para generar exámenes con IA, procesar la salida de un LLM y exportar preguntas a Moodle XML.

Guía detallada de flujo, endpoints, ejemplos y errores: GUIA_API_Y_FLUJO.md

El proyecto está centrado en backend. La carpeta frontend se mantiene vacía a nivel de aplicación, aunque existe un servicio en Docker Compose para reservar el despliegue futuro.

Stack

  • FastAPI
  • PostgreSQL
  • SQLAlchemy
  • Cliente LLM para Sinbad2IA UJA (POST /api/chat, modelo qwen3.5:35b)
  • Docker Compose con servicios backend, frontend y db

Puesta en Marcha

Copia el ejemplo de variables dentro de la carpeta del backend:

cp backend/.env.example backend/.env

Después levanta los servicios:

docker compose up --build

La API queda disponible en:

http://sinbad2.ujaen.es:8068

Configuración

El archivo de entorno debe estar en backend/.env.

Variables principales:

  • JWT_SECRET_KEY: secreto para firmar tokens JWT (mínimo 32 caracteres).
  • JWT_EXPIRE_MINUTES: duración del token de acceso.
  • GOOGLE_CLIENT_ID: Client ID de OAuth 2.0 en Google Cloud Console (para /auth/google).
  • DATABASE_URL: conexión PostgreSQL usada por el backend.
  • LLM_BASE_URL: URL base del servidor (por defecto ``; el cliente usa /api/chat).
  • LLM_MODEL: modelo (por defecto qwen3.5:35b).
  • LLM_TIMEOUT_SECONDS: tiempo máximo de espera (por defecto 180 s).
  • LLM_API_KEY: opcional, solo si el servidor exige autenticación.
  • ALLOWED_ORIGINS: orígenes permitidos por CORS.
  • MAX_STORAGE_BYTES_PER_TEMPLATE: cupo total de almacenamiento por examen (materiales + imágenes).

Todas las rutas bajo /exam requieren autenticación de usuario con:

Authorization: Bearer <access_token>

Si ya tenías una base de datos creada antes de añadir usuarios, recrea el volumen:

docker compose down -v
docker compose up --build

Flujo de Usuario

  1. Registrarse o iniciar sesión.
  2. Crear una plantilla de examen (queda asociada al usuario).
  3. Subir materiales de referencia (PDF, DOCX, TXT, PNG, JPG…) a la plantilla.
  4. Generar un prompt guiado para el LLM (incluye el texto extraído de los ficheros).
  5. Generar preguntas automáticamente con el LLM o parsear una salida externa en JSON/TXT.
  6. Guardar las preguntas validadas en PostgreSQL.
  7. Consultar el historial de exámenes creados.
  8. Exportar el examen a Moodle XML, TXT o JSON.

Endpoints

GET /health

Comprueba que la API está levantada.

POST /auth/register

Registra un usuario con email y contraseña.

POST /auth/login

Devuelve un token JWT para usar en las rutas protegidas.

POST /auth/google

Recibe el id_token de Google (Sign in with Google en el frontend), verifica la cuenta y devuelve el mismo JWT de la API.

GET /auth/me

Devuelve los datos del usuario autenticado.

GET /exam/history

Lista el historial de exámenes del usuario (plantillas, preguntas y exportaciones).

POST /exam/templates/{template_id}/materials

Sube un fichero (multipart/form-data, campo file). Formatos: PDF, DOCX, TXT, MD, PNG, JPG, WEBP. Extrae texto y lo guarda como contexto.

GET /exam/templates/{template_id}/materials

Lista los materiales subidos a una plantilla.

DELETE /exam/templates/{template_id}/materials/{material_id}

Elimina un material.

POST /exam/templates/{template_id}/images

Sube una imagen para preguntas visuales (file, opcional caption). No se usa OCR: la imagen se muestra en el examen y se embebe en el XML de Moodle.

GET /exam/templates/{template_id}/images

Lista las imágenes de la plantilla.

GET /exam/images/{image_id}/content

Devuelve la imagen (requiere JWT). Para previsualizar en el frontend o en Moodle tras importar.

DELETE /exam/templates/{template_id}/images/{image_id}

Elimina una imagen.

PATCH /exam/questions/{question_id}/image

Vincula o desvincula una imagen a una pregunta existente ({"image_id": "uuid"} o null).

POST /exam/templates

Crea una plantilla con materia, nivel educativo, tipos de pregunta, puntuación, penalización y dificultad.

GET /exam/templates

Lista las plantillas del usuario autenticado.

GET /exam/templates/{template_id}

Obtiene una plantilla concreta.

GET /exam/templates/{template_id}/storage

Muestra cuánto espacio usa el examen (materiales + imágenes) y el límite configurado.

POST /exam/prompts/{template_id}

Genera un prompt estructurado para IA.

POST /exam/generate

Llama al LLM configurado, parsea la respuesta y guarda las preguntas.

POST /exam/parse

Procesa una salida externa de IA en formato json o txt.

GET /exam/export/xml/{template_id}

Exporta las preguntas en Moodle XML.

GET /exam/export/txt/{template_id}

Exporta las preguntas en texto plano.

GET /exam/export/json/{template_id}

Exporta las preguntas en JSON.

Seguridad

  • Registro e inicio de sesión con contraseña hasheada (bcrypt).
  • Autenticación JWT por usuario.
  • Cada examen pertenece a un único usuario; no se puede acceder al de otro.
  • Rate limiting por cliente.
  • Límite de tamaño de petición.
  • Validación de entrada con Pydantic.
  • Manejo uniforme de errores HTTP.
  • Sanitización básica de prompts y respuestas antes de persistir/exportar.