
- Ajout docker-compose.simple.yml avec ports modifiés (15432, 16379, 19000, 19001, 18000) - Création app_simple.py sans dépendances IA - Ajout Dockerfile.simple et requirements.simple.txt - Correction attribut metadata réservé dans database.py - Ajout scripts de démarrage et test simplifiés - Configuration .env.simple pour version sans IA
203 lines
5.8 KiB
Python
203 lines
5.8 KiB
Python
"""
|
|
API d'ingestion simplifiée pour le pipeline notarial (sans IA)
|
|
"""
|
|
from fastapi import FastAPI, UploadFile, File, Form, HTTPException, Depends
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import JSONResponse
|
|
import uuid
|
|
import time
|
|
import os
|
|
import logging
|
|
|
|
from domain.models import ImportMeta, DocumentStatus
|
|
from domain.database import get_db, init_db
|
|
from routes import health
|
|
from utils.storage import store_document
|
|
|
|
# Configuration du logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
app = FastAPI(
|
|
title="Notariat Pipeline API (Simplifié)",
|
|
description="API d'ingestion simplifiée pour le traitement de documents notariaux (sans IA)",
|
|
version="1.0.0-simple"
|
|
)
|
|
|
|
# Configuration CORS
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"], # À restreindre en production
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Inclusion des routes
|
|
app.include_router(health.router, prefix="/api", tags=["health"])
|
|
|
|
@app.on_event("startup")
|
|
async def startup_event():
|
|
"""Initialisation au démarrage de l'application"""
|
|
logger.info("Démarrage de l'API Notariat Pipeline (Simplifié)")
|
|
await init_db()
|
|
|
|
@app.on_event("shutdown")
|
|
async def shutdown_event():
|
|
"""Nettoyage à l'arrêt de l'application"""
|
|
logger.info("Arrêt de l'API Notariat Pipeline (Simplifié)")
|
|
|
|
@app.exception_handler(Exception)
|
|
async def global_exception_handler(request, exc):
|
|
"""Gestionnaire d'exceptions global"""
|
|
logger.error(f"Erreur non gérée: {exc}", exc_info=True)
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"detail": "Erreur interne du serveur"}
|
|
)
|
|
|
|
@app.get("/")
|
|
async def root():
|
|
"""Point d'entrée principal"""
|
|
return {
|
|
"message": "API Notariat Pipeline (Simplifié)",
|
|
"version": "1.0.0-simple",
|
|
"status": "running",
|
|
"features": {
|
|
"ai_disabled": True,
|
|
"ocr_enabled": False,
|
|
"classification_enabled": False,
|
|
"extraction_enabled": False
|
|
}
|
|
}
|
|
|
|
@app.post("/api/import")
|
|
async def import_document(
|
|
file: UploadFile = File(...),
|
|
id_dossier: str = Form(...),
|
|
source: str = Form("upload"),
|
|
etude_id: str = Form(...),
|
|
utilisateur_id: str = Form(...),
|
|
db = Depends(get_db)
|
|
):
|
|
"""
|
|
Import d'un nouveau document dans le pipeline (version simplifiée)
|
|
"""
|
|
try:
|
|
# Vérification du type de fichier
|
|
allowed_types = ["application/pdf", "image/jpeg", "image/png", "image/tiff"]
|
|
if file.content_type not in allowed_types:
|
|
raise HTTPException(
|
|
status_code=415,
|
|
detail=f"Type de fichier non supporté: {file.content_type}"
|
|
)
|
|
|
|
# Génération d'un ID unique
|
|
doc_id = str(uuid.uuid4())
|
|
|
|
# Lecture du contenu du fichier
|
|
content = await file.read()
|
|
file_size = len(content)
|
|
|
|
# Stockage du document
|
|
storage_path = await store_document(doc_id, content, file.filename)
|
|
|
|
# Création de l'enregistrement en base
|
|
from domain.database import Document
|
|
document = Document(
|
|
id=doc_id,
|
|
filename=file.filename or "unknown",
|
|
mime_type=file.content_type,
|
|
size=file_size,
|
|
status=DocumentStatus.PENDING.value,
|
|
id_dossier=id_dossier,
|
|
etude_id=etude_id,
|
|
utilisateur_id=utilisateur_id,
|
|
source=source
|
|
)
|
|
|
|
db.add(document)
|
|
db.commit()
|
|
db.refresh(document)
|
|
|
|
logger.info(f"Document {doc_id} importé avec succès (version simplifiée)")
|
|
|
|
return {
|
|
"status": "stored",
|
|
"id_document": doc_id,
|
|
"message": "Document stocké (traitement IA désactivé)",
|
|
"storage_path": storage_path
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors de l'import du document: {e}")
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
@app.get("/api/documents/{document_id}")
|
|
async def get_document(
|
|
document_id: str,
|
|
db = Depends(get_db)
|
|
):
|
|
"""
|
|
Récupération des informations d'un document
|
|
"""
|
|
from domain.database import Document
|
|
document = db.query(Document).filter(Document.id == document_id).first()
|
|
|
|
if not document:
|
|
raise HTTPException(status_code=404, detail="Document non trouvé")
|
|
|
|
return {
|
|
"id": document.id,
|
|
"filename": document.filename,
|
|
"mime_type": document.mime_type,
|
|
"size": document.size,
|
|
"status": document.status,
|
|
"id_dossier": document.id_dossier,
|
|
"etude_id": document.etude_id,
|
|
"utilisateur_id": document.utilisateur_id,
|
|
"created_at": document.created_at,
|
|
"updated_at": document.updated_at,
|
|
"processing_steps": document.processing_steps,
|
|
"extracted_data": document.extracted_data,
|
|
"errors": document.errors
|
|
}
|
|
|
|
@app.get("/api/documents")
|
|
async def list_documents(
|
|
etude_id: str = None,
|
|
id_dossier: str = None,
|
|
limit: int = 50,
|
|
offset: int = 0,
|
|
db = Depends(get_db)
|
|
):
|
|
"""
|
|
Liste des documents avec filtres
|
|
"""
|
|
from domain.database import Document
|
|
query = db.query(Document)
|
|
|
|
if etude_id:
|
|
query = query.filter(Document.etude_id == etude_id)
|
|
|
|
if id_dossier:
|
|
query = query.filter(Document.id_dossier == id_dossier)
|
|
|
|
documents = query.offset(offset).limit(limit).all()
|
|
|
|
return [
|
|
{
|
|
"id": doc.id,
|
|
"filename": doc.filename,
|
|
"mime_type": doc.mime_type,
|
|
"size": doc.size,
|
|
"status": doc.status,
|
|
"id_dossier": doc.id_dossier,
|
|
"etude_id": doc.etude_id,
|
|
"utilisateur_id": doc.utilisateur_id,
|
|
"created_at": doc.created_at,
|
|
"updated_at": doc.updated_at
|
|
}
|
|
for doc in documents
|
|
]
|