""" Pydantic models for API key endpoints Story 3.6: Documentation OpenAPI (Swagger + ReDoc) """ from pydantic import BaseModel, Field from typing import Optional class APIKeyCreateRequest(BaseModel): """Request model for creating an API key""" name: Optional[str] = Field( default="Default API Key", max_length=100, example="Production API Key", description="Nom descriptif pour la clé API" ) class Config: json_schema_extra = { "example": { "name": "Production API Key" } } class APIKeyData(BaseModel): """API key data in response (full key shown only on creation)""" id: str = Field( ..., example="550e8400-e29b-41d4-a716-446655440000", description="Identifiant unique de la clé API" ) key: str = Field( ..., example="sk_live_abc123def456ghi789...", description="Clé API complète (affichée UNE SEULE FOIS à la création)" ) name: str = Field( ..., example="Production API Key", description="Nom de la clé API" ) key_prefix: str = Field( ..., example="sk_live_", description="Préfixe de la clé (pour identification)" ) created_at: str = Field( ..., example="2024-01-15T10:30:00Z", description="Date de création (ISO 8601)" ) class APIKeyResponse(BaseModel): """Response model for API key creation""" data: APIKeyData meta: dict = Field(default_factory=dict) class Config: json_schema_extra = { "example": { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "key": "sk_live_abc123def456ghi789jkl012mno345pqr678...", "name": "Production API Key", "key_prefix": "sk_live_", "created_at": "2024-01-15T10:30:00Z" }, "meta": {} } } class APIKeyListItem(BaseModel): """API key item in list (without secret)""" id: str = Field(..., description="Identifiant unique de la clé API") name: str = Field(..., description="Nom de la clé API") key_prefix: str = Field(..., description="Préfixe de la clé (pour identification)") is_active: bool = Field(..., description="Si la clé est active") last_used_at: Optional[str] = Field(None, description="Dernière utilisation (ISO 8601)") usage_count: int = Field(..., description="Nombre total d'utilisations") created_at: str = Field(..., description="Date de création (ISO 8601)") class Config: json_schema_extra = { "example": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Production API Key", "key_prefix": "sk_live_", "is_active": True, "last_used_at": "2024-01-15T14:30:00Z", "usage_count": 42, "created_at": "2024-01-15T10:30:00Z" } } class APIKeyListMeta(BaseModel): """Metadata for API key list response""" total: int = Field(..., description="Nombre total de clés API") class Config: json_schema_extra = { "example": { "total": 2 } } class APIKeyListResponse(BaseModel): """Response model for listing API keys""" data: list[APIKeyListItem] meta: APIKeyListMeta class Config: json_schema_extra = { "example": { "data": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Production API Key", "key_prefix": "sk_live_", "is_active": True, "last_used_at": "2024-01-15T14:30:00Z", "usage_count": 42, "created_at": "2024-01-15T10:30:00Z" }, { "id": "660e8400-e29b-41d4-a716-446655440001", "name": "Development API Key", "key_prefix": "sk_live_", "is_active": True, "last_used_at": None, "usage_count": 0, "created_at": "2024-01-16T09:00:00Z" } ], "meta": { "total": 2 } } } class APIKeyRevokeData(BaseModel): """Data returned after API key revocation""" id: str = Field(..., description="Identifiant de la clé révoquée") revoked: bool = Field(..., description="Confirmation de révocation") revoked_at: str = Field(..., description="Date de révocation (ISO 8601)") class APIKeyRevokeResponse(BaseModel): """Response model for API key revocation""" data: APIKeyRevokeData meta: dict = Field(default_factory=dict) class Config: json_schema_extra = { "example": { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "revoked": True, "revoked_at": "2024-01-15T16:00:00Z" }, "meta": {} } }