rameshmoorthy commited on
Commit
3aa1d62
·
verified ·
1 Parent(s): 6fe97e2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +291 -1
app.py CHANGED
@@ -1,4 +1,294 @@
1
- # import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  # from phi.agent import Agent
3
  # from phi.model.groq import Groq
4
  # import os
 
1
+ import gradio as gr
2
+ from phi.agent import Agent
3
+ from phi.model.groq import Groq
4
+ import os
5
+ import logging
6
+ from sentence_transformers import CrossEncoder
7
+ from backend.semantic_search import table, retriever
8
+ import numpy as np
9
+ from time import perf_counter
10
+ import requests
11
+ from jinja2 import Environment, FileSystemLoader
12
+ from pathlib import Path
13
+
14
+ # Set up logging
15
+ logging.basicConfig(level=logging.INFO)
16
+ logger = logging.getLogger(__name__)
17
+
18
+ # API Key setup
19
+ api_key = os.getenv("GROQ_API_KEY")
20
+ if not api_key:
21
+ gr.Warning("GROQ_API_KEY not found. Set it in 'Repository secrets'.")
22
+ logger.error("GROQ_API_KEY not found.")
23
+ api_key = "" # Fallback to empty string, but this will fail without a key
24
+ else:
25
+ os.environ["GROQ_API_KEY"] = api_key
26
+
27
+ # Bhashini API setup
28
+ bhashini_api_key = os.getenv("API_KEY", "").strip()
29
+ bhashini_user_id = os.getenv("USER_ID", "").strip()
30
+
31
+ def bhashini_translate(text: str, from_code: str = "en", to_code: str = "hi") -> dict:
32
+ """Translates text from source language to target language using the Bhashini API."""
33
+ if not text.strip():
34
+ print('Input text is empty. Please provide valid text for translation.')
35
+ return {"status_code": 400, "message": "Input text is empty", "translated_content": None}
36
+ else:
37
+ print('Input text - ', text)
38
+ print(f'Starting translation process from {from_code} to {to_code}...')
39
+ gr.Warning(f'Translating to {to_code}...')
40
+
41
+ url = 'https://meity-auth.ulcacontrib.org/ulca/apis/v0/model/getModelsPipeline'
42
+ headers = {
43
+ "Content-Type": "application/json",
44
+ "userID": bhashini_user_id,
45
+ "ulcaApiKey": bhashini_api_key
46
+ }
47
+ for key, value in headers.items():
48
+ if not isinstance(value, str) or '\n' in value or '\r' in value:
49
+ print(f"Invalid header value for {key}: {value}")
50
+ return {"status_code": 400, "message": f"Invalid header value for {key}", "translated_content": None}
51
+
52
+ payload = {
53
+ "pipelineTasks": [{"taskType": "translation", "config": {"language": {"sourceLanguage": from_code, "targetLanguage": to_code}}}],
54
+ "pipelineRequestConfig": {"pipelineId": "64392f96daac500b55c543cd"}
55
+ }
56
+
57
+ print('Sending initial request to get the pipeline...')
58
+ response = requests.post(url, json=payload, headers=headers)
59
+
60
+ if response.status_code != 200:
61
+ print(f'Error in initial request: {response.status_code}, Response: {response.text}')
62
+ return {"status_code": response.status_code, "message": "Error in translation request", "translated_content": None}
63
+
64
+ print('Initial request successful, processing response...')
65
+ response_data = response.json()
66
+ print('Full response data:', response_data)
67
+ if "pipelineInferenceAPIEndPoint" not in response_data or "callbackUrl" not in response_data["pipelineInferenceAPIEndPoint"]:
68
+ print('Unexpected response structure:', response_data)
69
+ return {"status_code": 400, "message": "Unexpected API response structure", "translated_content": None}
70
+
71
+ service_id = response_data["pipelineResponseConfig"][0]["config"][0]["serviceId"]
72
+ callback_url = response_data["pipelineInferenceAPIEndPoint"]["callbackUrl"]
73
+
74
+ print(f'Service ID: {service_id}, Callback URL: {callback_url}')
75
+
76
+ headers2 = {
77
+ "Content-Type": "application/json",
78
+ response_data["pipelineInferenceAPIEndPoint"]["inferenceApiKey"]["name"]: response_data["pipelineInferenceAPIEndPoint"]["inferenceApiKey"]["value"]
79
+ }
80
+ compute_payload = {
81
+ "pipelineTasks": [{"taskType": "translation", "config": {"language": {"sourceLanguage": from_code, "targetLanguage": to_code}, "serviceId": service_id}}],
82
+ "inputData": {"input": [{"source": text}], "audio": [{"audioContent": None}]}
83
+ }
84
+
85
+ print(f'Sending translation request with text: "{text}"')
86
+ compute_response = requests.post(callback_url, json=compute_payload, headers=headers2)
87
+
88
+ if compute_response.status_code != 200:
89
+ print(f'Error in translation request: {compute_response.status_code}, Response: {compute_response.text}')
90
+ return {"status_code": compute_response.status_code, "message": "Error in translation", "translated_content": None}
91
+
92
+ print('Translation request successful, processing translation...')
93
+ compute_response_data = compute_response.json()
94
+ translated_content = compute_response_data["pipelineResponse"][0]["output"][0]["target"]
95
+
96
+ print(f'Translation successful. Translated content: "{translated_content}"')
97
+ return {"status_code": 200, "message": "Translation successful", "translated_content": translated_content}
98
+
99
+ # Initialize PhiData Agent
100
+ agent = Agent(
101
+ name="Science Education Assistant",
102
+ role="You are a helpful science tutor for 10th-grade students",
103
+ instructions=[
104
+ "You are an expert science teacher specializing in 10th-grade curriculum.",
105
+ "Provide clear, accurate, and age-appropriate explanations.",
106
+ "Use simple language and examples that students can understand.",
107
+ "Focus on concepts from physics, chemistry, and biology.",
108
+ "Structure responses with headings and bullet points when helpful.",
109
+ "Encourage learning and curiosity."
110
+ ],
111
+ model=Groq(id="llama3-70b-8192", api_key=api_key),
112
+ markdown=True
113
+ )
114
+
115
+ # Set up Jinja2 environment
116
+ proj_dir = Path(__file__).parent
117
+ env = Environment(loader=FileSystemLoader(proj_dir / 'templates'))
118
+ template = env.get_template('template.j2') # For document context
119
+ template_html = env.get_template('template_html.j2') # For HTML output
120
+
121
+ # Response Generation Function
122
+ def retrieve_and_generate_response(query, cross_encoder_choice, history=None):
123
+ """Generate response using semantic search and LLM"""
124
+ top_rerank = 25
125
+ top_k_rank = 20
126
+
127
+ if not query.strip():
128
+ return "Please provide a valid question.", []
129
+
130
+ try:
131
+ start_time = perf_counter()
132
+
133
+ # Encode query and search documents
134
+ query_vec = retriever.encode(query)
135
+ documents = table.search(query_vec, vector_column_name="vector").limit(top_rerank).to_list()
136
+ documents = [doc["text"] for doc in documents]
137
+
138
+ # Re-rank documents using cross-encoder
139
+ cross_encoder_model = CrossEncoder('BAAI/bge-reranker-base') if cross_encoder_choice == '(ACCURATE) BGE reranker' else CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')
140
+ query_doc_pair = [[query, doc] for doc in documents]
141
+ cross_scores = cross_encoder_model.predict(query_doc_pair)
142
+ sim_scores_argsort = list(reversed(np.argsort(cross_scores)))
143
+ documents = [documents[idx] for idx in sim_scores_argsort[:top_k_rank]]
144
+
145
+ # Create context from top documents
146
+ context = "\n\n".join(documents[:10]) if documents else ""
147
+ context = f"Context information from educational materials:\n{context}\n\n"
148
+
149
+ # Add conversation history for context
150
+ history_context = ""
151
+ if history and len(history) > 0:
152
+ for user_msg, bot_msg in history[-2:]: # Last 2 exchanges
153
+ if user_msg and bot_msg:
154
+ history_context += f"Previous Q: {user_msg}\nPrevious A: {bot_msg}\n"
155
+
156
+ # Create full prompt
157
+ full_prompt = f"{history_context}{context}Question: {query}\n\nPlease answer the question using the context provided above. If the context doesn't contain relevant information, use your general knowledge about 10th-grade science topics."
158
+
159
+ # Generate response
160
+ response = agent.run(full_prompt)
161
+ response_text = response.content if hasattr(response, 'content') else str(response)
162
+
163
+ logger.info(f"Response generation took {perf_counter() - start_time:.2f} seconds")
164
+ return response_text, documents # Return documents for template
165
+
166
+ except Exception as e:
167
+ logger.error(f"Error in response generation: {e}")
168
+ return f"Error generating response: {str(e)}", []
169
+
170
+ def simple_chat_function(message, history, cross_encoder_choice):
171
+ """Chat function with semantic search and retriever integration"""
172
+ if not message.strip():
173
+ return "", history, ""
174
+
175
+ # Generate response and get documents
176
+ response, documents = retrieve_and_generate_response(message, cross_encoder_choice, history)
177
+
178
+ # Add to history
179
+ history.append([message, response])
180
+
181
+ # Render template with documents and query
182
+ prompt_html = template_html.render(documents=documents, query=message)
183
+
184
+ return "", history, prompt_html
185
+
186
+ def translate_text(selected_language, history):
187
+ """Translate the last response in history to the selected language."""
188
+ iso_language_codes = {
189
+ "Hindi": "hi", "Gom": "gom", "Kannada": "kn", "Dogri": "doi", "Bodo": "brx", "Urdu": "ur",
190
+ "Tamil": "ta", "Kashmiri": "ks", "Assamese": "as", "Bengali": "bn", "Marathi": "mr",
191
+ "Sindhi": "sd", "Maithili": "mai", "Punjabi": "pa", "Malayalam": "ml", "Manipuri": "mni",
192
+ "Telugu": "te", "Sanskrit": "sa", "Nepali": "ne", "Santali": "sat", "Gujarati": "gu", "Odia": "or"
193
+ }
194
+
195
+ to_code = iso_language_codes[selected_language]
196
+ response_text = history[-1][1] if history and history[-1][1] else ''
197
+ print('response_text for translation', response_text)
198
+ translation = bhashini_translate(response_text, to_code=to_code)
199
+ return translation.get('translated_content', 'Translation failed.')
200
+
201
+ # Gradio Interface with layout template
202
+ with gr.Blocks(title="Science Chatbot", theme='gradio/soft') as demo:
203
+ # Header section
204
+ with gr.Row():
205
+ with gr.Column(scale=10):
206
+ gr.HTML(value="""<div style="color: #FF4500;"><h1>Welcome! I am your friend!</h1>Ask me !I will help you<h1><span style="color: #008000">I AM A CHATBOT FOR 10TH SCIENCE WITH TRANSLATION IN 22 LANGUAGES</span></h1></div>""")
207
+ gr.HTML(value=f"""<p style="font-family: sans-serif; font-size: 16px;">A free chat bot developed by K.M.RAMYASRI,TGT,GHS.SUTHUKENY using Open source LLMs for 10 std students</p>""")
208
+ gr.HTML(value=f"""<p style="font-family: Arial, sans-serif; font-size: 14px;"> Suggestions may be sent to <a href="mailto:[email protected]" style="color: #00008B; font-style: italic;">[email protected]</a>.</p>""")
209
+ with gr.Column(scale=3):
210
+ try:
211
+ gr.Image(value='logo.png', height=200, width=200)
212
+ except:
213
+ gr.HTML("<div style='height: 200px; width: 200px; background-color: #f0f0f0; display: flex; align-items: center; justify-content: center;'>Logo</div>")
214
+
215
+ # Chat and input components
216
+ chatbot = gr.Chatbot(
217
+ [],
218
+ elem_id="chatbot",
219
+ avatar_images=('https://aui.atlassian.com/aui/8.8/docs/images/avatar-person.svg',
220
+ 'https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo.svg'),
221
+ bubble_full_width=False,
222
+ show_copy_button=True,
223
+ show_share_button=True,
224
+ )
225
+
226
+ with gr.Row():
227
+ msg = gr.Textbox(
228
+ scale=3,
229
+ show_label=False,
230
+ placeholder="Enter text and press enter",
231
+ container=False,
232
+ )
233
+ submit_btn = gr.Button(value="Submit text", scale=1, variant="primary")
234
+
235
+ # Additional controls
236
+ cross_encoder = gr.Radio(
237
+ choices=['(FAST) MiniLM-L6v2', '(ACCURATE) BGE reranker'],
238
+ value='(ACCURATE) BGE reranker',
239
+ label="Embeddings Model",
240
+ info="Select the model for document ranking"
241
+ )
242
+ language_dropdown = gr.Dropdown(
243
+ choices=[
244
+ "Hindi", "Gom", "Kannada", "Dogri", "Bodo", "Urdu", "Tamil", "Kashmiri", "Assamese", "Bengali", "Marathi",
245
+ "Sindhi", "Maithili", "Punjabi", "Malayalam", "Manipuri", "Telugu", "Sanskrit", "Nepali", "Santali",
246
+ "Gujarati", "Odia"
247
+ ],
248
+ value="Hindi",
249
+ label="Select Language for Translation"
250
+ )
251
+ translated_textbox = gr.Textbox(label="Translated Response")
252
+ prompt_html = gr.HTML() # Add HTML component for the template
253
+
254
+ # Event handlers
255
+ def update_chat_and_translate(message, history, cross_encoder_choice, selected_language):
256
+ if not message.strip():
257
+ return "", history, "", ""
258
+
259
+ # Generate response and get documents
260
+ response, documents = retrieve_and_generate_response(message, cross_encoder_choice, history)
261
+ history.append([message, response])
262
+
263
+ # Translate response
264
+ translated_text = translate_text(selected_language, history)
265
+
266
+ # Render template with documents and query
267
+ prompt_html_content = template_html.render(documents=documents, query=message)
268
+
269
+ return "", history, translated_text, prompt_html_content
270
+
271
+ msg.submit(update_chat_and_translate, [msg, chatbot, cross_encoder, language_dropdown], [msg, chatbot, translated_textbox, prompt_html])
272
+ submit_btn.click(update_chat_and_translate, [msg, chatbot, cross_encoder, language_dropdown], [msg, chatbot, translated_textbox, prompt_html])
273
+
274
+ clear = gr.Button("Clear Conversation")
275
+ clear.click(lambda: ([], "", "", ""), outputs=[chatbot, msg, translated_textbox, prompt_html])
276
+
277
+ # Example questions
278
+ gr.Examples(
279
+ examples=[
280
+ 'What is the difference between metals and non-metals?',
281
+ 'What is an ionic bond?',
282
+ 'Explain asexual reproduction',
283
+ 'What is photosynthesis?',
284
+ 'Explain Newton\'s laws of motion'
285
+ ],
286
+ inputs=msg,
287
+ label="Try these example questions:"
288
+ )
289
+
290
+ if __name__ == "__main__":
291
+ demo.launch(server_name="0.0.0.0", server_port=7860)# import gradio as gr
292
  # from phi.agent import Agent
293
  # from phi.model.groq import Groq
294
  # import os