feat: /chat/completions/{completion_id}/messages implementation completed
Browse files- app/api/chat_api.py +7 -36
- app/repository/chat_repository.py +1 -1
- app/schema/chat_schema.py +2 -0
- app/service/chat_service.py +7 -4
app/api/chat_api.py
CHANGED
|
@@ -3,16 +3,8 @@
|
|
| 3 |
from typing import List
|
| 4 |
from fastapi import APIRouter, HTTPException, Depends, Request
|
| 5 |
from pydantic import BaseModel
|
| 6 |
-
from app.schema.chat_schema import
|
| 7 |
-
|
| 8 |
-
ChatCompletionResponse,
|
| 9 |
-
MessageResponse,
|
| 10 |
-
PlotResponse,
|
| 11 |
-
)
|
| 12 |
-
from app.schema.conversation_schema import (
|
| 13 |
-
ConversationResponse,
|
| 14 |
-
ConversationItemResponse,
|
| 15 |
-
)
|
| 16 |
from app.service.chat_service import ChatService
|
| 17 |
from app.security.auth_service import AuthService
|
| 18 |
from app.core.api_response import api_response
|
|
@@ -40,9 +32,7 @@ async def get_version():
|
|
| 40 |
@router.post("/chat/completions", response_model=ChatCompletionResponse)
|
| 41 |
@api_response()
|
| 42 |
async def create_chat_completion(
|
| 43 |
-
chat_completion: ChatCompletionRequest,
|
| 44 |
-
request: Request,
|
| 45 |
-
username: str = Depends(auth_service.verify_credentials),
|
| 46 |
):
|
| 47 |
"""
|
| 48 |
Chat completion API - Given a list of messages comprising a conversation, the model will return a response.
|
|
@@ -58,10 +48,7 @@ async def create_chat_completion(
|
|
| 58 |
|
| 59 |
# get all chat completions
|
| 60 |
@router.get("/chat/completions", response_model=List[ChatCompletionResponse], deprecated=True)
|
| 61 |
-
async def list_chat_completions(
|
| 62 |
-
request: Request,
|
| 63 |
-
username: str = Depends(auth_service.verify_credentials),
|
| 64 |
-
):
|
| 65 |
"""
|
| 66 |
Get all chat completions
|
| 67 |
Summary: First load the chat interface(UI) for list of chat completions on the left side.
|
|
@@ -81,12 +68,7 @@ async def list_chat_completions(
|
|
| 81 |
|
| 82 |
# get a chat completion by id
|
| 83 |
@router.get("/chat/completions/{completion_id}", response_model=ChatCompletionResponse)
|
| 84 |
-
|
| 85 |
-
async def retrieve_chat_completion(
|
| 86 |
-
completion_id: str,
|
| 87 |
-
request: Request,
|
| 88 |
-
username: str = Depends(auth_service.verify_credentials),
|
| 89 |
-
):
|
| 90 |
"""
|
| 91 |
Get a chat completion by id
|
| 92 |
Summary: Click on a chat completion on the left side to load the chat completion on the right side.
|
|
@@ -99,12 +81,7 @@ async def retrieve_chat_completion(
|
|
| 99 |
|
| 100 |
# get all messages for a chat completion
|
| 101 |
@router.get("/chat/completions/{completion_id}/messages", response_model=List[MessageResponse], deprecated=True)
|
| 102 |
-
|
| 103 |
-
async def list_messages(
|
| 104 |
-
completion_id: str,
|
| 105 |
-
request: Request,
|
| 106 |
-
username: str = Depends(auth_service.verify_credentials),
|
| 107 |
-
):
|
| 108 |
"""
|
| 109 |
Get all messages for a chat completion
|
| 110 |
Summary: Click on a chat completion on the left side to load the chat completion on the right side.
|
|
@@ -120,13 +97,7 @@ async def list_messages(
|
|
| 120 |
################
|
| 121 |
# get a plot for a message
|
| 122 |
@router.get("/chat/completions/{completion_id}/messages/{message_id}/plot", response_model=PlotResponse)
|
| 123 |
-
|
| 124 |
-
async def retrieve_plot(
|
| 125 |
-
completion_id: str,
|
| 126 |
-
message_id: str,
|
| 127 |
-
request: Request,
|
| 128 |
-
username: str = Depends(auth_service.verify_credentials),
|
| 129 |
-
):
|
| 130 |
"""
|
| 131 |
Get a plot figure for a message to visualize the data
|
| 132 |
Summary: Click on a message on the right side to load the plot on the right side.
|
|
|
|
| 3 |
from typing import List
|
| 4 |
from fastapi import APIRouter, HTTPException, Depends, Request
|
| 5 |
from pydantic import BaseModel
|
| 6 |
+
from app.schema.chat_schema import ChatCompletionRequest, ChatCompletionResponse, MessageResponse, PlotResponse
|
| 7 |
+
from app.schema.conversation_schema import ConversationResponse, ConversationItemResponse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
from app.service.chat_service import ChatService
|
| 9 |
from app.security.auth_service import AuthService
|
| 10 |
from app.core.api_response import api_response
|
|
|
|
| 32 |
@router.post("/chat/completions", response_model=ChatCompletionResponse)
|
| 33 |
@api_response()
|
| 34 |
async def create_chat_completion(
|
| 35 |
+
chat_completion: ChatCompletionRequest, request: Request, username: str = Depends(auth_service.verify_credentials)
|
|
|
|
|
|
|
| 36 |
):
|
| 37 |
"""
|
| 38 |
Chat completion API - Given a list of messages comprising a conversation, the model will return a response.
|
|
|
|
| 48 |
|
| 49 |
# get all chat completions
|
| 50 |
@router.get("/chat/completions", response_model=List[ChatCompletionResponse], deprecated=True)
|
| 51 |
+
async def list_chat_completions(request: Request, username: str = Depends(auth_service.verify_credentials)):
|
|
|
|
|
|
|
|
|
|
| 52 |
"""
|
| 53 |
Get all chat completions
|
| 54 |
Summary: First load the chat interface(UI) for list of chat completions on the left side.
|
|
|
|
| 68 |
|
| 69 |
# get a chat completion by id
|
| 70 |
@router.get("/chat/completions/{completion_id}", response_model=ChatCompletionResponse)
|
| 71 |
+
async def retrieve_chat_completion(completion_id: str, request: Request, username: str = Depends(auth_service.verify_credentials)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
"""
|
| 73 |
Get a chat completion by id
|
| 74 |
Summary: Click on a chat completion on the left side to load the chat completion on the right side.
|
|
|
|
| 81 |
|
| 82 |
# get all messages for a chat completion
|
| 83 |
@router.get("/chat/completions/{completion_id}/messages", response_model=List[MessageResponse], deprecated=True)
|
| 84 |
+
async def list_messages(completion_id: str, request: Request, username: str = Depends(auth_service.verify_credentials)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
"""
|
| 86 |
Get all messages for a chat completion
|
| 87 |
Summary: Click on a chat completion on the left side to load the chat completion on the right side.
|
|
|
|
| 97 |
################
|
| 98 |
# get a plot for a message
|
| 99 |
@router.get("/chat/completions/{completion_id}/messages/{message_id}/plot", response_model=PlotResponse)
|
| 100 |
+
async def retrieve_plot(completion_id: str, message_id: str, request: Request, username: str = Depends(auth_service.verify_credentials)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
"""
|
| 102 |
Get a plot figure for a message to visualize the data
|
| 103 |
Summary: Click on a message on the right side to load the plot on the right side.
|
app/repository/chat_repository.py
CHANGED
|
@@ -179,7 +179,7 @@ class ChatRepository:
|
|
| 179 |
logger.debug(f"BEGIN REPO: find messages for chat completion id. input parameters: completion_id: {completion_id}")
|
| 180 |
projection = {"messages": 1, "_id": 0}
|
| 181 |
chat_doc = await self.db.chat_completion.find_one({"completion_id": completion_id}, projection)
|
| 182 |
-
|
| 183 |
if chat_doc and "messages" in chat_doc and chat_doc["messages"]:
|
| 184 |
try:
|
| 185 |
messages_list = [ChatMessage(**item) for item in chat_doc["messages"]]
|
|
|
|
| 179 |
logger.debug(f"BEGIN REPO: find messages for chat completion id. input parameters: completion_id: {completion_id}")
|
| 180 |
projection = {"messages": 1, "_id": 0}
|
| 181 |
chat_doc = await self.db.chat_completion.find_one({"completion_id": completion_id}, projection)
|
| 182 |
+
logger.trace(f"REPO find_messages. chat_doc: {chat_doc}")
|
| 183 |
if chat_doc and "messages" in chat_doc and chat_doc["messages"]:
|
| 184 |
try:
|
| 185 |
messages_list = [ChatMessage(**item) for item in chat_doc["messages"]]
|
app/schema/chat_schema.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
from typing import List, Optional
|
| 2 |
from pydantic import BaseModel, Field
|
|
|
|
| 3 |
|
| 4 |
|
| 5 |
class MessageRequest(BaseModel):
|
|
@@ -34,6 +35,7 @@ class MessageResponse(BaseModel):
|
|
| 34 |
role: Optional[str] = Field(None, description="The role of the message", examples=["user", "assistant", "system"])
|
| 35 |
content: Optional[str] = Field(None, description="The content of the message")
|
| 36 |
figure: Optional[dict] = Field(None, description="The figure data to be visualized")
|
|
|
|
| 37 |
|
| 38 |
|
| 39 |
class ChoiceResponse(BaseModel):
|
|
|
|
| 1 |
from typing import List, Optional
|
| 2 |
from pydantic import BaseModel, Field
|
| 3 |
+
from datetime import datetime
|
| 4 |
|
| 5 |
|
| 6 |
class MessageRequest(BaseModel):
|
|
|
|
| 35 |
role: Optional[str] = Field(None, description="The role of the message", examples=["user", "assistant", "system"])
|
| 36 |
content: Optional[str] = Field(None, description="The content of the message")
|
| 37 |
figure: Optional[dict] = Field(None, description="The figure data to be visualized")
|
| 38 |
+
created_date: Optional[datetime] = Field(None, description="The date and time the message was created")
|
| 39 |
|
| 40 |
|
| 41 |
class ChoiceResponse(BaseModel):
|
app/service/chat_service.py
CHANGED
|
@@ -1,8 +1,7 @@
|
|
| 1 |
import datetime
|
| 2 |
from typing import List
|
| 3 |
from app.repository.chat_repository import ChatRepository
|
| 4 |
-
from app.schema.chat_schema import ChatCompletionRequest, ChatCompletionResponse
|
| 5 |
-
from app.model.chat_model import ChatMessage
|
| 6 |
from app.mapper.chat_mapper import ChatMapper
|
| 7 |
from app.mapper.conversation_mapper import ConversationMapper
|
| 8 |
import uuid
|
|
@@ -47,8 +46,12 @@ class ChatService:
|
|
| 47 |
entity = await self.chat_repository.find_by_id(completion_id, project)
|
| 48 |
return self.chat_mapper.to_schema(entity) if entity else None
|
| 49 |
|
| 50 |
-
async def find_messages(self, completion_id: str) -> List[
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
# conversation service
|
| 54 |
async def find_all_conversations(self, username: str) -> List[ConversationResponse]:
|
|
|
|
| 1 |
import datetime
|
| 2 |
from typing import List
|
| 3 |
from app.repository.chat_repository import ChatRepository
|
| 4 |
+
from app.schema.chat_schema import ChatCompletionRequest, ChatCompletionResponse, MessageResponse
|
|
|
|
| 5 |
from app.mapper.chat_mapper import ChatMapper
|
| 6 |
from app.mapper.conversation_mapper import ConversationMapper
|
| 7 |
import uuid
|
|
|
|
| 46 |
entity = await self.chat_repository.find_by_id(completion_id, project)
|
| 47 |
return self.chat_mapper.to_schema(entity) if entity else None
|
| 48 |
|
| 49 |
+
async def find_messages(self, completion_id: str) -> List[MessageResponse]:
|
| 50 |
+
logger.debug(f"BEGIN SERVICE: find_messages for completion_id: {completion_id}")
|
| 51 |
+
messages = await self.chat_repository.find_messages(completion_id)
|
| 52 |
+
logger.debug(f"END SERVICE: find_messages for completion_id: {completion_id}, messages: {messages}")
|
| 53 |
+
messages_response = [MessageResponse(message_id=message.message_id, role=message.role, content=message.content, created_date=message.created_date) for message in messages]
|
| 54 |
+
return messages_response
|
| 55 |
|
| 56 |
# conversation service
|
| 57 |
async def find_all_conversations(self, username: str) -> List[ConversationResponse]:
|