adeebjamal commited on
Commit
030d3a9
·
1 Parent(s): 548c803

feat: add rename and delete conversation APIs

Browse files
Files changed (5) hide show
  1. database.py +41 -0
  2. main.py +38 -1
  3. models/schemas.py +7 -0
  4. query_constants.py +6 -0
  5. requests.txt +36 -0
database.py CHANGED
@@ -177,3 +177,44 @@ def get_messages_paginated(conv_id: int, start_row: int, end_row: int):
177
  finally:
178
  if conn:
179
  conn.close()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  finally:
178
  if conn:
179
  conn.close()
180
+
181
+ def rename_conversation(conv_id: int, new_name: str):
182
+ """Update a conversation's title."""
183
+ conn = None
184
+ try:
185
+ conn = get_db_connection()
186
+ cursor = conn.cursor()
187
+ cursor.execute(query_constants.RENAME_CONVERSATION, (new_name, conv_id))
188
+ updated = cursor.fetchone()
189
+ conn.commit()
190
+ return dict(updated) if updated else None
191
+ except Exception as e:
192
+ logger.error(f"Error renaming conversation: {e}")
193
+ if conn:
194
+ conn.rollback()
195
+ raise
196
+ finally:
197
+ if conn:
198
+ conn.close()
199
+
200
+ def delete_conversation(conv_id: int):
201
+ """Delete a conversation and all its messages."""
202
+ conn = None
203
+ try:
204
+ conn = get_db_connection()
205
+ cursor = conn.cursor()
206
+ # Delete messages first (also handled by CASCADE, but explicit is safer)
207
+ cursor.execute(query_constants.DELETE_MESSAGES_BY_CONVERSATION, (conv_id,))
208
+ # Delete the conversation itself
209
+ cursor.execute(query_constants.DELETE_CONVERSATION, (conv_id,))
210
+ deleted = cursor.fetchone()
211
+ conn.commit()
212
+ return dict(deleted) if deleted else None
213
+ except Exception as e:
214
+ logger.error(f"Error deleting conversation: {e}")
215
+ if conn:
216
+ conn.rollback()
217
+ raise
218
+ finally:
219
+ if conn:
220
+ conn.close()
main.py CHANGED
@@ -9,7 +9,7 @@ from fastapi import FastAPI, HTTPException
9
  from fastapi.middleware.cors import CORSMiddleware
10
 
11
  from fastapi.responses import StreamingResponse
12
- from models.schemas import CreateConversationRequest, LoadMessagesRequest, AskQuestionRequest
13
  import database
14
  import model
15
  import time
@@ -184,6 +184,43 @@ async def ask_question(req: AskQuestionRequest):
184
  logger.error(f"Error processing question: {e}")
185
  raise HTTPException(status_code=500, detail="Internal server error")
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  @app.get("/health")
188
  async def health_check():
189
  """Health check endpoint."""
 
9
  from fastapi.middleware.cors import CORSMiddleware
10
 
11
  from fastapi.responses import StreamingResponse
12
+ from models.schemas import CreateConversationRequest, LoadMessagesRequest, AskQuestionRequest, RenameConversationRequest, DeleteConversationRequest
13
  import database
14
  import model
15
  import time
 
184
  logger.error(f"Error processing question: {e}")
185
  raise HTTPException(status_code=500, detail="Internal server error")
186
 
187
+ @app.put("/conversations/rename")
188
+ async def rename_conversation(req: RenameConversationRequest):
189
+ """Renames an existing conversation."""
190
+ if not req.new_name or not req.new_name.strip():
191
+ raise HTTPException(status_code=400, detail="new_name must not be empty")
192
+
193
+ try:
194
+ conv = database.get_conversation(req.conversation_id)
195
+ if not conv:
196
+ raise HTTPException(status_code=404, detail="conversation_id not found")
197
+
198
+ updated = database.rename_conversation(req.conversation_id, req.new_name.strip())
199
+ if updated and 'created_at' in updated and updated['created_at']:
200
+ updated['created_at'] = updated['created_at'].isoformat()
201
+ return updated
202
+ except HTTPException:
203
+ raise
204
+ except Exception as e:
205
+ logger.error(f"Error renaming conversation: {e}")
206
+ raise HTTPException(status_code=500, detail="Internal server error")
207
+
208
+ @app.delete("/conversations/delete")
209
+ async def delete_conversation(req: DeleteConversationRequest):
210
+ """Deletes a conversation and all its messages."""
211
+ try:
212
+ conv = database.get_conversation(req.conversation_id)
213
+ if not conv:
214
+ raise HTTPException(status_code=404, detail="conversation_id not found")
215
+
216
+ deleted = database.delete_conversation(req.conversation_id)
217
+ return {"message": "Conversation deleted successfully", "deleted_id": deleted["id"]}
218
+ except HTTPException:
219
+ raise
220
+ except Exception as e:
221
+ logger.error(f"Error deleting conversation: {e}")
222
+ raise HTTPException(status_code=500, detail="Internal server error")
223
+
224
  @app.get("/health")
225
  async def health_check():
226
  """Health check endpoint."""
models/schemas.py CHANGED
@@ -12,3 +12,10 @@ class AskQuestionRequest(BaseModel):
12
  conversation_id: int
13
  query: str
14
  max_tokens: int = 500
 
 
 
 
 
 
 
 
12
  conversation_id: int
13
  query: str
14
  max_tokens: int = 500
15
+
16
+ class RenameConversationRequest(BaseModel):
17
+ conversation_id: int
18
+ new_name: str
19
+
20
+ class DeleteConversationRequest(BaseModel):
21
+ conversation_id: int
query_constants.py CHANGED
@@ -51,3 +51,9 @@ GET_PAGINATED_MESSAGES = """
51
  ORDER BY created_at ASC
52
  OFFSET %s LIMIT %s;
53
  """
 
 
 
 
 
 
 
51
  ORDER BY created_at ASC
52
  OFFSET %s LIMIT %s;
53
  """
54
+
55
+ RENAME_CONVERSATION = "UPDATE conversations SET title = %s WHERE id = %s RETURNING id, title, created_at;"
56
+
57
+ DELETE_MESSAGES_BY_CONVERSATION = "DELETE FROM messages WHERE conversation_id = %s;"
58
+
59
+ DELETE_CONVERSATION = "DELETE FROM conversations WHERE id = %s RETURNING id;"
requests.txt CHANGED
@@ -102,3 +102,39 @@ curl --location 'https://adeebjamal-private-ai-backend.hf.space/conversations/me
102
  # }
103
  # ]
104
  # }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  # }
103
  # ]
104
  # }
105
+
106
+
107
+ # -----------------------------------------------------------------------------
108
+
109
+ # 6. Rename a Conversation
110
+ # Updates the title of an existing conversation.
111
+ curl --location --request PUT 'https://adeebjamal-private-ai-backend.hf.space/conversations/rename' \
112
+ --header 'Content-Type: application/json' \
113
+ --data '{
114
+ "conversation_id": <REPLACE_WITH_CONVERSATION_ID>,
115
+ "new_name": "<REPLACE_WITH_NEW_NAME>"
116
+ }'
117
+
118
+ # Example Response:
119
+ # {
120
+ # "id": 2,
121
+ # "title": "Updated Chat Title",
122
+ # "created_at": "2026-04-21T17:09:16.741250"
123
+ # }
124
+
125
+
126
+ # -----------------------------------------------------------------------------
127
+
128
+ # 7. Delete a Conversation
129
+ # Deletes a conversation and all its associated messages permanently.
130
+ curl --location --request DELETE 'https://adeebjamal-private-ai-backend.hf.space/conversations/delete' \
131
+ --header 'Content-Type: application/json' \
132
+ --data '{
133
+ "conversation_id": <REPLACE_WITH_CONVERSATION_ID>
134
+ }'
135
+
136
+ # Example Response:
137
+ # {
138
+ # "message": "Conversation deleted successfully",
139
+ # "deleted_id": 2
140
+ # }