fermentation_predictor_madeUp / src /streamlit_app.py
AmandaHattaway's picture
Update src/streamlit_app.py
1e81d08 verified
Raw
History Blame Contribute Delete
12.3 kB
import streamlit as st
import snowflake.connector
import pandas as pd
import os
import json
st.set_page_config(
page_title="Fermentation Status Predictor",
page_icon="๐Ÿงช",
layout="wide"
)
@st.cache_resource
def get_snowflake_connection():
try:
user = os.environ.get("SNOWFLAKE_USER")
password = os.environ.get("SNOWFLAKE_PASSWORD")
account = os.environ.get("SNOWFLAKE_ACCOUNT")
warehouse = os.environ.get("SNOWFLAKE_WAREHOUSE")
st.write("๐Ÿ” Debug Info:")
st.write(f"- User found: {'โœ…' if user else 'โŒ'}")
st.write(f"- Password found: {'โœ…' if password else 'โŒ'}")
st.write(f"- Account found: {'โœ…' if account else 'โŒ'} (using: {account[:10]}...)")
st.write(f"- Warehouse found: {'โœ…' if warehouse else 'โŒ'} (using: {warehouse})")
if not all([user, password, account, warehouse]):
missing = []
if not user: missing.append("SNOWFLAKE_USER")
if not password: missing.append("SNOWFLAKE_PASSWORD")
if not account: missing.append("SNOWFLAKE_ACCOUNT")
if not warehouse: missing.append("SNOWFLAKE_WAREHOUSE")
st.error(f"โŒ Missing environment variables: {', '.join(missing)}")
st.info("๐Ÿ’ก Please add these as Repository Secrets in your Hugging Face Space settings.")
return None
st.write("๐Ÿ”‘ Attempting Snowflake connection...")
st.write(f"Trying to connect to: {account}.snowflakecomputing.com")
conn = snowflake.connector.connect(
user=user,
password=password,
account=account,
warehouse=warehouse,
database="sennos_interview_prep",
schema="public",
login_timeout=60,
network_timeout=60
)
st.success("โœ… Successfully connected to Snowflake!")
return conn
except Exception as e:
error_msg = str(e)
st.error(f"โŒ Failed to connect to Snowflake: {error_msg}")
st.write("**Troubleshooting steps:**")
if "250001" in error_msg or "Could not connect" in error_msg:
st.warning("๐Ÿ”ด **Network/Account Issue Detected**")
st.write("Your account identifier format might be wrong. Try these:")
st.code(f"""
# If your Snowflake URL is like:
https://abc12345.snowflakecomputing.com
๐Ÿ‘‰ Use: abc12345
# If your Snowflake URL is like:
https://abc12345.us-east-1.snowflakecomputing.com
๐Ÿ‘‰ Use: abc12345.us-east-1
# If you have a new org-based account:
https://orgname-accountname.snowflakecomputing.com
๐Ÿ‘‰ Use: orgname-accountname
""")
st.write("**Current account value (first 15 chars):**", account[:15] if len(account) > 15 else account)
st.write("- Check your Snowflake login URL and extract the exact account identifier")
st.write("- Make sure you can log into Snowflake from your browser")
st.write("- Verify the warehouse name is spelled correctly")
st.write("- Check if your Snowflake account allows external connections")
return None
def make_prediction(batch_id, temp_mean, temp_std, ph_mean, ph_std,
pressure_mean, pressure_std, conductivity_mean, conductivity_std):
try:
user = os.environ.get("SNOWFLAKE_USER")
password = os.environ.get("SNOWFLAKE_PASSWORD")
account = os.environ.get("SNOWFLAKE_ACCOUNT")
warehouse = os.environ.get("SNOWFLAKE_WAREHOUSE")
if not all([user, password, account, warehouse]):
return None, "Missing credentials"
conn = snowflake.connector.connect(
user=user,
password=password,
account=account,
warehouse=warehouse,
database="sennos_interview_prep",
schema="public"
)
cur = conn.cursor()
create_temp_sql = f"""
CREATE OR REPLACE TEMPORARY TABLE temp_prediction_input AS
SELECT
{temp_mean} as TEMP_MEAN,
{temp_std} as TEMP_STD,
{ph_mean} as PH_MEAN,
{ph_std} as PH_STD,
{pressure_mean} as PRESSURE_MEAN,
{pressure_std} as PRESSURE_STD,
{conductivity_mean} as CONDUCTIVITY_MEAN,
{conductivity_std} as CONDUCTIVITY_STD
"""
cur.execute(create_temp_sql)
prediction_sql = """
SELECT
sennos_interview_prep.public.fermentation_status_predictor!PREDICT(
TEMP_MEAN, TEMP_STD, PH_MEAN, PH_STD,
PRESSURE_MEAN, PRESSURE_STD, CONDUCTIVITY_MEAN, CONDUCTIVITY_STD
) as prediction_result
FROM temp_prediction_input
"""
cur.execute(prediction_sql)
result = cur.fetchone()
if result:
prediction_json = result[0]
if isinstance(prediction_json, str):
prediction_data = json.loads(prediction_json)
else:
prediction_data = prediction_json
prediction_int = int(prediction_data.get('output_feature_0', prediction_data))
if prediction_int == 0:
status_label = "Good"
elif prediction_int == 1:
status_label = "Infection"
else:
status_label = "Stalled"
cur.close()
conn.close()
return prediction_int, status_label
else:
cur.close()
conn.close()
return None, "No result returned"
except Exception as e:
return None, f"Prediction error: {str(e)}"
st.title("๐Ÿงช Fermentation Status Predictor")
st.write("Predict fermentation status using ML model hosted in Snowflake")
st.write("*This is a public demo - no login required!*")
with st.expander("๐Ÿ”— Connection Status"):
if get_snowflake_connection():
st.success("โœ… Connected to Snowflake")
else:
st.error("โŒ Failed to connect to Snowflake")
with st.form("prediction_form"):
st.subheader("Enter Fermentation Parameters:")
col1, col2 = st.columns(2)
with col1:
batch_id = st.number_input("Batch ID",
min_value=1000,
max_value=9999,
value=1001,
step=1)
temp_mean = st.number_input("Temperature Mean (ยฐC)",
min_value=0.0,
max_value=50.0,
value=33.5,
step=0.1)
temp_std = st.number_input("Temperature Std Dev",
min_value=0.0,
max_value=5.0,
value=0.5,
step=0.1)
ph_mean = st.number_input("pH Mean",
min_value=0.0,
max_value=14.0,
value=5.0,
step=0.1)
ph_std = st.number_input("pH Std Dev",
min_value=0.0,
max_value=2.0,
value=0.2,
step=0.01)
with col2:
pressure_mean = st.number_input("Pressure Mean",
min_value=0.0,
max_value=30.0,
value=15.0,
step=0.1)
pressure_std = st.number_input("Pressure Std Dev",
min_value=0.0,
max_value=5.0,
value=0.1,
step=0.01)
conductivity_mean = st.number_input("Conductivity Mean",
min_value=0,
max_value=3000,
value=1600,
step=10)
conductivity_std = st.number_input("Conductivity Std Dev",
min_value=0,
max_value=200,
value=50,
step=1)
submitted = st.form_submit_button("๐Ÿ”ฎ Make Prediction")
if submitted:
with st.spinner('๐Ÿ”„ Connecting to Snowflake and making prediction... Please wait...'):
prediction_int, status_or_error = make_prediction(
batch_id, temp_mean, temp_std, ph_mean, ph_std,
pressure_mean, pressure_std, conductivity_mean, conductivity_std
)
if prediction_int is not None:
st.success("โœ… Prediction Complete!")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("๐Ÿ†” Batch ID", batch_id)
with col2:
st.metric("๐ŸŒก๏ธ Temp Mean", f"{temp_mean}ยฐC")
with col3:
st.metric("๐Ÿงช pH Mean", f"{ph_mean}")
with col4:
st.metric("๐Ÿ“Š Conductivity", conductivity_mean)
st.subheader("๐Ÿ“Š Prediction Result:")
if status_or_error == "Good":
st.success(f"๐ŸŸข **Status: {status_or_error}** (Code: {prediction_int})")
st.info("โœ… Fermentation is proceeding normally!")
elif status_or_error == "Infection":
st.error(f"๐Ÿ”ด **Status: {status_or_error}** (Code: {prediction_int})")
st.warning("โš ๏ธ Possible bacterial infection detected!")
else:
st.warning(f"๐ŸŸก **Status: {status_or_error}** (Code: {prediction_int})")
st.info("โธ๏ธ Fermentation appears to be stalled.")
else:
st.error(f"โŒ {status_or_error}")
with st.expander("โ„น๏ธ About This Model"):
st.write("""
This fermentation status prediction model analyzes fermentation batch data to predict the current status:
- **๐ŸŸข Good (0)**: Fermentation is proceeding normally
- **๐Ÿ”ด Infection (1)**: Bacterial infection likely detected
- **๐ŸŸก Stalled (2)**: Fermentation has stalled or stopped
**Input Parameters:**
- **Temperature Stats**: Mean and standard deviation of batch temperature
- **pH Stats**: Mean and standard deviation of pH levels
- **Pressure Stats**: Mean and standard deviation of pressure readings
- **Conductivity Stats**: Mean and standard deviation of conductivity measurements
The model uses statistical features (mean + std dev) to capture both the central tendency
and variability of each measurement across the fermentation batch.
**Model Location**: Hosted in Snowflake Cloud Data Platform
""")
st.subheader("๐Ÿ“‹ Batch Predictions (CSV Upload)")
uploaded_file = st.file_uploader("Upload CSV with columns: BATCH_ID, TEMP_MEAN, TEMP_STD, PH_MEAN, PH_STD, PRESSURE_MEAN, PRESSURE_STD, CONDUCTIVITY_MEAN, CONDUCTIVITY_STD", type=['csv'])
if uploaded_file is not None:
try:
df = pd.read_csv(uploaded_file)
st.write("Preview of uploaded data:")
st.dataframe(df.head())
if st.button("๐Ÿš€ Run Batch Predictions"):
st.info("Batch predictions feature coming soon! For now, use individual predictions above.")
except Exception as e:
st.error(f"Error reading file: {str(e)}")
st.markdown("---")
st.write("๐Ÿš€ Powered by Snowflake ML | Hosted on Hugging Face Spaces")
st.write("*No authentication required - anyone can use this predictor!*")