128 lines
3.7 KiB
Python
128 lines
3.7 KiB
Python
"""
|
|
Prompt Service for Translation
|
|
Story 3.12: Custom Prompts - Application lors Traduction LLM
|
|
|
|
Provides functions to retrieve prompt content and validate access.
|
|
"""
|
|
|
|
import uuid
|
|
import logging
|
|
from typing import Optional, Tuple
|
|
|
|
from database.connection import get_sync_session
|
|
from database.models import CustomPrompt
|
|
from utils.exceptions import PromptNotFoundError
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _validate_uuid(id_str: str, id_name: str = "ID") -> None:
|
|
"""
|
|
Validate that a string is a valid UUID.
|
|
|
|
Args:
|
|
id_str: String to validate
|
|
id_name: Name of the ID for error messages
|
|
|
|
Raises:
|
|
PromptNotFoundError: If the string is not a valid UUID
|
|
"""
|
|
try:
|
|
uuid.UUID(id_str)
|
|
except (ValueError, AttributeError):
|
|
raise PromptNotFoundError(
|
|
message=f"{id_name} invalide.",
|
|
details={id_name.lower(): id_str}
|
|
)
|
|
|
|
|
|
def _get_prompt_record(prompt_id: str, user_id: str) -> Tuple[CustomPrompt, bool]:
|
|
"""
|
|
Internal helper to fetch a prompt record from the database.
|
|
|
|
This is a shared function to avoid code duplication between
|
|
get_prompt_content and validate_prompt_access.
|
|
|
|
Args:
|
|
prompt_id: UUID of the prompt
|
|
user_id: UUID of the user (must own the prompt)
|
|
|
|
Returns:
|
|
Tuple of (CustomPrompt, was_logged) - was_logged indicates if access was already logged
|
|
|
|
Raises:
|
|
PromptNotFoundError: If prompt doesn't exist or doesn't belong to user
|
|
"""
|
|
# Validate UUIDs before querying database
|
|
_validate_uuid(prompt_id, "prompt_id")
|
|
_validate_uuid(user_id, "user_id")
|
|
|
|
try:
|
|
with get_sync_session() as session:
|
|
prompt = (
|
|
session.query(CustomPrompt)
|
|
.filter(CustomPrompt.id == prompt_id, CustomPrompt.user_id == user_id)
|
|
.first()
|
|
)
|
|
|
|
if not prompt:
|
|
raise PromptNotFoundError(
|
|
message="Prompt introuvable ou vous n'avez pas accès à cette ressource.",
|
|
details={"prompt_id": prompt_id}
|
|
)
|
|
|
|
return prompt, False
|
|
|
|
except PromptNotFoundError:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error fetching prompt {prompt_id}: {e}")
|
|
raise PromptNotFoundError(
|
|
message="Erreur lors de la récupération du prompt.",
|
|
details={"prompt_id": prompt_id, "error": str(e)}
|
|
)
|
|
|
|
|
|
def get_prompt_content(prompt_id: str, user_id: str) -> str:
|
|
"""
|
|
Retrieve prompt content for a specific prompt owned by a user.
|
|
|
|
Args:
|
|
prompt_id: UUID of the prompt
|
|
user_id: UUID of the user (must own the prompt)
|
|
|
|
Returns:
|
|
The prompt content string
|
|
|
|
Raises:
|
|
PromptNotFoundError: If prompt doesn't exist or doesn't belong to user
|
|
"""
|
|
prompt, _ = _get_prompt_record(prompt_id, user_id)
|
|
|
|
logger.info(
|
|
f"Retrieved prompt '{prompt.name}' ({prompt_id}) for user {user_id}"
|
|
)
|
|
|
|
return prompt.content
|
|
|
|
|
|
def validate_prompt_access(prompt_id: str, user_id: str) -> bool:
|
|
"""
|
|
Validate that a prompt exists and belongs to the user.
|
|
|
|
Lightweight check before starting a translation job.
|
|
Does NOT log to avoid duplicate log entries when followed by get_prompt_content.
|
|
|
|
Args:
|
|
prompt_id: UUID of the prompt
|
|
user_id: UUID of the user (must own the prompt)
|
|
|
|
Returns:
|
|
True if prompt exists and belongs to user
|
|
|
|
Raises:
|
|
PromptNotFoundError: If prompt doesn't exist or doesn't belong to user
|
|
"""
|
|
_get_prompt_record(prompt_id, user_id)
|
|
return True
|