Download app/api/services.py from umar-30/AI-todo: direct link, hf CLI and curl.
- Browser
- Download file 4.19 kB
-
https://huggingface.co/spaces/umar-30/AI-todo/resolve/main/app/api/services.py
- Command line
-
hf download hf://spaces/umar-30/AI-todo/app/api/services.py
-
curl -L -o services.py https://huggingface.co/spaces/umar-30/AI-todo/resolve/main/app/api/services.py
4.19 kB
| """ | |
| Conversation service for database operations. | |
| Provides stateless database operations for conversations and messages. | |
| All state is loaded fresh from the database per request. | |
| """ | |
| from datetime import datetime, timezone | |
| from typing import Optional | |
| from uuid import UUID | |
| from sqlmodel import Session, select | |
| from ..database import get_engine | |
| from ..models.conversation import Conversation | |
| from ..models.message import Message | |
| class ConversationNotFoundError(Exception): | |
| """Raised when a conversation is not found.""" | |
| pass | |
| class ConversationAccessDeniedError(Exception): | |
| """Raised when user doesn't own the conversation.""" | |
| pass | |
| def _get_session() -> Session: | |
| """Get a new database session.""" | |
| return Session(get_engine()) | |
| def get_conversation_with_messages( | |
| conversation_id: UUID, | |
| user_id: str | |
| ) -> tuple[Conversation, list[Message]]: | |
| """ | |
| Load a conversation with all its messages from the database. | |
| Args: | |
| conversation_id: The conversation's unique identifier | |
| user_id: The user's unique identifier for ownership validation | |
| Returns: | |
| Tuple of (Conversation, list of Messages ordered by created_at) | |
| Raises: | |
| ConversationNotFoundError: If conversation doesn't exist | |
| ConversationAccessDeniedError: If user doesn't own the conversation | |
| """ | |
| with _get_session() as session: | |
| # Load conversation | |
| statement = select(Conversation).where(Conversation.id == conversation_id) | |
| conversation = session.exec(statement).first() | |
| if not conversation: | |
| raise ConversationNotFoundError( | |
| f"Conversation {conversation_id} not found" | |
| ) | |
| # Validate ownership | |
| if conversation.user_id != user_id: | |
| raise ConversationAccessDeniedError( | |
| f"Access denied to conversation {conversation_id}" | |
| ) | |
| # Load messages ordered by created_at | |
| msg_statement = ( | |
| select(Message) | |
| .where(Message.conversation_id == conversation_id) | |
| .order_by(Message.created_at) | |
| ) | |
| messages = list(session.exec(msg_statement).all()) | |
| return conversation, messages | |
| def create_conversation(user_id: str) -> Conversation: | |
| """ | |
| Create a new conversation for a user. | |
| Args: | |
| user_id: The user's unique identifier | |
| Returns: | |
| Newly created Conversation with generated ID | |
| """ | |
| conversation = Conversation(user_id=user_id) | |
| with _get_session() as session: | |
| session.add(conversation) | |
| session.commit() | |
| session.refresh(conversation) | |
| return conversation | |
| def create_message( | |
| user_id: str, | |
| conversation_id: UUID, | |
| role: str, | |
| content: str | |
| ) -> Message: | |
| """ | |
| Create a new message in a conversation. | |
| Also updates the conversation's updated_at timestamp. | |
| Args: | |
| user_id: The user's unique identifier | |
| conversation_id: The parent conversation's ID | |
| role: Message role ("user" or "assistant") | |
| content: Message content | |
| Returns: | |
| Newly created Message | |
| """ | |
| message = Message( | |
| user_id=user_id, | |
| conversation_id=conversation_id, | |
| role=role, | |
| content=content, | |
| ) | |
| with _get_session() as session: | |
| # Add the message | |
| session.add(message) | |
| # Update conversation timestamp | |
| statement = select(Conversation).where(Conversation.id == conversation_id) | |
| conversation = session.exec(statement).first() | |
| if conversation: | |
| conversation.updated_at = datetime.now(timezone.utc) | |
| session.add(conversation) | |
| session.commit() | |
| session.refresh(message) | |
| return message | |
| def get_conversation(conversation_id: UUID) -> Optional[Conversation]: | |
| """ | |
| Get a conversation by ID without messages. | |
| Args: | |
| conversation_id: The conversation's unique identifier | |
| Returns: | |
| Conversation if found, None otherwise | |
| """ | |
| with _get_session() as session: | |
| statement = select(Conversation).where(Conversation.id == conversation_id) | |
| return session.exec(statement).first() | |