-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
384 lines (318 loc) · 21.5 KB
/
Copy pathapp.py
File metadata and controls
384 lines (318 loc) · 21.5 KB
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
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
import os
from pathlib import Path
import streamlit as st
import pandas as pd
import PyPDF2
import matplotlib.pyplot as plt
import plotly.express as px
import google.generativeai as genai
from io import StringIO
# --- Page Configuration (Always at the top) ---
st.set_page_config(
page_title="AI Governance Analytics & LLM Interface",
page_icon="🤖",
layout="wide"
)
# --- Helpers ---
def load_env_file(env_path: Path) -> None:
if not env_path.exists():
return
for line in env_path.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'"))
def list_available_models() -> list[str]:
try:
return [m.name for m in genai.list_models()]
except Exception:
return []
# --- Configure Google Gemini API Key securely ---
load_env_file(Path(".env"))
try:
gemini_api_key = st.secrets["GOOGLE_API_KEY"]
genai.configure(api_key=gemini_api_key)
model_name = os.getenv("GEMINI_MODEL", "gemini-flash-latest")
gemini_model = genai.GenerativeModel(model_name)
except KeyError:
gemini_api_key = os.getenv("GOOGLE_API_KEY")
if not gemini_api_key:
st.error("Google API Key not found. Add `GOOGLE_API_KEY` to .streamlit/secrets.toml or .env.")
st.stop()
genai.configure(api_key=gemini_api_key)
model_name = os.getenv("GEMINI_MODEL", "gemini-flash-latest")
gemini_model = genai.GenerativeModel(model_name)
except Exception as e:
st.error(f"Could not initialize Gemini API. Error: {e}")
st.stop()
# --- Sidebar Options ---
st.sidebar.title("Navigation")
app_mode = st.sidebar.radio("Choose Functionality:", [
"📄 Document Summarizer",
"📊 Data Visualizer",
"🤖 AI Chat Assistant",
"🌐 Governance Dashboard"
])
with st.sidebar.expander("Model diagnostics"):
st.caption("If Gemini returns a 404, list models for your API key.")
if st.button("List available Gemini models"):
models = list_available_models()
if models:
st.write(models)
else:
st.warning("No models returned. Check API key or network.")
st.title("AI Governance Analytics & LLM Interface")
st.markdown("---") # Horizontal line for visual separation
# --- Dummy Data for Summarizer (for quick demo) ---
sample_policy_text = """
## AI Governance Framework: Principles and Practices
This document outlines the foundational principles and practical guidelines for the responsible development, deployment, and oversight of Artificial Intelligence (AI) systems within our organization. Our commitment to ethical AI is rooted in enhancing human well-being, fostering trust, and ensuring accountability across all AI initiatives.
**1. Fairness and Non-discrimination:**
AI systems must be designed and deployed to minimize bias and promote equitable outcomes. This includes rigorous testing for disparate impact across various demographic groups and continuous monitoring of model performance to detect and mitigate bias. Data used for training must be diverse and representative, and data collection practices must be ethical.
**2. Transparency and Explainability:**
The decision-making processes of AI systems should be understandable to stakeholders. We strive for sufficient transparency regarding the data, algorithms, and models used, appropriate to the context and potential impact of the AI. Where possible, explainable AI (XAI) techniques will be employed to provide insights into how AI reaches its conclusions.
**3. Accountability and Human Oversight:**
Clear lines of responsibility must be established for the development, deployment, and operation of AI systems. Humans must retain ultimate control and oversight, especially in high-stakes decisions. Mechanisms for appeal, redress, and human intervention will be integrated into AI-driven processes.
**4. Privacy and Security:**
Robust data privacy and security measures are paramount. AI systems will adhere to all relevant data protection regulations (e.g., GDPR, CCPA). Data minimization principles will be applied, and strong encryption and access controls will protect sensitive information. Regular security audits will be conducted.
**5. Robustness and Safety:**
AI systems must be resilient to errors, manipulation, and unexpected inputs. They should be designed to operate reliably and safely, even in unforeseen circumstances. Continuous testing, validation, and monitoring are essential to ensure the stability and integrity of AI models.
**6. Societal and Environmental Impact:**
We commit to assessing and mitigating the broader societal and environmental impacts of our AI systems. This includes considering implications for employment, social equity, and energy consumption. AI should be developed to contribute positively to society.
**Implementation Guidelines:**
* **Risk Assessment:** Conduct thorough AI risk assessments at each stage of the lifecycle.
* **Ethical Review Boards:** Establish multi-disciplinary ethical review boards for high-impact AI projects.
* **Training and Education:** Provide ongoing training for employees on AI ethics and responsible practices.
* **Monitoring and Auditing:** Implement continuous monitoring and regular independent audits of AI systems.
* **Stakeholder Engagement:** Engage with internal and external stakeholders to gather feedback and address concerns.
This framework is a living document and will be periodically reviewed and updated to reflect advancements in AI technology and evolving societal norms.
"""
# --- Dummy Data for Data Visualizer (for quick demo) ---
dummy_df = pd.DataFrame({
'Year': [2020, 2021, 2022, 2023, 2024],
'Compliance Score': [75, 80, 82, 85, 88],
'Bias Detections': [12, 15, 10, 8, 5],
'Domain': ['Healthcare', 'Finance', 'Education', 'Retail', 'Healthcare'],
'Risk Level': ['Medium', 'High', 'Medium', 'Low', 'Medium']
})
# --- Summarizer Logic ---
if app_mode == "📄 Document Summarizer":
st.header("Upload & Summarize PDF")
st.info("Upload a PDF document to get an AI-generated summary using Google Gemini. Alternatively, use the sample policy text below for quick testing. "
"For real-world examples, explore reports from institutions like the BIS or RBI linked in the sidebar.")
st.sidebar.markdown("---")
st.sidebar.subheader("External Resources for Summarizer:")
st.sidebar.markdown("- **AI Governance Documents Data (Kaggle):** [https://www.kaggle.com/datasets/umerhaddii/ai-governance-documents-data](https://www.kaggle.com/datasets/umerhaddii/ai-governance-documents-data)")
st.sidebar.markdown("- **Awesome AI Regulation (GitHub):** [https://github.com/ethicalml/awesome-artificial-intelligence-regulation](https://github.com/ethicalml/awesome-artificial-intelligence-regulation) (Find links to official PDF reports here)")
st.sidebar.markdown("- **IFC Report on AI in Central Banks (BIS):** [https://www.bis.org/ifc/publ/ifc_report_18.pdf](https://www.bis.org/ifc/publ/ifc_report_18.pdf)")
st.sidebar.markdown("- **RBI's FREE-AI Framework (IndiaAI Portal):** [https://indiaai.gov.in/article/rbi-s-framework-for-responsible-and-ethical-enablement-towards-ethical-ai-in-finance](https://indiaai.gov.in/article/rbi-s-framework-for-responsible-and-ethical-enablement-towards-ethical-ai-in-finance)")
st.sidebar.markdown("---")
uploaded_pdf = st.file_uploader("Upload PDF Document", type=["pdf"])
selected_text = ""
if uploaded_pdf:
try:
reader = PyPDF2.PdfReader(uploaded_pdf)
for page in reader.pages:
selected_text += page.extract_text()
if not selected_text.strip():
st.warning("Could not extract text from the uploaded PDF. It might be an image-based PDF or encrypted. Please try the sample text.")
selected_text = ""
else:
st.subheader("Extracted Text Preview (from PDF)")
st.write(selected_text[:1000] + ("..." if len(selected_text) > 1000 else ""))
except PyPDF2.errors.PdfReadError:
st.error("Invalid PDF file. Please upload a valid, unencrypted PDF.")
selected_text = ""
except Exception as e:
st.error(f"An unexpected error occurred during PDF processing: {e}")
selected_text = ""
use_sample = st.checkbox("Use Sample AI Governance Policy Text for summarization", value=not bool(uploaded_pdf))
if use_sample and not uploaded_pdf:
selected_text = sample_policy_text
st.subheader("Sample Text Preview (AI Governance Policy)")
st.write(selected_text[:1000] + ("..." if len(selected_text) > 1000 else ""))
if selected_text.strip():
if st.button("Generate Summary"):
with st.spinner("Summarizing your document with Gemini... This may take a moment."):
try:
response = gemini_model.generate_content(
f"Summarize this policy document concisely, focusing on key takeaways and main points:\n\n{selected_text}"
)
summary = response.text
st.subheader("Summary")
st.success("Summary generated successfully!")
st.write(summary)
except Exception as e:
st.error(f"Failed to generate summary with Gemini AI. Error: {e}")
st.warning("This could be due to text length, rate limits, or an issue with the Gemini API. Please try again or with a shorter document.")
elif uploaded_pdf and not selected_text.strip():
st.info("Please upload a PDF from which text can be extracted, or check 'Use Sample Policy Text'.")
elif not uploaded_pdf and not use_sample:
st.info("Upload a PDF or check 'Use Sample Policy Text' to begin summarization.")
# --- CSV Upload & Visualization ---
elif app_mode == "📊 Data Visualizer":
st.header("Data Upload and Visuals")
st.info("Upload a CSV file and build multiple charts (bar, line, scatter, histogram, pie, box). A sample dataset is available for quick testing.")
st.sidebar.markdown("---")
st.sidebar.subheader("External Resources for Data Visualizer:")
st.sidebar.markdown("- **AI in Mitigating Cybersecurity Risks in Government (Kaggle):** [https://www.kaggle.com/datasets/salman1541983/ai-in-mitigating-cybersecurity-risks-in-government/data](https://www.kaggle.com/datasets/salman1541983/ai-in-mitigating-cybersecurity-risks-in-government/data)")
st.sidebar.markdown("- **AI-Enhanced Cybersecurity Events Dataset (Kaggle):** [https://www.kaggle.com/datasets/hassaneskikri/ai-enhanced-cybersecurity-events-dataset](https://www.kaggle.com/datasets/hassaneskikri/ai-enhanced-cybersecurity-events-dataset)")
st.sidebar.markdown("---")
uploaded_file = st.file_uploader("Upload CSV file", type=["csv"])
df = None
use_dummy_data = st.checkbox("Use Sample Governance Data", value=not bool(uploaded_file))
if uploaded_file is not None:
try:
df = pd.read_csv(uploaded_file)
st.info("Using uploaded CSV data.")
except Exception as e:
st.error(f"Error reading CSV file: {e}. Please ensure it's a valid CSV.")
df = None
if df is None and use_dummy_data:
df = dummy_df
st.info("Using sample governance data for visualization.")
if df is not None:
st.subheader("Data Preview:")
st.dataframe(df.head())
if not df.empty:
numeric_columns = df.select_dtypes(include=['number']).columns.tolist()
categorical_columns = df.select_dtypes(include=['object', 'category', 'bool']).columns.tolist()
if numeric_columns:
st.subheader("Chart Builder")
chart_types = st.multiselect(
"Select chart types to create",
["Bar", "Line", "Scatter", "Histogram", "Pie", "Box"],
default=["Bar", "Histogram"]
)
if not chart_types:
st.info("Select at least one chart type to display.")
for chart in chart_types:
with st.expander(f"{chart} chart options", expanded=False):
if chart == "Bar":
x_col = st.selectbox("X (category)", categorical_columns or df.columns.tolist(), key="bar_x")
y_col = st.selectbox("Y (numeric)", numeric_columns, key="bar_y")
agg = st.selectbox("Aggregation", ["sum", "mean", "count"], key="bar_agg")
if agg == "count":
bar_df = df.groupby(x_col).size().reset_index(name="count")
fig = px.bar(bar_df, x=x_col, y="count", title=f"Count by {x_col}")
else:
bar_df = df.groupby(x_col)[y_col].agg(agg).reset_index()
fig = px.bar(bar_df, x=x_col, y=y_col, title=f"{agg.title()} of {y_col} by {x_col}")
st.plotly_chart(fig, use_container_width=True)
elif chart == "Line":
x_col = st.selectbox("X", df.columns.tolist(), key="line_x")
y_col = st.selectbox("Y (numeric)", numeric_columns, key="line_y")
fig = px.line(df, x=x_col, y=y_col, title=f"{y_col} over {x_col}")
st.plotly_chart(fig, use_container_width=True)
elif chart == "Scatter":
x_col = st.selectbox("X (numeric)", numeric_columns, key="scatter_x")
y_col = st.selectbox("Y (numeric)", numeric_columns, key="scatter_y")
color_col = st.selectbox("Color (optional)", ["None"] + df.columns.tolist(), key="scatter_color")
fig = px.scatter(
df,
x=x_col,
y=y_col,
color=None if color_col == "None" else color_col,
title=f"{y_col} vs {x_col}"
)
st.plotly_chart(fig, use_container_width=True)
elif chart == "Histogram":
col = st.selectbox("Numeric column", numeric_columns, key="hist_col")
bins = st.slider("Bins", min_value=5, max_value=50, value=20, key="hist_bins")
fig = px.histogram(df, x=col, nbins=bins, title=f"Distribution of {col}")
st.plotly_chart(fig, use_container_width=True)
elif chart == "Pie":
names_col = st.selectbox("Category", categorical_columns or df.columns.tolist(), key="pie_names")
value_col = st.selectbox("Values (numeric)", ["Count"] + numeric_columns, key="pie_values")
if value_col == "Count":
pie_df = df[names_col].value_counts().reset_index()
pie_df.columns = [names_col, "count"]
fig = px.pie(pie_df, names=names_col, values="count", title=f"Count by {names_col}")
else:
pie_df = df.groupby(names_col)[value_col].sum().reset_index()
fig = px.pie(pie_df, names=names_col, values=value_col, title=f"{value_col} by {names_col}")
st.plotly_chart(fig, use_container_width=True)
elif chart == "Box":
y_col = st.selectbox("Y (numeric)", numeric_columns, key="box_y")
x_col = st.selectbox("X (optional category)", ["None"] + categorical_columns, key="box_x")
fig = px.box(
df,
x=None if x_col == "None" else x_col,
y=y_col,
title=f"Box plot of {y_col}"
)
st.plotly_chart(fig, use_container_width=True)
else:
st.warning("No numeric columns found in the uploaded CSV (or sample data) for plotting.")
else:
st.warning("The uploaded CSV file (or sample data) is empty.")
else:
st.info("Upload a CSV file or check 'Use Sample Governance Data' to view visualizations.")
# --- AI Chat Assistant (LLM-Based Query) ---
elif app_mode == "🤖 AI Chat Assistant":
st.header("AI-Powered Chat on Governance Reports")
st.info("Ask general questions about AI governance, policies, or ethical considerations to Google Gemini.")
st.sidebar.markdown("---")
st.sidebar.subheader("Relevant AI Governance Reports & Articles:")
st.sidebar.markdown("- **Global Finance Magazine (AI in Banks):** [https://gfmag.com/banking/financial-institutions-double-down-on-ai-but-will-it-deliver/](https://gfmag.com/banking/financial-institutions-double-down-on-ai-but-will-it-deliver/)")
st.sidebar.markdown("- **Moody's (BIS report on AI in Central Banks):** [https://www.moodys.com/web/en/us/insights/regulatory-news/bis-report-discusses-ai-governance-at-central-banks.html](https://www.moodys.com/web/en/us/insights/regulatory-news/bis-report-discusses-ai-governance-at-central-banks.html)")
st.sidebar.markdown("---")
if "gemini_messages" not in st.session_state:
st.session_state.gemini_messages = []
st.session_state.gemini_messages.append({"role": "model", "parts": ["Hello! How can I help you with AI governance today?"]})
for message in st.session_state.gemini_messages:
with st.chat_message("user" if message["role"] == "user" else "assistant"):
st.markdown(" ".join(message["parts"]))
prompt = st.chat_input("Your query:")
if prompt:
st.session_state.gemini_messages.append({"role": "user", "parts": [prompt]})
with st.chat_message("user"):
st.markdown(prompt)
with st.spinner("Generating response with Gemini..."):
try:
response = gemini_model.generate_content(
st.session_state.gemini_messages
)
answer = response.text
st.session_state.gemini_messages.append({"role": "model", "parts": [answer]})
with st.chat_message("assistant"):
st.markdown(answer)
except Exception as e:
st.error(f"Failed to get response from Gemini AI. Error: {e}")
st.warning("This could be due to conversation context length, rate limits, or an issue with the Gemini API. Please try again.")
# --- AI Governance Dashboard View ---
elif app_mode == "🌐 Governance Dashboard":
st.header("Simulated Dashboard: AI Deployment & Governance Trends")
st.info("This dashboard displays simulated trends related to AI adoption and governance challenges across various domains. The data is pre-populated for demonstration and inspiration.")
st.sidebar.markdown("---")
st.sidebar.subheader("Dashboard Inspiration & Data Sources:")
st.sidebar.markdown("- **Multivariate Dataset on IoT and AI (Kaggle):** [https://www.kaggle.com/datasets/ziya07/multivariate-dataset-on-iot-and-ai](https://www.kaggle.com/datasets/ziya07/multivariate-dataset-on-iot-and-ai) (Contains AI adoption scores)")
st.sidebar.markdown("- Consider reports from **WEF, OECD, UNESCO, Partnership on AI** for real-world metrics and trends.")
st.sidebar.markdown("---")
years = list(range(2018, 2025))
ai_adoption = [15, 25, 35, 45, 55, 65, 72] # Percentage of AI adoption
bias_incidents = [1, 2, 4, 7, 9, 11, 12] # Number of reported incidents
dashboard_df = pd.DataFrame({
'Year': years,
'AI Deployment Rate (%)': ai_adoption,
'Reported Bias Incidents': bias_incidents
}).set_index('Year')
st.subheader("AI Adoption vs. Governance Challenges (2018–2024)")
st.line_chart(dashboard_df[['AI Deployment Rate (%)', 'Reported Bias Incidents']])
fig, ax1 = plt.subplots(figsize=(10, 6))
ax1.bar(years, ai_adoption, color='skyblue', label="AI Deployment Rate (%)", width=0.4, align='center')
ax1.set_xlabel("Year")
ax1.set_ylabel("AI Deployment Rate (%)", color='skyblue')
ax1.tick_params(axis='y', labelcolor='skyblue')
ax2 = ax1.twinx()
ax2.plot(years, bias_incidents, color='red', marker='o', linestyle='-', label="Reported Incidents")
ax2.set_ylabel("Reported Incidents", color='red')
ax2.tick_params(axis='y', labelcolor='red')
fig.suptitle("AI Adoption vs. Governance Challenges (2018–2024)")
lines, labels = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc="upper left", bbox_to_anchor=(0.1, 0.9))
st.pyplot(fig)
plt.close(fig)
st.caption("Note: This data is simulated and represents hypothetical trends in AI deployment and associated privacy/bias issues across an unspecified sector. Refer to external links for real-world datasets.")