Spaces:
Sleeping
Sleeping
File size: 10,246 Bytes
ae60efb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
import gradio as gr
import requests
import json
import logging
import os
from dotenv import load_dotenv
from typing import Dict, List, Tuple
# Load environment variables
load_dotenv()
# Configure logging
logging.basicConfig(
filename='gradio_frontend.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# API Configuration
API_BASE_URL=os.getenv("API_BASE_URL")
async def process_query(message: str, language: str, mode: str, chat_history: List[Dict]) -> Tuple[str, str]:
"""Make API request to get chatbot response"""
try:
payload = {
"message": message,
"language": language,
"mode": mode
}
response = requests.post(
f"{API_BASE_URL}/api/query",
json=payload
)
response.raise_for_status()
result = response.json()
return result["answer"], result.get("id")
except requests.RequestException as e:
logging.error(f"API request failed: {str(e)}")
return f"Sorry, there was an error processing your request: {str(e)}", None
async def submit_feedback(feedback_type: str, full_chat_history: List[Dict], language_choice: str, mode: str) -> str:
"""Submit feedback via API"""
try:
if mode == "Private":
return "Feedback is disabled in private mode."
if not full_chat_history or len(full_chat_history) < 2:
return "No recent interaction to provide feedback for."
# Get the last assistant message with an ID
assistant_messages = [msg for msg in full_chat_history
if msg.get("role") == "assistant" and "id" in msg]
if not assistant_messages:
logging.error("No assistant messages with ID found in chat history")
return "No response found to provide feedback for."
last_message = assistant_messages[-1]
question_id = last_message.get("id")
if not question_id:
logging.error(f"No ID found in last message: {last_message}")
return "Question ID not found. Please try asking another question."
logging.info(f"Submitting feedback for question ID: {question_id}")
# Submit feedback
payload = {
"question_id": question_id,
"feedback_type": feedback_type,
"language": language_choice,
"mode": mode
}
response = requests.post(
f"{API_BASE_URL}/api/feedback",
json=payload
)
response.raise_for_status()
return "Thanks for your feedback! Your response has been recorded."
except requests.RequestException as e:
logging.error(f"Failed to submit feedback: {str(e)}")
return f"Sorry, there was an error submitting your feedback: {str(e)}"
except Exception as e:
logging.error(f"Unexpected error in submit_feedback: {str(e)}")
return "An unexpected error occurred. Please try again."
# Create Gradio interface
with gr.Blocks(title="RRA FAQ Chatbot") as demo:
full_chat_history = gr.State([]) # Add this line
gr.Markdown(
"""
# RRA FAQ Chatbot
Ask tax-related questions in English or Kinyarwanda
"""
)
# Add mode selector
with gr.Row():
interaction_mode = gr.Radio(
choices=["Normal", "Private"],
value="Normal",
label="Interaction Mode",
info="Normal: Stores interactions to improve service | Private: No data storage"
)
with gr.Row():
gr.Markdown(
"""
> π **Data Storage Notice:**
> - Normal Mode: Questions and interactions are stored to improve our service
> - Private Mode: No data is stored, feedback feature is disabled
"""
)
# Add language selector
language = gr.Radio(
choices=["English", "Kinyarwanda"],
value="English",
label="Select Language / Hitamo Ururimi"
)
chatbot = gr.Chatbot(
value=[],
show_label=False,
height=400
)
with gr.Row():
msg = gr.Textbox(
label="Ask your question",
placeholder="Type your tax-related question here...",
show_label=False
)
submit = gr.Button("Send")
# Add feedback section
feedback_container = gr.Row(visible=True)
with feedback_container:
with gr.Column(scale=2):
feedback_label = gr.Markdown("Was this response helpful?")
with gr.Column(scale=1):
feedback_positive = gr.Button("π Helpful")
with gr.Column(scale=1):
feedback_negative = gr.Button("π Not Helpful")
# Add feedback status message
feedback_status = gr.Markdown("")
async def respond(message, lang, mode, chat_history, full_chat_history):
"""Process a user message and update chat history"""
try:
if chat_history is None:
chat_history = []
if full_chat_history is None:
full_chat_history = []
# Get response from API
bot_message, question_id = await process_query(message, lang, mode, chat_history)
if not bot_message:
return "", chat_history, full_chat_history
# Build new messages
user_message = {
"content": message,
"role": "user"
}
assistant_message = {
"content": bot_message,
"role": "assistant",
"id": question_id # Store ID in the message
}
# Append to full chat history
new_full_history = full_chat_history + [user_message, assistant_message]
# Prepare messages for chatbot display
new_chat_history = chat_history + [[message, bot_message]]
return "", new_chat_history, new_full_history
except Exception as e:
logging.error(f"Error in respond function: {e}")
return "", chat_history, full_chat_history
def update_mode(mode: str):
"""Update UI when mode changes"""
is_private = (mode == "Private")
return {
feedback_container: gr.update(visible=not is_private),
feedback_status: gr.update(value="" if not is_private else "Feedback is disabled in private mode")
}
# Connect feedback buttons
async def submit_positive_feedback(full_chat_history, language_choice, mode):
return await submit_feedback("positive", full_chat_history, language_choice, mode)
async def submit_negative_feedback(full_chat_history, language_choice, mode):
return await submit_feedback("negative", full_chat_history, language_choice, mode)
feedback_positive.click(
fn=submit_positive_feedback,
inputs=[full_chat_history, language, interaction_mode],
outputs=feedback_status
)
feedback_negative.click(
fn=submit_negative_feedback,
inputs=[full_chat_history, language, interaction_mode],
outputs=feedback_status
)
# Update UI when mode changes
interaction_mode.change(
fn=update_mode,
inputs=[interaction_mode],
outputs=[feedback_container, feedback_status]
)
# Example questions
with gr.Row() as english_examples_row:
gr.Examples(
examples=[
"What is VAT in Rwanda?",
"How do I register for taxes?",
"What are the tax payment deadlines?",
"How can I get a TIN number?",
"How do I get purchase code?"
],
inputs=msg,
label="English Examples"
)
with gr.Row(visible=False) as kinyarwanda_examples_row:
gr.Examples(
examples=[
"Ese VAT ni iki mu Rwanda?",
"Nabona TIN number nte?",
"Ni ryari tugomba kwishyura imisoro?",
"Ese nandikwa nte ku musoro?",
"Ni gute nabone kode yo kugura?"
],
inputs=msg,
label="Kinyarwanda Examples"
)
def toggle_language_interface(language_choice):
if language_choice == "English":
placeholder_text = "Type your tax-related question here..."
return {
msg: gr.update(placeholder=placeholder_text),
english_examples_row: gr.update(visible=True),
kinyarwanda_examples_row: gr.update(visible=False)
}
else:
placeholder_text = "Andika ibibazo bijyanye n'umusoro hano"
return {
msg: gr.update(placeholder=placeholder_text),
english_examples_row: gr.update(visible=False),
kinyarwanda_examples_row: gr.update(visible=True)
}
# Connect user inputs
msg.submit(
respond,
[msg, language, interaction_mode, chatbot, full_chat_history],
[msg, chatbot, full_chat_history]
)
submit.click(
respond,
[msg, language, interaction_mode, chatbot, full_chat_history],
[msg, chatbot, full_chat_history]
)
# Update interface on language change
language.change(
fn=toggle_language_interface,
inputs=language,
outputs=[msg, english_examples_row, kinyarwanda_examples_row]
)
gr.Markdown(
"""
### About
- Created by: [Cedric](mailto:[email protected])
- Data source: [RRA Website FAQ](https://www.rra.gov.rw/en/domestic-tax-services/faqs)
**Disclaimer:** This chatbot provides general tax information. For official guidance,
consult RRA or call 3004.
"""
)
if __name__ == "__main__":
try:
demo.launch(share=False)
logging.info("Gradio app launched successfully.")
except Exception as launch_error:
logging.critical(f"Failed to launch Gradio app: {launch_error}")
raise
|