Files
ARC/backend/app/schemas/spec.py
2026-06-16 11:27:41 +02:00

55 lines
4.2 KiB
Python

#spec.py
from pydantic import BaseModel, Field, model_validator
from typing import List, Optional, Literal
class InputOutputConfig(BaseModel):
has_inputs: bool = Field(default=False, description="Le script prend-il des éléments en entrée ?")
input_type: Optional[Literal["file", "directory", "api", "database", "none"]] = Field(None, description="Type d'entrée principale")
input_paths_or_sources: List[str] = Field(default_factory=list, description="Chemins, tables ou endpoints sources")
has_outputs: bool = Field(default=False, description="Le script génère-t-style des éléments en sortie ?")
output_type: Optional[Literal["file", "directory", "database", "api_response", "log_only"]] = Field(None, description="Type de sortie principale")
output_formats: List[str] = Field(default_factory=list, description="Formats attendus (ex: CSV, JSON, XLSX)")
class AuthenticationConfig(BaseModel):
requires_auth: bool = Field(default=False, description="Le script nécessite-t-il des accès sécurisés ?")
auth_method: Optional[Literal["env_variables", "service_account_json", "oauth2", "api_key", "none"]] = Field(None, description="Méthode d'authentification")
target_tools_and_apis: List[str] = Field(default_factory=list, description="Logiciels ou API avec lesquels interagir (ex: Sharepoint, JIRA)")
class EnvironmentConfig(BaseModel):
target_os: Literal["linux", "windows", "macos", "cross_platform"] = Field(default="cross_platform", description="Système d'exploitation cible")
language_version: str = Field(default="^3.11", description="Contrainte de version du langage")
critical_dependencies: List[str] = Field(default_factory=list, description="Librairies tierces indispensables")
class ProjectSpec(BaseModel):
title: Optional[str] = Field(None, description="Nom clair et concis du script")
description: Optional[str] = Field(None, description="Description macro de l'objectif du script")
requirements: List[str] = Field(default_factory=list, description="Liste des fonctionnalités pas-à-pas attendues")
constraints: List[str] = Field(default_factory=list, description="Normes, formats de code et conventions de nommage imposés")
language: str = Field(default="Python", description="Langage de programmation principal")
target_stack: str = Field(None, description="Stack technique ou framework attendu (ex: Pandas, FastAPI, Flask, Django, etc.)")
# Sous-configurations détaillées (permettent la détection des champs manquants)
io_config: InputOutputConfig = Field(default_factory=InputOutputConfig)
auth_config: AuthenticationConfig = Field(default_factory=AuthenticationConfig)
env_config: EnvironmentConfig = Field(default_factory=EnvironmentConfig)
error_handling_strategy: Literal["abort_on_error", "log_and_continue", "retry_policy"] = Field(
default="log_and_continue",
description="Comportement du script face à une anomalie"
)
is_complete: bool = Field(default=False, description="Passez à True UNIQUEMENT si vous avez TOUTES les infos pour coder (titre, desc, reqs, io_config, auth_config si besoin).")
clarifying_question: Optional[str] = Field(None, description="Si is_complete est False, écrivez ici une question claire et polie pour Chainlit pour demander les détails manquants.")
@model_validator(mode="after")
def validate_conditional_fields(self) -> 'ProjectSpec':
"""Validation des dépendances logiques pour marquer le cahier des charges comme valide."""
# Si les champs majeurs sont remplis, on valide la cohérence interne
if self.title and self.description and len(self.requirements) > 0:
if self.io_config.has_inputs and not self.io_config.input_type:
raise ValueError("input_type manquant alors que has_inputs est True")
if self.io_config.has_outputs and not self.io_config.output_type:
raise ValueError("output_type manquant alors que has_outputs est True")
if self.auth_config.requires_auth and (not self.auth_config.auth_method or self.auth_config.auth_method == "none"):
raise ValueError("auth_method manquante alors que requires_auth est True")
return self