Spaces:
Build error
Build error
Download app.py from Sumayyea/GovernmentServicesAssistant: direct link, hf CLI and curl.
- Browser
- Download file 10.2 kB
-
https://huggingface.co/spaces/Sumayyea/GovernmentServicesAssistant/resolve/main/app.py
- Command line
-
hf download hf://spaces/Sumayyea/GovernmentServicesAssistant/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Sumayyea/GovernmentServicesAssistant/resolve/main/app.py
10.2 kB
| import streamlit as st | |
| import google.generativeai as genai | |
| import os | |
| # Page configuration | |
| st.set_page_config( | |
| page_title="Government Services Assistant", | |
| page_icon="🏛️", | |
| layout="centered" | |
| ) | |
| # Custom CSS for better styling | |
| st.markdown(""" | |
| <style> | |
| .main { | |
| padding: 2rem; | |
| } | |
| .stTextInput > div > div > input { | |
| font-size: 16px; | |
| } | |
| .chat-message { | |
| padding: 1rem; | |
| border-radius: 0.5rem; | |
| margin-bottom: 1rem; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .user-message { | |
| background-color: #e3f2fd; | |
| align-items: flex-end; | |
| } | |
| .assistant-message { | |
| background-color: #f5f5f5; | |
| align-items: flex-start; | |
| } | |
| .message-content { | |
| max-width: 80%; | |
| padding: 0.5rem 1rem; | |
| border-radius: 0.5rem; | |
| } | |
| .header-container { | |
| text-align: center; | |
| padding: 1rem 0 2rem 0; | |
| border-bottom: 2px solid #4CAF50; | |
| margin-bottom: 2rem; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Initialize session state | |
| if 'messages' not in st.session_state: | |
| st.session_state.messages = [] | |
| if 'chat_session' not in st.session_state: | |
| st.session_state.chat_session = None | |
| if 'api_key_configured' not in st.session_state: | |
| st.session_state.api_key_configured = False | |
| # Hardcoded responses | |
| IDENTITY_GREETING = """I am a Government Services Assistant for the KP Government. | |
| My role is to provide official information about: | |
| • Government services and procedures | |
| • Required documents for applications | |
| • Office timings and locations | |
| • General service-related guidance | |
| ⚠️ Important: I do not provide legal or medical advice. | |
| How may I assist you today?""" | |
| EMERGENCY_RESPONSE = """⚠️ For emergencies, please contact official emergency services: | |
| • Police: 15 | |
| • Rescue: 1122 | |
| • Edhi: 115 | |
| This chatbot does not handle emergency situations.""" | |
| LEGAL_DISCLAIMER = """⚖️ I cannot provide legal advice or legal interpretations. | |
| Please consult: | |
| • A qualified legal professional | |
| • The relevant government authority | |
| • Legal aid services | |
| I can only provide procedural information about government services.""" | |
| MEDICAL_DISCLAIMER = """🏥 I am not authorized to provide medical advice. | |
| Please consult a licensed medical professional or healthcare provider. | |
| I can provide information about: | |
| • How to obtain medical certificates (procedure only) | |
| • Hospital locations and timings""" | |
| POLITICAL_RESPONSE = """I focus only on government service procedures and official information. | |
| I do not provide opinions on political matters.""" | |
| def initialize_chat_session(api_key): | |
| """Initialize the Gemini chat session with pre-seeded persona""" | |
| try: | |
| genai.configure(api_key=api_key) | |
| # Create model | |
| model = genai.GenerativeModel('gemini-2.5-flash') | |
| # Pre-seeded persona history | |
| initial_history = [ | |
| { | |
| "role": "user", | |
| "parts": [{ | |
| "text": """You are a Government Services Assistant for KP Government, Pakistan. | |
| Your behavior rules: | |
| 1. Use friendly, professional, and official tone | |
| 2. Focus ONLY on Pakistan/KP government procedures | |
| 3. Provide step-by-step procedural guidance | |
| 4. Always list required documents clearly | |
| 5. Use clear, simple language (no technical jargon) | |
| 6. When giving processing times or fees, add: "Please confirm with the concerned office as these may vary by district." | |
| 7. Never interpret laws or provide legal opinions | |
| 8. Never guess - if unsure, say "Please contact the relevant government office for accurate information." | |
| 9. Be polite and respectful in all interactions | |
| You assist with services like: | |
| - Domicile certificates | |
| - CNIC procedures | |
| - Birth certificates | |
| - Complaint procedures | |
| - Office timings and locations | |
| - General procedural guidance | |
| Respond in the same language as the user (English/Urdu/Pashto).""" | |
| }] | |
| }, | |
| { | |
| "role": "model", | |
| "parts": [{ | |
| "text": "Persona confirmed. I am the Government Services Assistant for KP Government. I am ready to assist citizens with official service information and procedures." | |
| }] | |
| } | |
| ] | |
| # Start chat session with history | |
| chat_session = model.start_chat(history=initial_history) | |
| return chat_session, None | |
| except Exception as e: | |
| return None, str(e) | |
| def check_hardcoded_responses(user_input): | |
| """Check if user input matches hardcoded response patterns""" | |
| user_lower = user_input.lower() | |
| # Identity queries | |
| if user_lower in ["who are you?", "who are you", "what can you do?", "what can you do", | |
| "introduce yourself", "what is your purpose?", "what is your purpose"]: | |
| return IDENTITY_GREETING | |
| # Emergency queries | |
| if any(word in user_lower for word in ["emergency", "urgent help", "police", "ambulance", "rescue"]): | |
| return EMERGENCY_RESPONSE | |
| # Legal advice queries | |
| if any(word in user_lower for word in ["legal advice", "can i sue", "is this legal", | |
| "lawyer", "court case", "legal opinion"]): | |
| return LEGAL_DISCLAIMER | |
| # Medical advice queries | |
| if any(word in user_lower for word in ["medical advice", "health advice", "diagnosis", | |
| "medicine", "treatment", "doctor recommendation"]): | |
| return MEDICAL_DISCLAIMER | |
| # Political queries | |
| if any(word in user_lower for word in ["which party", "political opinion", "vote for", | |
| "is this policy good", "government failure"]): | |
| return POLITICAL_RESPONSE | |
| return None | |
| # Header | |
| st.markdown(""" | |
| <div class="header-container"> | |
| <h1>🏛️ Government Services Assistant</h1> | |
| <h3>KP Government, Pakistan</h3> | |
| <p>خوش آمدید • ښه راغلاست • Welcome</p> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Sidebar for API key | |
| with st.sidebar: | |
| st.header("⚙️ Configuration") | |
| # Try to get API key from environment variable first | |
| env_api_key = os.getenv("GEMINI_API_KEY") | |
| if env_api_key: | |
| api_key = env_api_key | |
| st.success("✅ API Key loaded from environment") | |
| st.session_state.api_key_configured = True | |
| else: | |
| api_key = st.text_input( | |
| "Enter your Gemini API Key", | |
| type="password", | |
| help="Get your API key from https://makersuite.google.com/app/apikey" | |
| ) | |
| if api_key: | |
| st.session_state.api_key_configured = True | |
| else: | |
| st.warning("⚠️ Please enter your Gemini API key to use the chatbot") | |
| st.markdown(""" | |
| **How to get an API key:** | |
| 1. Visit [Google AI Studio](https://makersuite.google.com/app/apikey) | |
| 2. Sign in with your Google account | |
| 3. Create a new API key | |
| 4. Copy and paste it above | |
| """) | |
| st.markdown("---") | |
| st.markdown(""" | |
| **About this Assistant:** | |
| - Provides KP Government service information | |
| - Answers queries about procedures and documents | |
| - Operates 24/7 | |
| **Note:** This is an AI assistant. For official matters, | |
| please contact the relevant government office. | |
| """) | |
| if st.button("🔄 Clear Chat History"): | |
| st.session_state.messages = [] | |
| st.session_state.chat_session = None | |
| st.rerun() | |
| # Initialize chat session if not already done and API key is configured | |
| if st.session_state.api_key_configured and st.session_state.chat_session is None: | |
| with st.spinner("Initializing chat session..."): | |
| chat_session, error = initialize_chat_session(api_key) | |
| if chat_session: | |
| st.session_state.chat_session = chat_session | |
| else: | |
| st.error(f"❌ Failed to initialize chat session: {error}") | |
| # Display chat messages | |
| for message in st.session_state.messages: | |
| role_class = "user-message" if message["role"] == "user" else "assistant-message" | |
| role_icon = "👤" if message["role"] == "user" else "🤖" | |
| st.markdown(f""" | |
| <div class="chat-message {role_class}"> | |
| <div class="message-content"> | |
| <strong>{role_icon} {"You" if message["role"] == "user" else "Assistant"}:</strong><br> | |
| {message["content"]} | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Chat input | |
| if st.session_state.api_key_configured: | |
| user_input = st.chat_input("Type your message here...") | |
| if user_input: | |
| # Add user message to history | |
| st.session_state.messages.append({"role": "user", "content": user_input}) | |
| # Check for hardcoded responses first | |
| hardcoded_response = check_hardcoded_responses(user_input) | |
| if hardcoded_response: | |
| response_text = hardcoded_response | |
| else: | |
| # Get AI response | |
| try: | |
| with st.spinner("Thinking..."): | |
| response = st.session_state.chat_session.send_message(user_input) | |
| response_text = response.text | |
| except Exception as e: | |
| response_text = f"❌ Error: {str(e)}\n\nPossible reasons:\n• Rate limit exceeded\n• Network connection issue\n• Invalid API configuration" | |
| # Add assistant response to history | |
| st.session_state.messages.append({"role": "assistant", "content": response_text}) | |
| # Rerun to display new messages | |
| st.rerun() | |
| else: | |
| st.info("👈 Please configure your API key in the sidebar to start chatting") | |
| # Footer | |
| st.markdown("---") | |
| st.markdown(""" | |
| <div style="text-align: center; color: #666; padding: 1rem;"> | |
| <p>Developed for KP Government Training 2026 • AI-based Chatbots Workshop</p> | |
| <p style="font-size: 0.9em;">Trainer: Engr. Sumayyea Salahuddin</p> | |
| </div> | |
| """, unsafe_allow_html=True) |