""" Endpoints pour la liste des attributs uniques """ from fastapi import APIRouter, HTTPException, Query from ..database import db from ..models import AttributeListResponse, AttributeListItem router = APIRouter(prefix="/api/attributes", tags=["attributes"]) @router.get("/{attr_type}", response_model=AttributeListResponse) async def get_attributes( attr_type: str, limit: int = Query(100, ge=1, le=1000, description="Nombre maximum de résultats") ): """ Récupère la liste des valeurs uniques pour un type d'attribut """ try: # Mapping des types vers les colonnes type_column_map = { "ip": "src_ip", "ja4": "ja4", "country": "country_code", "asn": "asn_number", "host": "host", "threat_level": "threat_level", "model_name": "model_name", "asn_org": "asn_org" } if attr_type not in type_column_map: raise HTTPException( status_code=400, detail=f"Type invalide. Types supportés: {', '.join(type_column_map.keys())}" ) column = type_column_map[attr_type] # Requête de base base_query = f""" SELECT {column} AS value, count() AS count FROM ml_detected_anomalies WHERE detected_at >= now() - INTERVAL 24 HOUR """ # Ajout du filtre pour exclure les valeurs vides/nulles # Gestion spéciale pour les types IPv6/IPv4 qui ne peuvent pas être comparés à '' if attr_type == "ip": # Pour les adresses IP, on convertit en string et on filtre query = f""" SELECT value, count FROM ( SELECT toString({column}) AS value, count() AS count FROM ml_detected_anomalies WHERE detected_at >= now() - INTERVAL 24 HOUR GROUP BY {column} ) WHERE value != '' AND value IS NOT NULL ORDER BY count DESC LIMIT %(limit)s """ else: query = f""" {base_query} AND {column} != '' AND {column} IS NOT NULL GROUP BY value ORDER BY count DESC LIMIT %(limit)s """ result = db.query(query, {"limit": limit}) items = [ AttributeListItem( value=str(row[0]), count=row[1] ) for row in result.result_rows ] return AttributeListResponse( type=attr_type, items=items, total=len(items) ) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")