
- Set up project structure with FastAPI and SQLite - Implement user authentication using JWT - Create database models for users, conversations, and messages - Implement API endpoints for user management and chat functionality - Set up WebSocket for real-time messaging - Add database migrations with Alembic - Create health check endpoint - Update README with comprehensive documentation generated with BackendIM... (backend.im)
116 lines
3.9 KiB
Python
116 lines
3.9 KiB
Python
from typing import Any, List
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.dependencies.auth import get_current_active_user
|
|
from app.db.repositories.conversation import conversation_repository
|
|
from app.db.repositories.user import user_repository
|
|
from app.db.session import get_db
|
|
from app.models.user import User
|
|
from app.schemas.conversation import Conversation, ConversationCreate, ConversationUpdate
|
|
|
|
router = APIRouter(tags=["conversations"])
|
|
|
|
@router.post("/conversations", response_model=Conversation)
|
|
def create_conversation(
|
|
*,
|
|
db: Session = Depends(get_db),
|
|
conversation_in: ConversationCreate,
|
|
current_user: User = Depends(get_current_active_user),
|
|
) -> Any:
|
|
"""
|
|
Create new conversation.
|
|
"""
|
|
# Check if direct conversation between these two users already exists
|
|
if len(conversation_in.participant_ids) == 1 and not conversation_in.is_group:
|
|
other_user_id = conversation_in.participant_ids[0]
|
|
existing_conversation = conversation_repository.get_conversation_between_users(
|
|
db, user_id_1=current_user.id, user_id_2=other_user_id
|
|
)
|
|
if existing_conversation:
|
|
return existing_conversation
|
|
|
|
# Check if all participants exist
|
|
for user_id in conversation_in.participant_ids:
|
|
user = user_repository.get(db, id=user_id)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail=f"User with id {user_id} not found",
|
|
)
|
|
|
|
conversation = conversation_repository.create_with_participants(
|
|
db, obj_in=conversation_in, creator_id=current_user.id
|
|
)
|
|
return conversation
|
|
|
|
@router.get("/conversations", response_model=List[Conversation])
|
|
def read_conversations(
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user),
|
|
) -> Any:
|
|
"""
|
|
Retrieve conversations.
|
|
"""
|
|
conversations = conversation_repository.get_user_conversations(
|
|
db, user_id=current_user.id, skip=skip, limit=limit
|
|
)
|
|
return conversations
|
|
|
|
@router.get("/conversations/{conversation_id}", response_model=Conversation)
|
|
def read_conversation(
|
|
conversation_id: str,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user),
|
|
) -> Any:
|
|
"""
|
|
Get a specific conversation by id.
|
|
"""
|
|
conversation = conversation_repository.get(db, id=conversation_id)
|
|
if not conversation:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Conversation not found",
|
|
)
|
|
|
|
# Check if user is a participant in this conversation
|
|
if current_user not in conversation.participants:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Not a participant of this conversation",
|
|
)
|
|
|
|
return conversation
|
|
|
|
@router.put("/conversations/{conversation_id}", response_model=Conversation)
|
|
def update_conversation(
|
|
*,
|
|
conversation_id: str,
|
|
conversation_in: ConversationUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user),
|
|
) -> Any:
|
|
"""
|
|
Update a conversation.
|
|
"""
|
|
conversation = conversation_repository.get(db, id=conversation_id)
|
|
if not conversation:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Conversation not found",
|
|
)
|
|
|
|
# Check if user is a participant in this conversation
|
|
if current_user not in conversation.participants:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Not a participant of this conversation",
|
|
)
|
|
|
|
conversation = conversation_repository.update(
|
|
db, db_obj=conversation, obj_in=conversation_in
|
|
)
|
|
return conversation |