cevheri commited on
Commit
4c257f6
·
1 Parent(s): 26e046b

feat: add mock conversation api and models

Browse files
.gitignore CHANGED
@@ -6,6 +6,10 @@ dist/
6
  wheels/
7
  *.egg-info
8
 
 
 
 
 
9
  # Virtual environments
10
  .venv
11
 
@@ -18,3 +22,6 @@ app.log
18
  # API key
19
  api_key.txt
20
 
 
 
 
 
6
  wheels/
7
  *.egg-info
8
 
9
+ # ide
10
+ .idea/
11
+ .vscode/
12
+
13
  # Virtual environments
14
  .venv
15
 
 
22
  # API key
23
  api_key.txt
24
 
25
+ .ruff_cache/
26
+
27
+ *_UML*
app/api/chat_api.py CHANGED
@@ -3,16 +3,23 @@
3
  from typing import List
4
  from fastapi import APIRouter, HTTPException, Depends
5
  from app.schema.chat_schema import ChatCompletionRequest, ChatCompletionResponse, MessageResponse, PlotResponse
 
6
  from app.service.chat_service import ChatService
7
  from app.security.auth_service import AuthService
 
 
8
 
9
  router = APIRouter(prefix="/v1", tags=["chat"])
10
  service = ChatService()
11
  auth_service = AuthService()
12
 
 
 
 
13
  # create a chat completion
14
- @router.post("/chat/completions", response_model=ChatCompletionResponse, dependencies=[Depends(auth_service.verify_credentials)])
15
- async def create(req: ChatCompletionRequest, username: str = Depends(auth_service.verify_credentials)):
 
16
  """
17
  Chat completion API - Given a list of messages comprising a conversation, the model will return a response.
18
  If completion_id is not provided, start a new chat completion by providing a list of messages.
@@ -26,8 +33,8 @@ async def create(req: ChatCompletionRequest, username: str = Depends(auth_servic
26
 
27
 
28
  # get all chat completions
29
- @router.get("/chat/completions", response_model=List[ChatCompletionResponse], dependencies=[Depends(auth_service.verify_credentials)])
30
- async def find(username: str = Depends(auth_service.verify_credentials)):
31
  """
32
  Get all chat completions
33
  Summary: First load the chat interface(UI) for list of chat completions on the left side.
@@ -46,8 +53,8 @@ async def find(username: str = Depends(auth_service.verify_credentials)):
46
 
47
 
48
  # get a chat completion by id
49
- @router.get("/chat/completions/{completion_id}", response_model=ChatCompletionResponse, dependencies=[Depends(auth_service.verify_credentials)])
50
- async def find_by_id(completion_id: str, username: str = Depends(auth_service.verify_credentials)):
51
  """
52
  Get a chat completion by id
53
  Summary: Click on a chat completion on the left side to load the chat completion on the right side.
@@ -59,8 +66,8 @@ async def find_by_id(completion_id: str, username: str = Depends(auth_service.ve
59
 
60
 
61
  # get all messages for a chat completion
62
- @router.get("/chat/completions/{completion_id}/messages", response_model=List[MessageResponse], dependencies=[Depends(auth_service.verify_credentials)])
63
- async def find_messages(completion_id: str, username: str = Depends(auth_service.verify_credentials)):
64
  """
65
  Get all messages for a chat completion
66
  Summary: Click on a chat completion on the left side to load the chat completion on the right side.
@@ -71,9 +78,12 @@ async def find_messages(completion_id: str, username: str = Depends(auth_service
71
  raise HTTPException(status_code=500, detail=str(e))
72
 
73
 
 
 
 
74
  # get a plot for a message
75
- @router.get("/chat/completions/{completion_id}/messages/{message_id}/plot", response_model=PlotResponse, dependencies=[Depends(auth_service.verify_credentials)])
76
- async def find_plot(completion_id: str, message_id: str, username: str = Depends(auth_service.verify_credentials)):
77
  """
78
  Get a plot figure for a message to visualize the data
79
  Summary: Click on a message on the right side to load the plot on the right side.
@@ -84,7 +94,32 @@ async def find_plot(completion_id: str, message_id: str, username: str = Depends
84
  raise HTTPException(status_code=500, detail=str(e))
85
 
86
 
 
 
 
 
 
87
 
88
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
-
 
 
 
 
 
 
 
 
 
 
3
  from typing import List
4
  from fastapi import APIRouter, HTTPException, Depends
5
  from app.schema.chat_schema import ChatCompletionRequest, ChatCompletionResponse, MessageResponse, PlotResponse
6
+ from app.schema.conversation import ConversationResponse
7
  from app.service.chat_service import ChatService
8
  from app.security.auth_service import AuthService
9
+ from app.core.api_response import api_response
10
+
11
 
12
  router = APIRouter(prefix="/v1", tags=["chat"])
13
  service = ChatService()
14
  auth_service = AuthService()
15
 
16
+ ################
17
+ # chat completion api list
18
+ ################
19
  # create a chat completion
20
+ @api_response()
21
+ @router.post("/chat/completions", response_model=ChatCompletionResponse)
22
+ async def create_chat_completion(req: ChatCompletionRequest, username: str = Depends(auth_service.verify_credentials)):
23
  """
24
  Chat completion API - Given a list of messages comprising a conversation, the model will return a response.
25
  If completion_id is not provided, start a new chat completion by providing a list of messages.
 
33
 
34
 
35
  # get all chat completions
36
+ @router.get("/chat/completions", response_model=List[ChatCompletionResponse])
37
+ async def list_chat_completions(username: str = Depends(auth_service.verify_credentials)):
38
  """
39
  Get all chat completions
40
  Summary: First load the chat interface(UI) for list of chat completions on the left side.
 
53
 
54
 
55
  # get a chat completion by id
56
+ @router.get("/chat/completions/{completion_id}", response_model=ChatCompletionResponse)
57
+ async def retrieve_chat_completion(completion_id: str, username: str = Depends(auth_service.verify_credentials)):
58
  """
59
  Get a chat completion by id
60
  Summary: Click on a chat completion on the left side to load the chat completion on the right side.
 
66
 
67
 
68
  # get all messages for a chat completion
69
+ @router.get("/chat/completions/{completion_id}/messages", response_model=List[MessageResponse])
70
+ async def list_messages(completion_id: str, username: str = Depends(auth_service.verify_credentials)):
71
  """
72
  Get all messages for a chat completion
73
  Summary: Click on a chat completion on the left side to load the chat completion on the right side.
 
78
  raise HTTPException(status_code=500, detail=str(e))
79
 
80
 
81
+ ################
82
+ # plot api list
83
+ ################
84
  # get a plot for a message
85
+ @router.get("/chat/completions/{completion_id}/messages/{message_id}/plot", response_model=PlotResponse)
86
+ async def retrieve_plot(completion_id: str, message_id: str, username: str = Depends(auth_service.verify_credentials)):
87
  """
88
  Get a plot figure for a message to visualize the data
89
  Summary: Click on a message on the right side to load the plot on the right side.
 
94
  raise HTTPException(status_code=500, detail=str(e))
95
 
96
 
97
+ ################
98
+ # conversation api list
99
+ ################
100
+ # GET https://chatgpt.com/backend-api/conversations
101
+ # GET https://chatgpt.com/backend-api/conversations/{completion_id}
102
 
103
 
104
+ # get all conversations
105
+ @api_response()
106
+ @router.get("/conversations", response_model=List[ConversationResponse])
107
+ async def list_conversations(username: str = Depends(auth_service.verify_credentials)):
108
+ """
109
+ Get all conversations
110
+ """
111
+ try:
112
+ return await service.find_all_conversations(username)
113
+ except Exception as e:
114
+ raise HTTPException(status_code=500, detail=str(e))
115
 
116
+ # get a conversation by id
117
+ @router.get("/conversations/{completion_id}", response_model=ConversationResponse)
118
+ async def retrieve_conversation(completion_id: str, username: str = Depends(auth_service.verify_credentials)):
119
+ """
120
+ Get a conversation by id
121
+ """
122
+ try:
123
+ return await service.find_conversation_by_id(completion_id)
124
+ except Exception as e:
125
+ raise HTTPException(status_code=500, detail=str(e))
app/core/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ """
2
+ Core module for the application.
3
+ """
app/model/chat_model.py CHANGED
@@ -37,7 +37,11 @@ from typing import List
37
  # },
38
  # {
39
  # "role": "assistant",
40
- # "content": "**Between Cities**: Take a high-speed train (Italo or Trenitalia) from Rome to Florence. Book in advance for tickets around €25-35 one-way (1.5 hours). Trains depart from Roma Termini and arrive at Firenze Santa Maria Novella. Check schedules on trenitalia.com or italo.it.\n\n**Within Florence**: Florence is compact and walkable, so you won’t need much public transport. For longer distances (e.g., to Piazzale Michelangelo), use ATAF buses (~€1.50 per ride, buy tickets at tabaccherie). Alternatively, rent a bike (~€10/day) for a scenic way to explore. Taxis are pricier (~€10-15 for short trips), so stick to walking or buses for budget travel."
 
 
 
 
41
  # }
42
  # ],
43
  # "temperature": 0.8,
 
37
  # },
38
  # {
39
  # "role": "assistant",
40
+ # "content": "**Between Cities**: Take a high-speed train (Italo or Trenitalia) from Rome to Florence. Book in advance for tickets around €25-35 one-way (1.5 hours). Trains depart from Roma Termini and arrive at Firenze Santa Maria Novella. Check schedules on trenitalia.com or italo.it.\n\n**Within Florence**: Florence is compact and walkable, so you won’t need much public transport. For longer distances (e.g., to Piazzale Michelangelo), use ATAF buses (~€1.50 per ride, buy tickets at tabaccherie). Alternatively, rent a bike (~€10/day) for a scenic way to explore. Taxis are pricier (~€10-15 for short trips), so stick to walking or buses for budget travel.",
41
+ # "plot": {
42
+ # "data": {},
43
+ # "layout": {}
44
+ # }
45
  # }
46
  # ],
47
  # "temperature": 0.8,
app/repository/chat_repository.py CHANGED
@@ -20,6 +20,9 @@ class ChatRepository:
20
  completion_id = str(result.upserted_id) if result.upserted_id else entity.completion_id
21
  entity.completion_id = completion_id
22
 
 
 
 
23
  return entity
24
 
25
  def find(self, query: dict, page: int = 1, limit: int = 10, sort: dict = None, project: dict = None) -> List[ChatCompletion]:
 
20
  completion_id = str(result.upserted_id) if result.upserted_id else entity.completion_id
21
  entity.completion_id = completion_id
22
 
23
+ # save conversation if new chat completion
24
+ # TODO: save conversation
25
+
26
  return entity
27
 
28
  def find(self, query: dict, page: int = 1, limit: int = 10, sort: dict = None, project: dict = None) -> List[ChatCompletion]:
app/service/chat_service.py CHANGED
@@ -5,6 +5,9 @@ from app.schema.chat_schema import ChatCompletionRequest, ChatCompletionResponse
5
  from app.model.chat_model import ChatCompletion, ChatMessage
6
  import uuid
7
 
 
 
 
8
  class ChatService:
9
  def __init__(self):
10
  self.chat_repository = ChatRepository()
@@ -44,4 +47,9 @@ class ChatService:
44
  async def find_messages(self, completion_id: str) -> List[ChatMessage]:
45
  return self.chat_repository.find_messages(completion_id)
46
 
47
-
 
 
 
 
 
 
5
  from app.model.chat_model import ChatCompletion, ChatMessage
6
  import uuid
7
 
8
+ from app.schema.conversation import ConversationResponse
9
+
10
+
11
  class ChatService:
12
  def __init__(self):
13
  self.chat_repository = ChatRepository()
 
47
  async def find_messages(self, completion_id: str) -> List[ChatMessage]:
48
  return self.chat_repository.find_messages(completion_id)
49
 
50
+ # conversation service
51
+ async def find_all_conversations(self, username: str) -> List[ConversationResponse]:
52
+ raise NotImplementedError("Not implemented")
53
+
54
+ async def find_conversation_by_id(self, completion_id: str) -> ConversationResponse:
55
+ raise NotImplementedError("Not implemented")