ComplianceApp / app.py
eaglelandsonce's picture
Update app.py
4f43ed0 verified
# https://chatgpt.com/c/692f03df-88e8-8326-9e22-230b32dd2194
import gradio as gr
# -----------------------------
# Compliance configuration
# -----------------------------
compliance_areas = {
"Data Privacy": {
"description": "Ensure protection of personal user data (GDPR, HIPAA).",
"checks": ["User data is anonymized", "Consent collected"],
},
"Explainability": {
"description": "Ensure outputs are interpretable to humans (EU AI Act, IEEE guidelines).",
"checks": ["Model outputs are interpretable", "Feature importance is logged"],
},
"Auditability": {
"description": "Ensure chatbot decisions can be traced (NIST AI RMF).",
"checks": ["All conversations are stored securely", "Logs include timestamps and user IDs"],
},
"Fairness": {
"description": "Ensure equal treatment and inclusive language (AI Fairness 360, IBM).",
"checks": ["Bias metrics are checked monthly", "Language models use inclusive vocabulary"],
},
}
def build_compliance_instructions() -> str:
"""
Build a textual description of the compliance areas to include in the prompt.
"""
lines = []
for area_name, area_data in compliance_areas.items():
lines.append(f"{area_name}:")
lines.append(f"- Description: {area_data['description']}")
lines.append("- Checks:")
for check in area_data["checks"]:
lines.append(f" - {check}")
lines.append("") # blank line between areas
return "\n".join(lines)
def analyze_compliance(api_key: str, free_text: str, uploaded_file) -> str:
"""
Use OpenAI to analyze the given text against the compliance_areas and
return a markdown report.
"""
# Basic validation
if not api_key or api_key.strip() == "":
return "⚠️ **Error:** Please enter your OpenAI API key."
# Resolve text input source: uploaded file has priority if present
text_to_check = ""
if uploaded_file is not None:
try:
file_path = getattr(uploaded_file, "name", None)
if file_path:
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
text_to_check = f.read()
else:
if hasattr(uploaded_file, "read"):
raw_bytes = uploaded_file.read()
if isinstance(raw_bytes, bytes):
text_to_check = raw_bytes.decode("utf-8", errors="ignore")
else:
text_to_check = str(raw_bytes)
except Exception as e:
return f"⚠️ **Error reading uploaded file:** {e}"
# If no file content, use the textbox content
if not text_to_check.strip():
if not free_text or free_text.strip() == "":
return "⚠️ **Error:** Please type some text or upload a .txt file to analyze."
text_to_check = free_text
# Build the prompt
compliance_description = build_compliance_instructions()
system_message = (
"You are an AI compliance auditor for financial AI systems. "
"You strictly evaluate text against the given compliance areas. "
"You return clear, structured markdown that a non-technical user "
"can read in a dashboard."
)
user_message = (
"You are given the following text from a finance-related AI system.\n\n"
"---- TEXT START ----\n"
f"{text_to_check}\n"
"---- TEXT END ----\n\n"
"Evaluate the text against these compliance areas and checks:\n\n"
f"{compliance_description}\n"
"For EACH compliance area (Data Privacy, Explainability, Auditability, Fairness):\n"
"1. State **Overall: PASSED** or **Overall: FAILED** for that area.\n"
"2. For each individual check, state:\n"
" - **Check:** <check name>\n"
" - **Status:** PASSED or FAILED\n"
" - **Reason:** One short sentence quoting or paraphrasing the text.\n"
"3. If the area FAILED, add a short '**Risk:**' line explaining why this matters "
"for a financial institution.\n\n"
"Return the result in markdown format with headings:\n"
"## Data Privacy\n"
"## Explainability\n"
"## Auditability\n"
"## Fairness\n"
)
# -----------------------------
# OpenAI call with robust import handling
# -----------------------------
try:
# Try new SDK style first (openai>=1.x)
try:
from openai import OpenAI # type: ignore
client = OpenAI(api_key=api_key)
response = client.chat.completions.create(
model="gpt-4.1-mini", # change to "gpt-4.1" if desired
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": user_message},
],
temperature=0.1,
)
result = response.choices[0].message.content
return result
except ModuleNotFoundError:
# Fallback: older SDK style `import openai`
try:
import openai # type: ignore
openai.api_key = api_key
response = openai.ChatCompletion.create(
model="gpt-4.1-mini",
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": user_message},
],
temperature=0.1,
)
result = response["choices"][0]["message"]["content"]
return result
except ModuleNotFoundError:
return (
"⚠️ **OpenAI library not installed.**\n\n"
"Please add `openai` to your `requirements.txt`:\n\n"
"```text\nopenai>=1.0.0\n```\n"
"and rebuild/restart the app."
)
except Exception as e:
return f"⚠️ **OpenAI API Error:** {e}"
# -----------------------------
# Gradio UI
# -----------------------------
def build_interface():
with gr.Blocks(title="AI Compliance Checker (Finance)") as demo:
gr.Markdown(
"""
# 🧭 AI Compliance Checker (Finance)
Paste or upload a **finance-related AI system description** and check it against:
- **Data Privacy**
- **Explainability**
- **Auditability**
- **Fairness**
The app uses the **OpenAI API** to generate a structured compliance report.
"""
)
with gr.Group():
api_key = gr.Textbox(
label="OpenAI API Key",
placeholder="sk-...",
type="password",
)
with gr.Row():
text_input = gr.Textbox(
label="Text to Analyze (you can type or paste here)",
lines=12,
placeholder="Paste your AI policy, system description, or output here...",
)
file_input = gr.File(
label="Or Upload a .txt Document",
file_types=["text"],
)
output = gr.Markdown(label="Compliance Report")
run_button = gr.Button("🔍 Run Compliance Check")
run_button.click(
fn=analyze_compliance,
inputs=[api_key, text_input, file_input],
outputs=output,
)
return demo
if __name__ == "__main__":
demo = build_interface()
demo.launch()