feat: add operation exercises generation using gen_op.py

Moved gen-op.py to app/gen_op.py and integrated it with the FastAPI application

Added a new section in the UI for generating operation exercises

Updated the PDF generation to work in memory and upload to S3

Bumped version to 1.0.9
This commit is contained in:
2025-09-25 19:10:13 +02:00
parent 8bedd8a97a
commit 28b1c80b50
4 changed files with 272 additions and 7 deletions
+42
View File
@@ -6,6 +6,7 @@ import io
import boto3
import zipfile
import tempfile
import importlib.util
from botocore.exceptions import ClientError
from typing import List
from fastapi import FastAPI, Request, Form
@@ -16,6 +17,9 @@ from fpdf import FPDF
import logging
# Import the functions from gen_op.py
from app.gen_op import generer_pdf_exercices_en_memoire
# Custom filter to exclude health check logs
class HealthCheckFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
@@ -163,6 +167,9 @@ class ExerciseRequest(BaseModel):
max_table: int
num_exercises: int = 15
class OperationExerciseRequest(BaseModel):
num_exercises: int = 20
def generate_exercises(
min_table: int, max_table: int, num_exercises: int = 15
@@ -305,6 +312,26 @@ def create_math_exercises_pdf(
return pdf_filename
def create_operation_exercises_pdf(num_exercises: int = 20) -> str:
"""Crée un fichier PDF avec des exercices d'opérations et l'upload sur S3"""
import datetime
# Add timestamp to filename
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
pdf_filename = f"exercices_operations_{num_exercises}_exercices_{timestamp}.pdf"
# Generate PDF in memory using gen-op functions
pdf_data = generer_pdf_exercices_en_memoire(num_exercises)
# Upload to S3
upload_success = upload_to_s3(pdf_data, S3_BUCKET_NAME, pdf_filename, "application/pdf")
if not upload_success:
raise Exception("Failed to upload PDF to S3")
return pdf_filename
@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@@ -333,6 +360,21 @@ async def generate_exercises_endpoint(request: ExerciseRequest):
return {"error": f"Erreur lors de la création du PDF: {str(e)}"}
@app.post("/generate-operations")
async def generate_operation_exercises_endpoint(request: OperationExerciseRequest):
try:
if request.num_exercises < 1:
return {"error": "Le nombre d'exercices doit être supérieur à 0"}
pdf_filename = create_operation_exercises_pdf(request.num_exercises)
# Return redirect to automatically download the file
return RedirectResponse(url=f"/download/{pdf_filename}", status_code=303)
except Exception as e:
return {"error": f"Erreur lors de la création du PDF: {str(e)}"}
@app.get("/download/{filename}")
async def download_pdf(filename: str):
# Download file from S3