Upload folder using huggingface_hub
Browse files- Dockerfile +13 -7
- app.py +99 -29
Dockerfile
CHANGED
|
@@ -1,16 +1,22 @@
|
|
| 1 |
-
|
|
|
|
| 2 |
|
|
|
|
| 3 |
ENV PYTHONDONTWRITEBYTECODE=1
|
| 4 |
ENV PYTHONUNBUFFERED=1
|
| 5 |
|
| 6 |
WORKDIR /app
|
| 7 |
|
| 8 |
-
|
| 9 |
-
RUN pip install --no-cache-dir --upgrade pip \
|
| 10 |
-
&& pip install --no-cache-dir -r requirements.txt
|
| 11 |
-
|
| 12 |
COPY . .
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
| 15 |
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#Use a minimal base image with Python 3.9 installed
|
| 2 |
+
FROM python:3.9-slim
|
| 3 |
|
| 4 |
+
# Prevent Python from writing pyc files and buffering stdout
|
| 5 |
ENV PYTHONDONTWRITEBYTECODE=1
|
| 6 |
ENV PYTHONUNBUFFERED=1
|
| 7 |
|
| 8 |
WORKDIR /app
|
| 9 |
|
| 10 |
+
#Copy project files
|
|
|
|
|
|
|
|
|
|
| 11 |
COPY . .
|
| 12 |
|
| 13 |
+
#Upgrade pip and install dependencies
|
| 14 |
+
RUN pip install --no-cache-dir --upgrade pip \
|
| 15 |
+
&& pip install --no-cache-dir -r requirements.txt
|
| 16 |
|
| 17 |
+
#Streamlit runs on 7860 in Hugging Face Spaces
|
| 18 |
+
CMD ["streamlit", "run", "app.py", \
|
| 19 |
+
"--server.port=7860", \
|
| 20 |
+
"--server.address=0.0.0.0", \
|
| 21 |
+
"--server.headless=true", \
|
| 22 |
+
"--server.enableXsrfProtection=false"]
|
app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
import pandas as pd
|
| 3 |
import requests
|
|
|
|
| 4 |
|
| 5 |
# -----------------------------
|
| 6 |
# App Config
|
|
@@ -12,7 +13,7 @@ st.set_page_config(
|
|
| 12 |
|
| 13 |
st.title("Predictive Maintenance Predictor")
|
| 14 |
st.write(
|
| 15 |
-
"This app predicts **Predictive Maintenance** based on engine sensor data.
|
| 16 |
"Developed and Deployed by **Sathiamurthy Samidurai (AIML Student)**."
|
| 17 |
)
|
| 18 |
|
|
@@ -22,6 +23,63 @@ st.write(
|
|
| 22 |
BACKEND_URL = "https://samdurai102024-predictive-maintenance-be.hf.space/v1/maintenance"
|
| 23 |
BACKEND_URL_BATCH = "https://samdurai102024-predictive-maintenance-be.hf.space/v1/maintenancebatch"
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
# -----------------------------
|
| 26 |
# User Inputs
|
| 27 |
# -----------------------------
|
|
@@ -34,18 +92,18 @@ Coolant_pressure = st.number_input("Coolant Pressure", min_value=0.0)
|
|
| 34 |
lub_oil_temp = st.number_input("Lub Oil Temperature", min_value=0.0)
|
| 35 |
Coolant_temp = st.number_input("Coolant Temperature", min_value=0.0)
|
| 36 |
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
)
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
)
|
| 46 |
|
| 47 |
# -----------------------------
|
| 48 |
-
#
|
| 49 |
# -----------------------------
|
| 50 |
payload = {
|
| 51 |
"Engine_rpm": Engine_rpm,
|
|
@@ -54,8 +112,12 @@ payload = {
|
|
| 54 |
"Coolant_pressure": Coolant_pressure,
|
| 55 |
"lub_oil_temp": lub_oil_temp,
|
| 56 |
"Coolant_temp": Coolant_temp,
|
| 57 |
-
"rpm_category":
|
| 58 |
-
"oil_pressure_category":
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
}
|
| 60 |
|
| 61 |
# -----------------------------
|
|
@@ -63,23 +125,14 @@ payload = {
|
|
| 63 |
# -----------------------------
|
| 64 |
if st.button("Predict", type="primary"):
|
| 65 |
try:
|
| 66 |
-
response = requests.post(
|
| 67 |
-
BACKEND_URL,
|
| 68 |
-
json=payload,
|
| 69 |
-
timeout=10
|
| 70 |
-
)
|
| 71 |
-
|
| 72 |
if response.status_code == 200:
|
| 73 |
result = response.json()
|
| 74 |
st.success("Prediction Successful")
|
| 75 |
-
st.metric(
|
| 76 |
-
label="Predictive Maintenance Result",
|
| 77 |
-
value=result["prediction"]
|
| 78 |
-
)
|
| 79 |
else:
|
| 80 |
st.error(f"API Error {response.status_code}")
|
| 81 |
-
st.
|
| 82 |
-
|
| 83 |
except requests.exceptions.RequestException as e:
|
| 84 |
st.error("Backend service unavailable")
|
| 85 |
st.write(str(e))
|
|
@@ -90,18 +143,35 @@ if st.button("Predict", type="primary"):
|
|
| 90 |
st.divider()
|
| 91 |
st.subheader("Batch Prediction")
|
| 92 |
|
| 93 |
-
|
| 94 |
"Upload CSV file",
|
| 95 |
type=["csv"],
|
| 96 |
-
help="CSV must contain the same feature columns used during training"
|
| 97 |
)
|
| 98 |
|
| 99 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
if st.button("Predict for Batch", type="primary"):
|
|
|
|
|
|
|
|
|
|
| 101 |
try:
|
| 102 |
response = requests.post(
|
| 103 |
BACKEND_URL_BATCH,
|
| 104 |
-
files={"file":
|
| 105 |
timeout=20
|
| 106 |
)
|
| 107 |
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
import pandas as pd
|
| 3 |
import requests
|
| 4 |
+
import io
|
| 5 |
|
| 6 |
# -----------------------------
|
| 7 |
# App Config
|
|
|
|
| 13 |
|
| 14 |
st.title("Predictive Maintenance Predictor")
|
| 15 |
st.write(
|
| 16 |
+
"This app predicts **Predictive Maintenance** based on engine sensor data.\n\n"
|
| 17 |
"Developed and Deployed by **Sathiamurthy Samidurai (AIML Student)**."
|
| 18 |
)
|
| 19 |
|
|
|
|
| 23 |
BACKEND_URL = "https://samdurai102024-predictive-maintenance-be.hf.space/v1/maintenance"
|
| 24 |
BACKEND_URL_BATCH = "https://samdurai102024-predictive-maintenance-be.hf.space/v1/maintenancebatch"
|
| 25 |
|
| 26 |
+
# -----------------------------
|
| 27 |
+
# Feature Engineering Functions
|
| 28 |
+
# -----------------------------
|
| 29 |
+
def rpm_category_fn(rpm):
|
| 30 |
+
if rpm <= 742:
|
| 31 |
+
return "High Risk"
|
| 32 |
+
elif rpm <= 886:
|
| 33 |
+
return "Moderate Risk"
|
| 34 |
+
else:
|
| 35 |
+
return "Lower Risk"
|
| 36 |
+
|
| 37 |
+
def oil_pressure_category_fn(op):
|
| 38 |
+
if op <= 2.5:
|
| 39 |
+
return "Low Risk"
|
| 40 |
+
elif op <= 5.0:
|
| 41 |
+
return "Mid Risk"
|
| 42 |
+
else:
|
| 43 |
+
return "High Risk"
|
| 44 |
+
|
| 45 |
+
def fuel_pressure_category_fn(fp):
|
| 46 |
+
if fp <= 4.0:
|
| 47 |
+
return "Low Risk"
|
| 48 |
+
elif fp <= 5.1:
|
| 49 |
+
return "Mid Risk"
|
| 50 |
+
elif fp <= 6.2:
|
| 51 |
+
return "High Risk"
|
| 52 |
+
else:
|
| 53 |
+
return "Very High Risk"
|
| 54 |
+
|
| 55 |
+
def coolant_pressure_category_fn(cp):
|
| 56 |
+
if cp <= 3.1:
|
| 57 |
+
return "Normal-to-Elevated"
|
| 58 |
+
elif cp <= 3.8:
|
| 59 |
+
return "Critical Pressure"
|
| 60 |
+
else:
|
| 61 |
+
return "Relief / Saturation Regime"
|
| 62 |
+
|
| 63 |
+
def fuel_oil_risk_fn(fp, ot):
|
| 64 |
+
if (fp > 5.1) and (ot < 77.2):
|
| 65 |
+
return "High Risk"
|
| 66 |
+
elif (fp > 5.1) and (ot >= 77.2):
|
| 67 |
+
return "Mid Risk"
|
| 68 |
+
elif (fp <= 5.1) and (ot < 77.2):
|
| 69 |
+
return "Mid Risk"
|
| 70 |
+
else:
|
| 71 |
+
return "Low Risk"
|
| 72 |
+
|
| 73 |
+
def coolant_temp_category_fn(ct):
|
| 74 |
+
if ct < 69.17:
|
| 75 |
+
return "High"
|
| 76 |
+
elif ct < 72.27:
|
| 77 |
+
return "Elevated"
|
| 78 |
+
elif ct < 80.55:
|
| 79 |
+
return "Moderate"
|
| 80 |
+
else:
|
| 81 |
+
return "Lower"
|
| 82 |
+
|
| 83 |
# -----------------------------
|
| 84 |
# User Inputs
|
| 85 |
# -----------------------------
|
|
|
|
| 92 |
lub_oil_temp = st.number_input("Lub Oil Temperature", min_value=0.0)
|
| 93 |
Coolant_temp = st.number_input("Coolant Temperature", min_value=0.0)
|
| 94 |
|
| 95 |
+
# -----------------------------
|
| 96 |
+
# Derived Features (Single)
|
| 97 |
+
# -----------------------------
|
| 98 |
+
rpm_category_val = rpm_category_fn(Engine_rpm)
|
| 99 |
+
oil_pressure_category_val = oil_pressure_category_fn(Lub_oil_pressure)
|
| 100 |
+
fuel_pressure_category_val = fuel_pressure_category_fn(Fuel_pressure)
|
| 101 |
+
coolant_pressure_category_val = coolant_pressure_category_fn(Coolant_pressure)
|
| 102 |
+
fuel_pressure_oil_temp_val = fuel_oil_risk_fn(Fuel_pressure, lub_oil_temp)
|
| 103 |
+
coolant_temp_category_val = coolant_temp_category_fn(Coolant_temp)
|
| 104 |
|
| 105 |
# -----------------------------
|
| 106 |
+
# Payload
|
| 107 |
# -----------------------------
|
| 108 |
payload = {
|
| 109 |
"Engine_rpm": Engine_rpm,
|
|
|
|
| 112 |
"Coolant_pressure": Coolant_pressure,
|
| 113 |
"lub_oil_temp": lub_oil_temp,
|
| 114 |
"Coolant_temp": Coolant_temp,
|
| 115 |
+
"rpm_category": rpm_category_val,
|
| 116 |
+
"oil_pressure_category": oil_pressure_category_val,
|
| 117 |
+
"fuel_pressure_category": fuel_pressure_category_val,
|
| 118 |
+
"coolant_pressure_category": coolant_pressure_category_val,
|
| 119 |
+
"fuel_pressure_oil_temp": fuel_pressure_oil_temp_val,
|
| 120 |
+
"coolant_temp_category": coolant_temp_category_val
|
| 121 |
}
|
| 122 |
|
| 123 |
# -----------------------------
|
|
|
|
| 125 |
# -----------------------------
|
| 126 |
if st.button("Predict", type="primary"):
|
| 127 |
try:
|
| 128 |
+
response = requests.post(BACKEND_URL, json=payload, timeout=10)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
if response.status_code == 200:
|
| 130 |
result = response.json()
|
| 131 |
st.success("Prediction Successful")
|
| 132 |
+
st.metric("Predictive Maintenance Result", result["prediction"])
|
|
|
|
|
|
|
|
|
|
| 133 |
else:
|
| 134 |
st.error(f"API Error {response.status_code}")
|
| 135 |
+
st.write(response.text)
|
|
|
|
| 136 |
except requests.exceptions.RequestException as e:
|
| 137 |
st.error("Backend service unavailable")
|
| 138 |
st.write(str(e))
|
|
|
|
| 143 |
st.divider()
|
| 144 |
st.subheader("Batch Prediction")
|
| 145 |
|
| 146 |
+
uploaded_file = st.file_uploader(
|
| 147 |
"Upload CSV file",
|
| 148 |
type=["csv"],
|
| 149 |
+
help="CSV must contain the same raw feature columns used during training"
|
| 150 |
)
|
| 151 |
|
| 152 |
+
if uploaded_file is not None:
|
| 153 |
+
df = pd.read_csv(uploaded_file)
|
| 154 |
+
|
| 155 |
+
# Feature Engineering
|
| 156 |
+
df["rpm_category"] = df["Engine_rpm"].apply(rpm_category_fn)
|
| 157 |
+
df["oil_pressure_category"] = df["Lub_oil_pressure"].apply(oil_pressure_category_fn)
|
| 158 |
+
df["fuel_pressure_category"] = df["Fuel_pressure"].apply(fuel_pressure_category_fn)
|
| 159 |
+
df["coolant_pressure_category"] = df["Coolant_pressure"].apply(coolant_pressure_category_fn)
|
| 160 |
+
df["fuel_pressure_oil_temp"] = df.apply(
|
| 161 |
+
lambda r: fuel_oil_risk_fn(r["Fuel_pressure"], r["lub_oil_temp"]), axis=1
|
| 162 |
+
)
|
| 163 |
+
df["coolant_temp_category"] = df["Coolant_temp"].apply(coolant_temp_category_fn)
|
| 164 |
+
|
| 165 |
+
st.dataframe(df.head())
|
| 166 |
+
|
| 167 |
if st.button("Predict for Batch", type="primary"):
|
| 168 |
+
csv_buffer = io.StringIO()
|
| 169 |
+
df.to_csv(csv_buffer, index=False)
|
| 170 |
+
|
| 171 |
try:
|
| 172 |
response = requests.post(
|
| 173 |
BACKEND_URL_BATCH,
|
| 174 |
+
files={"file": ("batch.csv", csv_buffer.getvalue())},
|
| 175 |
timeout=20
|
| 176 |
)
|
| 177 |
|