Files
notytex/backend/api/main.py
Bertrand Benjamin 2b08eb534a Migration v1 (Flask) -> v2 (FastAPI + Vue.js) complétée
 Changements majeurs:
- Suppression complète du code Flask legacy
- Migration backend FastAPI vers racine /backend
- Migration frontend Vue.js vers racine /frontend
- Suppression de notytex-v2/ (code monté à la racine)

 Validations:
- Backend démarre correctement (port 8000)
- API /api/v2/health répond healthy
- 99/99 tests unitaires passent
- Frontend configuré avec proxy Vite

📝 Documentation:
- README.md réécrit pour v2
- Instructions de démarrage mises à jour
- .gitignore adapté pour backend/frontend/

🎯 Architecture finale:
notytex/
├── backend/     # FastAPI + SQLAlchemy + Pydantic
├── frontend/    # Vue 3 + Vite + TailwindCSS
├── docs/        # Documentation
└── school_management.db  # Base de données (inchangée)

Jalon 6 complété: Application v2 prête pour utilisation!
2025-11-25 21:09:47 +01:00

112 lines
3.2 KiB
Python

"""
Application FastAPI principale pour Notytex v2.
"""
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy import text, inspect
from core.config import settings
from infrastructure.database.session import async_engine, sync_engine
from infrastructure.database.models import (
ClassGroup,
Student,
Assessment,
Exercise,
GradingElement,
Grade,
)
# Import des routes
from api.routes import classes, students, assessments, config, council
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Gestion du cycle de vie de l'application.
"""
# Startup
print(f"Starting {settings.app_name} v{settings.app_version}")
yield
# Shutdown
await async_engine.dispose()
print("Application shutdown complete")
app = FastAPI(
title=settings.app_name,
version=settings.app_version,
description="API REST pour le système de gestion scolaire Notytex",
docs_url=f"{settings.api_v2_prefix}/docs",
redoc_url=f"{settings.api_v2_prefix}/redoc",
openapi_url=f"{settings.api_v2_prefix}/openapi.json",
lifespan=lifespan,
)
# Configuration CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get(f"{settings.api_v2_prefix}/health")
async def health_check():
"""
Endpoint de santé pour vérifier que l'API est opérationnelle
et connectée à la base de données.
Returns:
Dict avec statut, connexion DB et comptage des entités
"""
try:
# Utiliser une connexion sync pour l'inspection des tables
# car inspect() n'est pas async
with sync_engine.connect() as conn:
inspector = inspect(sync_engine)
tables = inspector.get_table_names()
# Compter les entités principales
classes_count = conn.execute(text("SELECT COUNT(*) FROM class_group")).scalar()
students_count = conn.execute(text("SELECT COUNT(*) FROM student")).scalar()
assessments_count = conn.execute(text("SELECT COUNT(*) FROM assessment")).scalar()
return {
"status": "healthy",
"database": "connected",
"tables": len(tables),
"classes": classes_count,
"students": students_count,
"assessments": assessments_count,
}
except Exception as e:
return {
"status": "unhealthy",
"database": "disconnected",
"error": str(e),
}
@app.get("/")
async def root():
"""Redirection vers la documentation API."""
return {
"message": f"Bienvenue sur {settings.app_name}",
"version": settings.app_version,
"docs": f"{settings.api_v2_prefix}/docs",
}
# Enregistrement des routes
app.include_router(classes.router, prefix=settings.api_v2_prefix)
app.include_router(students.router, prefix=settings.api_v2_prefix)
app.include_router(assessments.router, prefix=settings.api_v2_prefix)
app.include_router(config.router, prefix=settings.api_v2_prefix)
app.include_router(council.router, prefix=settings.api_v2_prefix)