Kiruthikaramalingam commited on
Commit
66ce833
·
verified ·
1 Parent(s): 7d02e86

Update routes/chatbot_routes.py

Browse files
Files changed (1) hide show
  1. routes/chatbot_routes.py +200 -196
routes/chatbot_routes.py CHANGED
@@ -1,196 +1,200 @@
1
- from flask import Blueprint, request, jsonify
2
- import openai
3
- import os
4
- from dotenv import load_dotenv
5
- from utils.quiz_utils import quiz_questions
6
- from utils.openai_utils import query_dynamic_generation, format_code_block
7
- from response import predefined_responses
8
-
9
- # Load environment variables
10
- load_dotenv()
11
-
12
- # Initialize OpenAI API
13
- openai_api_key = os.getenv("OPENAI_API_KEY")
14
- if not openai_api_key:
15
- raise ValueError("OPENAI_API_KEY environment variable is not set!")
16
-
17
- openai.api_key = openai_api_key
18
-
19
- # Define a Blueprint for chatbot routes
20
- chatbot_routes = Blueprint("test_hugging_face", __name__)
21
-
22
- # Maintain a history for context-aware responses
23
- history = [
24
- {"role": "system", "content": "You are a Python programming tutor and assistant."}
25
- ]
26
-
27
- quiz_state = {} # Initialize quiz state
28
-
29
-
30
-
31
- def add_to_history(role, content):
32
- history.append({"role": role, "content": content})
33
- if len(history) > 5: # Limit to the last 5 exchanges
34
- history.pop(1)
35
-
36
-
37
- @chatbot_routes.route("/get_response", methods=["POST"])
38
- def get_response():
39
- user_input = request.json.get("user_input", "").strip()
40
-
41
- if not user_input:
42
- return jsonify({"reply": "Please provide a valid input."})
43
-
44
- # Normalize user input
45
- user_input_normalized = user_input.lower()
46
-
47
- # Check if the input explicitly asks for an explanation or dynamic query
48
- if "explain" in user_input_normalized or "describe" or "what" in user_input_normalized:
49
- try:
50
- # Handle dynamic query generation for explanations
51
- add_to_history("user", user_input)
52
- chatbot_reply = query_dynamic_generation(user_input)
53
- add_to_history("assistant", chatbot_reply)
54
- chatbot_reply = format_code_block(chatbot_reply)
55
- return jsonify({"reply": chatbot_reply})
56
- except Exception as e:
57
- return jsonify({"reply": f"Error: {str(e)}"})
58
-
59
- # Check predefined responses for exact match (if no explanation keyword is found)
60
- if user_input_normalized in predefined_responses:
61
- chatbot_reply = predefined_responses[user_input_normalized]
62
- chatbot_reply = format_code_block(chatbot_reply)
63
- return jsonify({"reply": chatbot_reply})
64
-
65
- # Extract keywords for predefined responses
66
- keyword = extract_keywords(user_input_normalized)
67
-
68
- if keyword and keyword in predefined_responses:
69
- chatbot_reply = predefined_responses[keyword]
70
- chatbot_reply = format_code_block(chatbot_reply)
71
- return jsonify({"reply": chatbot_reply})
72
-
73
- # Fallback to dynamic query generation if no match is found
74
- try:
75
- add_to_history("user", user_input)
76
- chatbot_reply = query_dynamic_generation(user_input)
77
- add_to_history("assistant", chatbot_reply)
78
- chatbot_reply = format_code_block(chatbot_reply)
79
- return jsonify({"reply": chatbot_reply})
80
- except Exception as e:
81
- return jsonify({"reply": f"Error: {str(e)}"})
82
-
83
-
84
-
85
- @chatbot_routes.route("/clear_history", methods=["POST"])
86
- def clear_history():
87
- """
88
- Clears the conversation history and resets quiz state.
89
- """
90
- global history
91
- history = [
92
- {"role": "system", "content": "You are a Python programming tutor and assistant."}
93
- ]
94
- quiz_state.clear() # Clear quiz state if any
95
- return jsonify({"reply": "Chat history cleared!"})
96
-
97
-
98
- # Route: Start Quiz
99
- @chatbot_routes.route("/start_quiz", methods=["POST"])
100
- def start_quiz():
101
- """
102
- Initializes or resets the quiz for the user based on the selected difficulty level.
103
- """
104
- user_id = request.json.get("user_id", "default")
105
- level = request.json.get("level", "beginner") # Default to beginner level
106
-
107
- # Reset quiz state if level changes or new quiz is started
108
- if user_id not in quiz_state or quiz_state[user_id].get("level") != level:
109
- quiz_state[user_id] = {
110
- "current": 0,
111
- "level": level,
112
- "questions": quiz_questions.get(level, [])
113
- }
114
-
115
- state = quiz_state[user_id]
116
-
117
- # Check if there are more questions available
118
- if state["current"] < len(state["questions"]):
119
- current_question = state["questions"][state["current"]]
120
- return jsonify({"question": current_question["question"], "options": current_question["options"]})
121
- return jsonify({"reply": "Quiz finished! Great job!"})
122
-
123
-
124
- # Route: Submit Answer
125
- @chatbot_routes.route("/submit_answer", methods=["POST"])
126
- def submit_answer():
127
- """
128
- Handles the user's answer and returns the next question or completion message.
129
- """
130
- user_id = request.json.get("user_id", "default")
131
- answer = request.json.get("answer", "").strip()
132
- state = quiz_state.get(user_id, {})
133
-
134
- if not state:
135
- return jsonify({"reply": "No active quiz found. Start a quiz first."})
136
-
137
- current_index = state.get("current", 0)
138
- questions = state.get("questions", [])
139
-
140
- if current_index >= len(questions):
141
- return jsonify({"reply": "You have completed the quiz! Great job!"})
142
-
143
- correct_answer = questions[current_index]["answer"].strip()
144
-
145
- state["current"] += 1 # Move to the next question
146
-
147
- if answer.lower() == correct_answer.lower():
148
- if state["current"] < len(questions):
149
- next_question = questions[state["current"]]
150
- return jsonify({
151
- "reply": f"Correct! Here's your next question: ",
152
- "next_question": next_question["question"],
153
- "options": next_question["options"]
154
- })
155
- else:
156
- return jsonify({"reply": "Correct! You have completed the quiz! Great job!"})
157
- else:
158
- if state["current"] < len(questions):
159
- next_question = questions[state["current"]]
160
- return jsonify({
161
- "reply": f"Incorrect! The correct answer was: {correct_answer}.",
162
- "next_question": next_question["question"],
163
- "options": next_question["options"]
164
- })
165
- else:
166
- return jsonify({"reply": f"Incorrect! The correct answer was: {correct_answer}. You have completed the quiz!"})
167
-
168
-
169
- @chatbot_routes.route("/debug_quiz_state", methods=["GET"])
170
- def debug_quiz_state():
171
- return jsonify(quiz_state)
172
-
173
-
174
- def normalize_answer(answer):
175
- """
176
- Normalize the answer for case-insensitive and whitespace-insensitive matching.
177
- """
178
- import re
179
- # Remove extra spaces and make case-insensitive
180
- return re.sub(r"\s+", " ", answer.strip().lower())
181
-
182
-
183
- def extract_keywords(user_input):
184
- """
185
- Extract keywords from user input to match predefined responses.
186
- """
187
- user_input_normalized = user_input.lower().strip()
188
- keywords = ["product", "fibonacci", "count characters", "add", "factorial", "if-else", "if else", "bubble sort example", "indentation error example", "path", "quiz"]
189
- for keyword in keywords:
190
- if keyword in user_input_normalized:
191
- return keyword
192
- return None
193
-
194
-
195
-
196
-
 
 
 
 
 
1
+ from flask import Blueprint, request, jsonify
2
+ import openai
3
+ import os
4
+ from dotenv import load_dotenv
5
+ from utils.quiz_utils import quiz_questions
6
+ from utils.openai_utils import query_dynamic_generation, format_code_block
7
+ from response import predefined_responses
8
+
9
+ # Load environment variables
10
+ load_dotenv()
11
+
12
+ # Initialize OpenAI API
13
+ openai_api_key = os.getenv("OPENAI_API_KEY")
14
+ if not openai_api_key:
15
+ raise ValueError("OPENAI_API_KEY environment variable is not set!")
16
+
17
+ openai.api_key = openai_api_key
18
+
19
+ # Define a Blueprint for chatbot routes
20
+ chatbot_routes = Blueprint("test_hugging_face", __name__)
21
+
22
+ # Maintain a history for context-aware responses
23
+ history = [
24
+ {"role": "system", "content": "You are a Python programming tutor and assistant."}
25
+ ]
26
+
27
+ quiz_state = {} # Initialize quiz state
28
+
29
+
30
+
31
+ def add_to_history(role, content):
32
+ history.append({"role": role, "content": content})
33
+ if len(history) > 5: # Limit to the last 5 exchanges
34
+ history.pop(1)
35
+
36
+
37
+ @chatbot_routes.route("/get_response", methods=["POST"])
38
+ def get_response():
39
+ user_input = request.json.get("user_input", "").strip()
40
+
41
+ if not user_input:
42
+ return jsonify({"reply": "Please provide a valid input."})
43
+
44
+ # Normalize user input
45
+ user_input_normalized = user_input.lower()
46
+
47
+ # Check if the input explicitly asks for an explanation or dynamic query
48
+ if "explain" in user_input_normalized or "describe" or "what" in user_input_normalized:
49
+ try:
50
+ # Handle dynamic query generation for explanations
51
+ add_to_history("user", user_input)
52
+ chatbot_reply = query_dynamic_generation(user_input)
53
+ add_to_history("assistant", chatbot_reply)
54
+ chatbot_reply = format_code_block(chatbot_reply)
55
+ return jsonify({"reply": chatbot_reply})
56
+ except Exception as e:
57
+ return jsonify({"reply": f"Error: {str(e)}"})
58
+
59
+ # Check predefined responses for exact match (if no explanation keyword is found)
60
+ if user_input_normalized in predefined_responses:
61
+ chatbot_reply = predefined_responses[user_input_normalized]
62
+ chatbot_reply = format_code_block(chatbot_reply)
63
+ return jsonify({"reply": chatbot_reply})
64
+
65
+ # Extract keywords for predefined responses
66
+ keyword = extract_keywords(user_input_normalized)
67
+
68
+ if keyword and keyword in predefined_responses:
69
+ chatbot_reply = predefined_responses[keyword]
70
+ chatbot_reply = format_code_block(chatbot_reply)
71
+ return jsonify({"reply": chatbot_reply})
72
+
73
+ # Fallback to dynamic query generation if no match is found
74
+ try:
75
+ add_to_history("user", user_input)
76
+ chatbot_reply = query_dynamic_generation(user_input)
77
+ add_to_history("assistant", chatbot_reply)
78
+ chatbot_reply = format_code_block(chatbot_reply)
79
+ return jsonify({"reply": chatbot_reply})
80
+ except Exception as e:
81
+ return jsonify({"reply": f"Error: {str(e)}"})
82
+
83
+
84
+
85
+ @chatbot_routes.route("/clear_history", methods=["POST"])
86
+ def clear_history():
87
+ """
88
+ Clears the conversation history and resets quiz state.
89
+ """
90
+ global history
91
+ history = [
92
+ {"role": "system", "content": "You are a Python programming tutor and assistant."}
93
+ ]
94
+ quiz_state.clear() # Clear quiz state if any
95
+ return jsonify({"reply": "Chat history cleared!"})
96
+
97
+
98
+ # Route: Start Quiz
99
+ @chatbot_routes.route("/start_quiz", methods=["POST"])
100
+ def start_quiz():
101
+ """
102
+ Initializes or resets the quiz for the user based on the selected difficulty level.
103
+ """
104
+ user_id = request.json.get("user_id", "default")
105
+ level = request.json.get("level", "beginner") # Default to beginner level
106
+
107
+ # Reset quiz state if level changes or new quiz is started
108
+ if user_id not in quiz_state or quiz_state[user_id].get("level") != level:
109
+ quiz_state[user_id] = {
110
+ "current": 0,
111
+ "level": level,
112
+ "questions": quiz_questions.get(level, []),
113
+ "score": 0 # Reset score when starting a new quiz
114
+ }
115
+
116
+ state = quiz_state[user_id]
117
+
118
+ # Check if there are more questions available
119
+ if state["current"] < len(state["questions"]):
120
+ current_question = state["questions"][state["current"]]
121
+ return jsonify({"question": current_question["question"], "options": current_question["options"]})
122
+ return jsonify({"reply": "Quiz finished! Great job!"})
123
+
124
+
125
+ # Route: Submit Answer
126
+ @chatbot_routes.route("/submit_answer", methods=["POST"])
127
+ def submit_answer():
128
+ """
129
+ Handles the user's answer, adjusts the score, and returns the next question or completion message.
130
+ """
131
+ user_id = request.json.get("user_id", "default")
132
+ answer = request.json.get("answer", "").strip()
133
+ state = quiz_state.get(user_id, {})
134
+
135
+ if not state:
136
+ return jsonify({"reply": "No active quiz found. Start a quiz first."})
137
+
138
+ current_index = state.get("current", 0)
139
+ questions = state.get("questions", [])
140
+
141
+ if current_index >= len(questions):
142
+ return jsonify({"reply": f"Quiz completed! Final Score: {state.get('score', 0)}. Great job!"})
143
+
144
+ correct_answer = questions[current_index]["answer"].strip()
145
+
146
+ # Adjust the score based on the user's answer
147
+ if answer.lower() == correct_answer.lower():
148
+ state["score"] += 10 # Add 10 points for a correct answer
149
+ feedback = f"Correct! +10 points. Your current score: {state['score']}."
150
+ else:
151
+ state["score"] -= 5 # Deduct 5 points for an incorrect answer
152
+ feedback = f"Incorrect! The correct answer was: {correct_answer}. -5 points. Your current score: {state['score']}."
153
+
154
+ # Move to the next question
155
+ state["current"] += 1
156
+
157
+ # Check if there are more questions available
158
+ if state["current"] < len(questions):
159
+ next_question = questions[state["current"]]
160
+ return jsonify({
161
+ "reply": feedback,
162
+ "next_question": next_question["question"],
163
+ "options": next_question["options"],
164
+ "score": state["score"]
165
+ })
166
+ else:
167
+ return jsonify({
168
+ "reply": f"{feedback} Quiz completed! Final Score: {state['score']}. Great job!",
169
+ "score": state["score"]
170
+ })
171
+
172
+
173
+ @chatbot_routes.route("/debug_quiz_state", methods=["GET"])
174
+ def debug_quiz_state():
175
+ return jsonify(quiz_state)
176
+
177
+
178
+ def normalize_answer(answer):
179
+ """
180
+ Normalize the answer for case-insensitive and whitespace-insensitive matching.
181
+ """
182
+ import re
183
+ # Remove extra spaces and make case-insensitive
184
+ return re.sub(r"\s+", " ", answer.strip().lower())
185
+
186
+
187
+ def extract_keywords(user_input):
188
+ """
189
+ Extract keywords from user input to match predefined responses.
190
+ """
191
+ user_input_normalized = user_input.lower().strip()
192
+ keywords = ["product", "fibonacci", "count characters", "add", "factorial", "if-else", "if else", "bubble sort example", "indentation error example", "path", "quiz"]
193
+ for keyword in keywords:
194
+ if keyword in user_input_normalized:
195
+ return keyword
196
+ return None
197
+
198
+
199
+
200
+