Spaces:
Sleeping
Sleeping
| # 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() | |