import json import logging from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Request, status from pydantic import BaseModel from open_webui.socket.main import sio from open_webui.models.channels import Channels, ChannelModel, ChannelForm from open_webui.models.messages import Messages, MessageModel, MessageForm from open_webui.config import ENABLE_ADMIN_CHAT_ACCESS, ENABLE_ADMIN_EXPORT from open_webui.constants import ERROR_MESSAGES from open_webui.env import SRC_LOG_LEVELS from open_webui.utils.auth import get_admin_user, get_verified_user from open_webui.utils.access_control import has_access log = logging.getLogger(__name__) log.setLevel(SRC_LOG_LEVELS["MODELS"]) router = APIRouter() ############################ # GetChatList ############################ @router.get("/", response_model=list[ChannelModel]) async def get_channels(user=Depends(get_verified_user)): if user.role == "admin": return Channels.get_channels() else: return Channels.get_channels_by_user_id(user.id) ############################ # CreateNewChannel ############################ @router.post("/create", response_model=Optional[ChannelModel]) async def create_new_channel(form_data: ChannelForm, user=Depends(get_admin_user)): try: channel = Channels.insert_new_channel(form_data, user.id) return ChannelModel(**channel.model_dump()) except Exception as e: log.exception(e) raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() ) ############################ # GetChannelMessages ############################ @router.get("/{id}/messages", response_model=list[MessageModel]) async def get_channel_messages(id: str, page: int = 1, user=Depends(get_verified_user)): channel = Channels.get_channel_by_id(id) if not channel: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND ) if not has_access(user.id, type="read", access_control=channel.access_control): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() ) limit = 50 skip = (page - 1) * limit return Messages.get_messages_by_channel_id(id, skip, limit) ############################ # PostNewMessage ############################ @router.post("/{id}/messages/post", response_model=Optional[MessageModel]) async def post_new_message( id: str, form_data: MessageForm, user=Depends(get_verified_user) ): channel = Channels.get_channel_by_id(id) if not channel: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND ) if not has_access(user.id, type="read", access_control=channel.access_control): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() ) try: message = Messages.insert_new_message(form_data, channel.id, user.id) if message: await sio.emit( "channel-events", { "channel_id": channel.id, "message_id": message.id, "data": {"type": "message", "data": message.model_dump()}, }, to=f"channel:{channel.id}", ) return MessageModel(**message.model_dump()) except Exception as e: log.exception(e) raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() )