In the pharmaceutical industry, data privacy is a non-negotiable priority. Sending sensitive clinical trials, drug formulations, or patient records to public cloud-based AI models can pose significant security and regulatory risks (HIPAA, GDPR).
In this codelab, you will build a
"Zero-Compromise" AI Business Dashboard
. This advanced version uses Gemma 3
not just as a chatbot, but as a Structured Data Analyst
that identifies business domains, recommends KPIs, and suggests visualizations—all while keeping data strictly local.
To follow this tutorial, you will need the following:
We are using Gemma 3 because it is a lightweight, high-performance model optimized for reasoning and structured output tasks.
After installing Ollama, run the following command to download the model:
# Pull the Gemma 3 4B model
ollama pull gemma3:4b
Install the libraries needed for data processing and the web interface:
pip install streamlit pandas ollama
Create a file named
app.py
. We will implement this in three logical layers: Data Preprocessing, AI Analysis (JSON-based), and Dynamic UI Rendering.
Before sending data to the AI, we need to summarise it so the model understands the schema without reading thousands of rows.
preprocess_data: Extracts column names, types, and missing value counts.safe_json_parse: Since LLMs sometimes add conversational text around JSON, this uses Regular Expressions to find and extract the valid JSON block.calculate_kpi: A mapping function that calculates actual totals from the dataframe based on the names suggested by the AI.This function constructs a prompt containing the "Profile" of the dataset. Notice the instruction
"Return STRICT JSON"
. This is crucial because it allows our Python code to use the AI's "thoughts" to build actual UI components.
Using Streamlit, we create a file uploader. Once a file is uploaded, the AI analyzes the metadata, and the dashboard dynamically builds metrics and charts.
Paste the following code into your
app.py
:
import streamlit as st
import pandas as pd
import json
import ollama
import re
# -————— CONFIG & UI -—————
st.set_page_config(page_title="AI Pharma Business Dashboard", layout="wide")
st.title("📊 Pharma Business Dashboard (Gemma 3 – AI Analyst)")
# -————— HELPERS: Data & Parsing -—————
def preprocess_data(df):
""" Summarises dataset structure for the LLM."""
return {
"rows": len(df),
"columns": list(df.columns),
"numeric": df.select\_dtypes(include="number").columns.tolist(),
"categorical": df.select\_dtypes(exclude="number").columns.tolist(),
"missing": df.isnull().sum().to\_dict()
}
def safe_json_parse(text):
"""Safely extracts and parses JSON from LLM response."""
if not text or text.strip() \== "": return None
try:
return json.loads(text)
except:
match \= re.search(r"\\{.\*\\}", text, re.DOTALL)
if match:
try: return json.loads(match.group())
except: return None
return None
def calculate_kpi(kpi_name, df):
"""Logic to map AI suggested KPIs to actual data values."""
name \= kpi\_name.lower()
numeric\_cols \= df.select\_dtypes(include="number").columns
if any(x in name for x in \["revenue", "sales", "amount"\]):
for col in numeric\_cols:
if any(x in col.lower() for x in \["revenue", "sales", "amount"\]):
return f"${df\[col\].sum():,.0f}"
return "N/A"
# -————— AI ANALYSIS ENGINE -—————
def gemma_business_analysis(profile, df):
sample \= df.head(5).to\_dict()
prompt \= f"""
You are a senior pharma business analyst.
Dataset profile: {profile}
Sample data: {sample}
Tasks:
1. Identify business domain (e.g., Clinical Trials, Sales, Supply Chain)
2. List 4–6 important KPIs
3. Recommend charts (bar or line)
4. Write clear business insights
Return STRICT JSON:
{{
"domain": "",
"kpis": ["", ""],
"charts": [{{"type": "bar", "x": "", "y": ""}}],
"insights": ["", ""]
}}
"""
response \= ollama.chat(model="gemma3:4b", messages=\[{"role": "user", "content": prompt}\])
parsed \= safe\_json\_parse(response\["message"\]\["content"\])
return parsed if parsed else {"domain": "Unknown", "kpis": \[\], "charts": \[\], "insights": \["Parsing Error"\]}
# -————— DYNAMIC UI RENDERING -—————
uploaded_file = st.file_uploader("📁 Upload your Pharma/Business CSV file", type=["csv"])
if uploaded_file:
df \= pd.read\_csv(uploaded\_file, encoding="latin-1")
st.subheader(" Data Preview")
st.dataframe(df.head())
profile \= preprocess\_data(df)
if st.button(" Generate AI Insights"):
with st.spinner("Gemma 3 is analyzing your data locally..."):
result \= gemma\_business\_analysis(profile, df)
st.subheader(f" Domain: {result\['domain'\]}")
\# Display KPIs
st.markdown("\#\# 📈 Key Metrics")
k\_cols \= st.columns(len(result\["kpis"\]\[:4\]))
for i, kpi in enumerate(result\["kpis"\]\[:4\]):
val \= calculate\_kpi(kpi, df)
k\_cols\[i\].metric(kpi, val)
\# Render AI-Recommended Charts
st.subheader("📊 Visual Analytics")
for chart in result\["charts"\]:
x, y \= chart.get("x"), chart.get("y")
if x in df.columns and y in df.columns:
if chart\["type"\] \== "bar": st.bar\_chart(df.groupby(x)\[y\].sum())
else: st.line\_chart(df.groupby(x)\[y\].sum())
st.subheader(" Strategic Insights")
for insight in result\["insights"\]:
st.write(f"• {insight}")
ollama instance.Launch your private dashboard by running:
streamlit run app.py
By integrating Gemma 3 as a structured analyst, you've moved beyond simple chat interfaces into
Agentic BI
. For Pharma consultants, this provides a "ready-to-deploy" framework that respects data sovereignty while delivering high-level executive insights.
Next Steps:
calculate_kpi function to handle complex Pharma-specific formulas like "Drug Efficacy Ratio."The true power of this project lies in its future scalability. We are moving towards an
Agentic AutoML
framework where:
Developed by Geeta Kakrani | Google Developer Expert (AI)