-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
137 lines (111 loc) Β· 5.91 KB
/
app.py
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
from flask import Flask, request, jsonify, render_template
import google.genai as genai
from google.genai import types
import os
import json
from dotenv import load_dotenv
from flask_cors import CORS
# Load API key from .env file
load_dotenv()
GENAI_API_KEY = os.getenv("GEMINI_API_KEY")
# Initialize Gemini API Client
client = genai.Client(api_key=GENAI_API_KEY)
app = Flask(__name__)
# Enable Cross-Origin Resource Sharing (CORS) to allow requests from any domain
CORS(app, resources={r"/*": {"origins": "*"}})
# Load hospital data from JSON file
def load_nrh_data():
"""Load hospital information from a JSON file."""
try:
with open("nrh_data.json", "r") as file:
return json.load(file)
except Exception as e:
print(f"Error loading JSON file: {e}")
return {}
nrh_data = load_nrh_data()
# Function to retrieve relevant hospital information based on user query
def fetch_hospital_info(user_query):
"""Extracts relevant hospital information based on user input."""
response = []
query_lower = user_query.lower()
# General Services Query
if "service" in query_lower:
all_services = {service for dept in nrh_data.get("departments", {}).values() for service in dept.get("services", [])}
if all_services:
response.append(f"We offer a range of medical services including: {', '.join(all_services)}.")
# Department-Specific Queries
for department, details in nrh_data.get("departments", {}).items():
if department.lower() in query_lower:
response.append(f"Department of {department.capitalize()}: {details.get('description', 'No description available')}.")
response.append(f"Services offered: {', '.join(details.get('services', ['No services listed']))}.")
# General Hospital Information Queries
if "phone" in query_lower or "contact" in query_lower:
contacts = nrh_data.get("hospital_info", {}).get("contact", {})
response.append(f"π General Contact: {contacts.get('general', 'Not available')}")
response.append(f"π Emergency: {contacts.get('emergency', 'Not available')}")
response.append(f"π Ambulance: {contacts.get('ambulance', 'Not available')}")
if "location" in query_lower:
response.append(f"π Hospital Location: {nrh_data.get('hospital_info', {}).get('location', 'Not available')}")
if "values" in query_lower or "mission" in query_lower:
response.append(f"π₯ Core Values: {', '.join(nrh_data.get('hospital_info', {}).get('values', ['Not available']))}")
if "insurance" in query_lower or "NHIF" in query_lower:
response.append(f"β
Accepted Insurance: {', '.join(nrh_data.get('insurance_partners', ['Not available']))}")
if "payment" in query_lower:
response.append(f"π³ Payment Methods: {', '.join(nrh_data.get('payment_methods', ['Not available']))}")
if "facility" in query_lower or "facilities" in query_lower:
facilities = nrh_data.get("facilities", {})
response.append(f"π Beds: {facilities.get('beds', 'Not available')}")
response.append(f"π Ambulances: {facilities.get('ambulances', 'Not available')}")
response.append(f"π Pharmacy: {facilities.get('pharmacy', 'Not available')}")
response.append(f"π‘ Radiology: {', '.join(facilities.get('radiology', []))}")
if "visiting" in query_lower or "visiting hours" in query_lower:
visiting = nrh_data.get("visiting_hours", {})
response.append(f"β° Visiting Hours: Morning - {visiting.get('morning', 'Not available')}, Evening - {visiting.get('evening', 'Not available')}.")
response.append(f"π Rules: {', '.join(visiting.get('rules', []))}")
return "\n".join(response) if response else "I'm sorry, I couldn't find that information."
# Function to generate AI chatbot prompt
def hospital_assistant_prompt(user_input):
"""Constructs a structured prompt for the AI chatbot."""
hospital_info = fetch_hospital_info(user_input)
return (
"You are a virtual assistant for Nakuru Referral Hospital. "
"Keep responses clear, concise, and helpful. "
"Avoid formatting responses. no markdown, no asterisks. "
"Do not provide contact details unless explicitly asked.\n\n"
f"Hospital Data: {hospital_info}\n"
f"User: {user_input}\n"
"Assistant:"
)
@app.route("/")
def index():
"""Render the index page (frontend interface)."""
return render_template("index.html")
@app.route("/chat", methods=["POST"])
def chat():
"""Handles user chat requests and returns AI-generated responses."""
data = request.json
user_input = data.get("message")
if not user_input:
return jsonify({"error": "Message is required"}), 400
try:
# AI Response Generation Configuration
response = client.models.generate_content(
model="gemini-2.0-flash", # Select the model to use
contents=[hospital_assistant_prompt(user_input)], # Pass user input as part of the prompt
config=types.GenerateContentConfig(
temperature=0.5, # Controls randomness: lower = more deterministic, higher = more creative
top_k=30, # Limits choices per step to top-k likely words
top_p=0.9, # Nucleus sampling: selects from top-p probability words
max_output_tokens=150, # Restricts response length to 150 tokens
frequency_penalty=0.3, # Discourages repetition of frequently used phrases
presence_penalty=0.1 # Encourages AI to introduce new words
)
)
# Extract AI-generated response
reply = response.text if response.text else "I'm sorry, I couldn't understand that."
return jsonify({"response": reply})
except Exception as e:
print(f"ERROR: {str(e)}")
return jsonify({"error": f"An internal error occurred: {str(e)}"}), 500
if __name__ == "__main__":
app.run(debug=True)