feat: revue de code, doc CODE_REVIEW, forfaits 2026, traduction LLM, providers avec modèle
Made-with: Cursor
This commit is contained in:
120
services/providers/schemas.py
Normal file
120
services/providers/schemas.py
Normal file
@@ -0,0 +1,120 @@
|
||||
"""
|
||||
Pydantic models for translation provider request/response schemas.
|
||||
"""
|
||||
|
||||
import re
|
||||
from typing import Optional, List
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
||||
|
||||
|
||||
LANGUAGE_CODE_PATTERN = re.compile(r"^[a-z]{2}(-[A-Z]{2})?$|^auto$")
|
||||
|
||||
|
||||
class TranslationRequest(BaseModel):
|
||||
"""Request model for translation operations."""
|
||||
|
||||
text: str = Field(..., description="Text to translate")
|
||||
target_language: str = Field(
|
||||
..., description="Target language code (e.g., 'en', 'fr', 'es')"
|
||||
)
|
||||
source_language: str = Field(
|
||||
default="auto", description="Source language code (default: auto-detect)"
|
||||
)
|
||||
metadata: Optional[dict] = Field(
|
||||
default=None,
|
||||
description="Optional metadata for provider-specific options (e.g., custom_prompt)",
|
||||
)
|
||||
|
||||
@field_validator("target_language", "source_language")
|
||||
@classmethod
|
||||
def validate_language_code(cls, v: str) -> str:
|
||||
if not LANGUAGE_CODE_PATTERN.match(v):
|
||||
raise ValueError(
|
||||
f"Invalid language code '{v}'. Expected format: 'xx' or 'xx-XX' (e.g., 'en', 'fr', 'en-US')"
|
||||
)
|
||||
return v
|
||||
|
||||
|
||||
class TranslationResponse(BaseModel):
|
||||
"""Response model for translation operations."""
|
||||
|
||||
translated_text: str = Field(..., description="Translated text")
|
||||
provider_name: str = Field(
|
||||
..., description="Name of the provider that performed the translation"
|
||||
)
|
||||
from_cache: bool = Field(
|
||||
default=False, description="Whether the result came from cache"
|
||||
)
|
||||
source_language: Optional[str] = Field(
|
||||
default=None, description="Detected or specified source language"
|
||||
)
|
||||
error: Optional[str] = Field(
|
||||
default=None, description="Error message if translation failed"
|
||||
)
|
||||
error_code: Optional[str] = Field(
|
||||
default=None, description="Error code for programmatic error handling"
|
||||
)
|
||||
error_details: Optional[dict] = Field(
|
||||
default=None, description="Additional error details"
|
||||
)
|
||||
|
||||
@property
|
||||
def success(self) -> bool:
|
||||
"""Check if translation was successful."""
|
||||
return self.error is None
|
||||
|
||||
def to_error_dict(self) -> dict:
|
||||
"""Convert error to dictionary format for API responses."""
|
||||
if self.error is None:
|
||||
return {}
|
||||
result = {
|
||||
"error": self.error_code or "UNKNOWN_ERROR",
|
||||
"message": self.error,
|
||||
}
|
||||
if self.error_details:
|
||||
result["details"] = self.error_details
|
||||
return result
|
||||
|
||||
|
||||
class BatchTranslationRequest(BaseModel):
|
||||
"""Request model for batch translation operations."""
|
||||
|
||||
texts: List[str] = Field(..., description="List of texts to translate")
|
||||
target_language: str = Field(..., description="Target language code")
|
||||
source_language: str = Field(
|
||||
default="auto", description="Source language code (default: auto-detect)"
|
||||
)
|
||||
|
||||
|
||||
class BatchTranslationResponse(BaseModel):
|
||||
"""Response model for batch translation operations."""
|
||||
|
||||
translated_texts: List[str] = Field(..., description="List of translated texts")
|
||||
provider_name: str = Field(
|
||||
..., description="Name of the provider that performed the translations"
|
||||
)
|
||||
from_cache_count: int = Field(default=0, description="Number of results from cache")
|
||||
|
||||
|
||||
class ProviderHealthStatus(BaseModel):
|
||||
"""Health status model for a translation provider."""
|
||||
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
name: str = Field(..., description="Provider name")
|
||||
available: bool = Field(..., description="Whether the provider is available")
|
||||
latency_ms: Optional[float] = Field(
|
||||
default=None, description="Response latency in milliseconds"
|
||||
)
|
||||
error: Optional[str] = Field(
|
||||
default=None, description="Error message if unavailable"
|
||||
)
|
||||
last_check: Optional[str] = Field(
|
||||
default=None, description="ISO timestamp of last health check"
|
||||
)
|
||||
model: Optional[str] = Field(
|
||||
default=None, description="Model name (e.g. for LLM providers)"
|
||||
)
|
||||
model_available: Optional[bool] = Field(
|
||||
default=None, description="Whether the configured model is available"
|
||||
)
|
||||
Reference in New Issue
Block a user