davidtran999 commited on
Commit
f5ba315
·
verified ·
1 Parent(s): 7d7792c

Upload backend/chatbot/views.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. backend/chatbot/views.py +261 -0
backend/chatbot/views.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Chatbot API views for handling conversational queries.
3
+ """
4
+ import json
5
+ import logging
6
+ import uuid
7
+ from typing import Any, Dict
8
+
9
+ from django.http import HttpRequest, JsonResponse
10
+ from django.views.decorators.csrf import csrf_exempt
11
+ from rest_framework import status
12
+ from rest_framework.decorators import api_view
13
+ from rest_framework.request import Request
14
+ from rest_framework.response import Response
15
+
16
+ from .chatbot import get_chatbot
17
+ from hue_portal.chatbot.context_manager import ConversationContext
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ @csrf_exempt
23
+ def chat_simple(request: HttpRequest) -> JsonResponse:
24
+ """
25
+ Lightweight POST-only endpoint to help Spaces hit the chatbot without DRF.
26
+ """
27
+ if request.method != "POST":
28
+ return JsonResponse({"error": "Method not allowed"}, status=405)
29
+
30
+ try:
31
+ payload: Dict[str, Any] = json.loads(request.body.decode("utf-8"))
32
+ except json.JSONDecodeError as exc:
33
+ return JsonResponse(
34
+ {"error": "Invalid JSON body", "details": str(exc)},
35
+ status=400,
36
+ )
37
+
38
+ message: str = str(payload.get("message", "")).strip()
39
+ session_id_raw = payload.get("session_id") or ""
40
+ session_id: str = str(session_id_raw).strip() if session_id_raw else ""
41
+ reset_session: bool = bool(payload.get("reset_session", False))
42
+
43
+ if not message:
44
+ return JsonResponse({"error": "message is required"}, status=400)
45
+
46
+ if reset_session:
47
+ session_id = ""
48
+
49
+ if not session_id:
50
+ session_id = str(uuid.uuid4())
51
+ else:
52
+ try:
53
+ uuid.UUID(session_id)
54
+ except ValueError:
55
+ session_id = str(uuid.uuid4())
56
+
57
+ try:
58
+ chatbot = get_chatbot()
59
+ response = chatbot.generate_response(message, session_id=session_id)
60
+ except Exception as exc:
61
+ return JsonResponse(
62
+ {
63
+ "message": "Xin lỗi, có lỗi xảy ra. Vui lòng thử lại.",
64
+ "intent": "error",
65
+ "error": str(exc),
66
+ "results": [],
67
+ "count": 0,
68
+ "session_id": session_id,
69
+ },
70
+ status=500,
71
+ )
72
+
73
+ if "session_id" not in response:
74
+ response["session_id"] = session_id
75
+
76
+ return JsonResponse(response, status=200)
77
+
78
+
79
+ @api_view(["POST"])
80
+ def chat(request: Request) -> Response:
81
+ """
82
+ Chatbot endpoint for natural language queries with session support.
83
+
84
+ Request body:
85
+ {
86
+ "message": "Mức phạt vượt đèn đỏ là bao nhiêu?",
87
+ "session_id": "optional-uuid-string",
88
+ "reset_session": false
89
+ }
90
+
91
+ Response:
92
+ {
93
+ "message": "Tôi tìm thấy 1 mức phạt liên quan đến '...':",
94
+ "intent": "search_fine",
95
+ "confidence": 0.95,
96
+ "results": [...],
97
+ "count": 1,
98
+ "session_id": "uuid-string"
99
+ }
100
+ """
101
+ # Log raw request data for debugging
102
+ raw_data = dict(request.data) if hasattr(request.data, 'get') else {}
103
+ logger.info(f"[CHAT] 📥 Raw request data keys: {list(raw_data.keys())}, Content-Type: {request.content_type}")
104
+ print(f"[CHAT] 📥 Raw request data keys: {list(raw_data.keys())}, Content-Type: {request.content_type}", flush=True)
105
+
106
+ message = request.data.get("message", "").strip()
107
+ session_id = request.data.get("session_id") or ""
108
+ if session_id:
109
+ session_id = str(session_id).strip()
110
+ else:
111
+ session_id = ""
112
+ reset_session = request.data.get("reset_session", False)
113
+
114
+ # Log received message for debugging
115
+ message_preview = message[:100] + "..." if len(message) > 100 else message
116
+ logger.info(f"[CHAT] 📨 Received POST request - Message: '{message_preview}' (length: {len(message)}), Session: {session_id[:8] if session_id else 'new'}")
117
+ print(f"[CHAT] 📨 Received POST request - Message: '{message_preview}' (length: {len(message)}), Session: {session_id[:8] if session_id else 'new'}", flush=True)
118
+
119
+ if not message:
120
+ return Response(
121
+ {"error": "message is required"},
122
+ status=status.HTTP_400_BAD_REQUEST
123
+ )
124
+
125
+ # Handle session reset
126
+ if reset_session:
127
+ session_id = None
128
+
129
+ # Generate new session_id if not provided
130
+ if not session_id:
131
+ session_id = str(uuid.uuid4())
132
+ else:
133
+ # Validate session_id format
134
+ try:
135
+ uuid.UUID(session_id)
136
+ except ValueError:
137
+ # Invalid UUID format, generate new one
138
+ session_id = str(uuid.uuid4())
139
+
140
+ try:
141
+ logger.info(f"[CHAT] ⏳ Starting response generation for message (length: {len(message)})")
142
+ print(f"[CHAT] ⏳ Starting response generation for message (length: {len(message)})", flush=True)
143
+
144
+ chatbot = get_chatbot()
145
+ response = chatbot.generate_response(message, session_id=session_id)
146
+
147
+ # Ensure session_id is in response
148
+ if "session_id" not in response:
149
+ response["session_id"] = session_id
150
+
151
+ response_preview = response.get("message", "")[:100] + "..." if len(response.get("message", "")) > 100 else response.get("message", "")
152
+ logger.info(f"[CHAT] ✅ Response generated successfully - Intent: {response.get('intent', 'unknown')}, Response length: {len(response.get('message', ''))}")
153
+ print(f"[CHAT] ✅ Response generated successfully - Intent: {response.get('intent', 'unknown')}, Response preview: '{response_preview}'", flush=True)
154
+
155
+ return Response(response, status=status.HTTP_200_OK)
156
+ except Exception as e:
157
+ return Response(
158
+ {
159
+ "message": "Xin lỗi, có lỗi xảy ra. Vui lòng thử lại.",
160
+ "intent": "error",
161
+ "error": str(e),
162
+ "results": [],
163
+ "count": 0,
164
+ "session_id": session_id
165
+ },
166
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR
167
+ )
168
+
169
+
170
+ @api_view(["GET"])
171
+ def health(request):
172
+ """
173
+ Health check endpoint for chatbot service.
174
+ """
175
+ try:
176
+ chatbot = get_chatbot()
177
+ return Response({
178
+ "status": "healthy",
179
+ "service": "chatbot",
180
+ "classifier_loaded": chatbot.intent_classifier is not None
181
+ })
182
+ except Exception as e:
183
+ return Response(
184
+ {"status": "unhealthy", "error": str(e)},
185
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR
186
+ )
187
+
188
+
189
+ @api_view(["GET"])
190
+ def test_init(request: Request) -> Response:
191
+ """
192
+ Force chatbot initialization to validate startup on Hugging Face Spaces.
193
+ """
194
+ try:
195
+ chatbot = get_chatbot()
196
+ return Response(
197
+ {
198
+ "status": "initialized",
199
+ "classifier_loaded": chatbot.intent_classifier is not None,
200
+ },
201
+ status=status.HTTP_200_OK,
202
+ )
203
+ except Exception as exc:
204
+ return Response(
205
+ {"status": "error", "message": str(exc)},
206
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR,
207
+ )
208
+
209
+
210
+ @api_view(["POST"])
211
+ def test_generate(request: Request) -> Response:
212
+ """
213
+ Generate a quick response for smoke-testing LLM connectivity.
214
+ """
215
+ message = request.data.get("message", "").strip()
216
+ if not message:
217
+ return Response(
218
+ {"error": "message is required"},
219
+ status=status.HTTP_400_BAD_REQUEST,
220
+ )
221
+
222
+ session_id = str(request.data.get("session_id") or uuid.uuid4())
223
+
224
+ try:
225
+ chatbot = get_chatbot()
226
+ response = chatbot.generate_response(message, session_id=session_id)
227
+ response.setdefault("session_id", session_id)
228
+ return Response(response, status=status.HTTP_200_OK)
229
+ except Exception as exc:
230
+ return Response(
231
+ {
232
+ "message": "Xin lỗi, có lỗi xảy ra. Vui lòng thử lại.",
233
+ "intent": "error",
234
+ "error": str(exc),
235
+ "results": [],
236
+ "count": 0,
237
+ "session_id": session_id,
238
+ },
239
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR,
240
+ )
241
+
242
+
243
+ @api_view(["GET"])
244
+ def model_status(request: Request) -> Response:
245
+ """
246
+ Provide lightweight diagnostics about the current chatbot instance.
247
+ """
248
+ try:
249
+ chatbot = get_chatbot()
250
+ status_payload = {
251
+ "intent_classifier_loaded": chatbot.intent_classifier is not None,
252
+ "knowledge_base_ready": getattr(chatbot, "knowledge_base", None) is not None,
253
+ "llm_provider": getattr(chatbot, "llm_provider", "unknown"),
254
+ }
255
+ return Response(status_payload, status=status.HTTP_200_OK)
256
+ except Exception as exc:
257
+ return Response(
258
+ {"status": "error", "message": str(exc)},
259
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR,
260
+ )
261
+