Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -10,36 +10,23 @@ import PyPDF2
|
|
10 |
import tempfile
|
11 |
import os
|
12 |
|
13 |
-
st.set_page_config(page_title="π WiFi Anomaly Detection", layout="wide")
|
14 |
-
|
15 |
# -------------------------------
|
16 |
-
#
|
17 |
# -------------------------------
|
18 |
-
st.
|
|
|
19 |
st.markdown("""
|
20 |
-
|
21 |
-
|
|
|
22 |
""")
|
23 |
-
st.markdown("### How it Works:")
|
24 |
st.markdown("""
|
25 |
-
|
26 |
-
- **Anomaly Detection:** Use AI algorithms to automatically spot unusual patterns.
|
27 |
-
- **Visualization:** Review data in 2D and 3D interactive charts.
|
28 |
-
- **Report Generation:** Download a comprehensive PDF report with summaries and visuals.
|
29 |
""")
|
30 |
|
31 |
# -------------------------------
|
32 |
-
#
|
33 |
-
# -------------------------------
|
34 |
-
st.sidebar.header("π Upload Data File")
|
35 |
-
uploaded_file = st.sidebar.file_uploader("Choose a file", type=["csv", "txt", "pdf"])
|
36 |
-
st.sidebar.markdown("---")
|
37 |
-
model_option = st.sidebar.radio("Select Anomaly Detection Model", ("Local Model", "Groq API"))
|
38 |
-
|
39 |
# -------------------------------
|
40 |
-
# Helper Functions
|
41 |
-
# -------------------------------
|
42 |
-
|
43 |
def load_data(uploaded_file):
|
44 |
file_type = uploaded_file.name.split('.')[-1].lower()
|
45 |
if file_type == 'csv':
|
@@ -51,7 +38,6 @@ def load_data(uploaded_file):
|
|
51 |
return None, None
|
52 |
elif file_type == 'txt':
|
53 |
try:
|
54 |
-
# Try comma separated first; if not, try whitespace separation
|
55 |
try:
|
56 |
df = pd.read_csv(uploaded_file, sep=",")
|
57 |
except:
|
@@ -66,7 +52,6 @@ def load_data(uploaded_file):
|
|
66 |
text = ""
|
67 |
for page in pdf_reader.pages:
|
68 |
text += page.extract_text()
|
69 |
-
# For demonstration, create a DataFrame with one text column
|
70 |
df = pd.DataFrame({"text": [text]})
|
71 |
return df, "pdf"
|
72 |
except Exception as e:
|
@@ -85,23 +70,18 @@ def run_local_anomaly_detection(df):
|
|
85 |
X = df[numeric_cols].fillna(0)
|
86 |
model = IsolationForest(contamination=0.1, random_state=42)
|
87 |
model.fit(X)
|
88 |
-
# Model returns -1 for anomalies, 1 for normal records
|
89 |
df['anomaly'] = model.predict(X)
|
90 |
df['anomaly_flag'] = df['anomaly'].apply(lambda x: "π¨ Anomaly" if x == -1 else "β
Normal")
|
91 |
return df
|
92 |
|
93 |
def call_groq_api(df):
|
94 |
# ----- Dummy Groq API integration -----
|
95 |
-
#
|
96 |
-
# response = requests.post("https://api.groq.ai/detect", json=df.to_dict(orient="records"))
|
97 |
-
# and then process the JSON response.
|
98 |
-
# For demo purposes, we simply call the local model.
|
99 |
-
# ----------------------------------------
|
100 |
df = run_local_anomaly_detection(df)
|
101 |
return df
|
102 |
|
103 |
def generate_plots(df):
|
104 |
-
#
|
105 |
numeric_cols = df.select_dtypes(include=[np.number]).columns
|
106 |
fig2d, fig3d = None, None
|
107 |
if len(numeric_cols) >= 2:
|
@@ -144,53 +124,99 @@ def generate_pdf_report(summary_text, fig2d, fig3d):
|
|
144 |
for image in image_files:
|
145 |
os.remove(image)
|
146 |
|
147 |
-
|
148 |
-
pdf.output(pdf_output)
|
149 |
-
pdf_data = pdf_output.getvalue()
|
150 |
-
pdf_output.close()
|
151 |
return pdf_data
|
152 |
|
153 |
# -------------------------------
|
154 |
-
#
|
155 |
# -------------------------------
|
156 |
-
if
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
|
|
|
|
|
|
|
|
|
|
193 |
else:
|
194 |
-
st.
|
195 |
-
|
196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
import tempfile
|
11 |
import os
|
12 |
|
|
|
|
|
13 |
# -------------------------------
|
14 |
+
# Page Configuration and Header
|
15 |
# -------------------------------
|
16 |
+
st.set_page_config(page_title="π WiFi Anomaly Detection", layout="wide")
|
17 |
+
st.title("π WiFi Anomaly Detection System")
|
18 |
st.markdown("""
|
19 |
+
> "Innovation distinguishes between a leader and a follower." β *Steve Jobs*
|
20 |
+
|
21 |
+
> "The future depends on what you do today." β *Mahatma Gandhi*
|
22 |
""")
|
|
|
23 |
st.markdown("""
|
24 |
+
Welcome to the WiFi Anomaly Detection System. This application uses AI to proactively detect abnormal behavior in Public Wi-Fi systems, identifying suspicious spikes that may indicate hacking attempts. Letβs build a more secure network, one anomaly at a time!
|
|
|
|
|
|
|
25 |
""")
|
26 |
|
27 |
# -------------------------------
|
28 |
+
# Define Helper Functions
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
# -------------------------------
|
|
|
|
|
|
|
30 |
def load_data(uploaded_file):
|
31 |
file_type = uploaded_file.name.split('.')[-1].lower()
|
32 |
if file_type == 'csv':
|
|
|
38 |
return None, None
|
39 |
elif file_type == 'txt':
|
40 |
try:
|
|
|
41 |
try:
|
42 |
df = pd.read_csv(uploaded_file, sep=",")
|
43 |
except:
|
|
|
52 |
text = ""
|
53 |
for page in pdf_reader.pages:
|
54 |
text += page.extract_text()
|
|
|
55 |
df = pd.DataFrame({"text": [text]})
|
56 |
return df, "pdf"
|
57 |
except Exception as e:
|
|
|
70 |
X = df[numeric_cols].fillna(0)
|
71 |
model = IsolationForest(contamination=0.1, random_state=42)
|
72 |
model.fit(X)
|
|
|
73 |
df['anomaly'] = model.predict(X)
|
74 |
df['anomaly_flag'] = df['anomaly'].apply(lambda x: "π¨ Anomaly" if x == -1 else "β
Normal")
|
75 |
return df
|
76 |
|
77 |
def call_groq_api(df):
|
78 |
# ----- Dummy Groq API integration -----
|
79 |
+
# Replace this dummy call with an actual Groq API call as needed.
|
|
|
|
|
|
|
|
|
80 |
df = run_local_anomaly_detection(df)
|
81 |
return df
|
82 |
|
83 |
def generate_plots(df):
|
84 |
+
# Generate 2D and 3D plots from the first numeric columns
|
85 |
numeric_cols = df.select_dtypes(include=[np.number]).columns
|
86 |
fig2d, fig3d = None, None
|
87 |
if len(numeric_cols) >= 2:
|
|
|
124 |
for image in image_files:
|
125 |
os.remove(image)
|
126 |
|
127 |
+
pdf_data = pdf.output(dest="S").encode("latin1")
|
|
|
|
|
|
|
128 |
return pdf_data
|
129 |
|
130 |
# -------------------------------
|
131 |
+
# Initialize Session State Variables
|
132 |
# -------------------------------
|
133 |
+
if "step" not in st.session_state:
|
134 |
+
st.session_state.step = "upload"
|
135 |
+
if "df" not in st.session_state:
|
136 |
+
st.session_state.df = None
|
137 |
+
if "df_processed" not in st.session_state:
|
138 |
+
st.session_state.df_processed = None
|
139 |
+
if "fig2d" not in st.session_state:
|
140 |
+
st.session_state.fig2d = None
|
141 |
+
if "fig3d" not in st.session_state:
|
142 |
+
st.session_state.fig3d = None
|
143 |
+
if "summary_text" not in st.session_state:
|
144 |
+
st.session_state.summary_text = ""
|
145 |
+
|
146 |
+
# -------------------------------
|
147 |
+
# Sidebar: Step Buttons
|
148 |
+
# -------------------------------
|
149 |
+
st.sidebar.title("π§ Application Steps")
|
150 |
+
if st.sidebar.button("π Upload File"):
|
151 |
+
st.session_state.step = "upload"
|
152 |
+
if st.sidebar.button("π Data Visualization"):
|
153 |
+
st.session_state.step = "viz"
|
154 |
+
if st.sidebar.button("π Statistic Analysis"):
|
155 |
+
st.session_state.step = "stats"
|
156 |
+
if st.sidebar.button("β¬οΈ Download Report"):
|
157 |
+
st.session_state.step = "download"
|
158 |
+
|
159 |
+
# -------------------------------
|
160 |
+
# Main Workflow Based on Step
|
161 |
+
# -------------------------------
|
162 |
+
if st.session_state.step == "upload":
|
163 |
+
st.subheader("Step 1: Upload Your Data File")
|
164 |
+
st.markdown("Please upload a CSV, TXT, or PDF file with network data. The expected columns for CSV/TXT files are:")
|
165 |
+
st.code("['traffic', 'latency', 'packet_loss']", language="python")
|
166 |
+
uploaded_file = st.file_uploader("Choose a file", type=["csv", "txt", "pdf"])
|
167 |
+
if uploaded_file is not None:
|
168 |
+
df, file_type = load_data(uploaded_file)
|
169 |
+
if df is not None:
|
170 |
+
st.session_state.df = df
|
171 |
+
st.success("File uploaded and processed successfully!")
|
172 |
+
if file_type == "pdf":
|
173 |
+
st.subheader("Extracted Text from PDF:")
|
174 |
+
st.text_area("PDF Content", df["text"][0], height=300)
|
175 |
else:
|
176 |
+
st.subheader("Data Preview:")
|
177 |
+
st.dataframe(df.head())
|
178 |
+
else:
|
179 |
+
st.info("Awaiting file upload. π")
|
180 |
+
|
181 |
+
elif st.session_state.step == "viz":
|
182 |
+
st.subheader("Step 2: Data Visualization")
|
183 |
+
if st.session_state.df is None:
|
184 |
+
st.error("Please upload a file first in the 'Upload File' step.")
|
185 |
+
else:
|
186 |
+
# Process the data if not already done
|
187 |
+
if st.session_state.df_processed is None:
|
188 |
+
# Here, you can choose between the local model or Groq API; we use the local model for demo.
|
189 |
+
st.session_state.df_processed = run_local_anomaly_detection(st.session_state.df)
|
190 |
+
fig2d, fig3d = generate_plots(st.session_state.df_processed)
|
191 |
+
st.session_state.fig2d = fig2d
|
192 |
+
st.session_state.fig3d = fig3d
|
193 |
+
if fig2d:
|
194 |
+
st.plotly_chart(fig2d, use_container_width=True)
|
195 |
+
if fig3d:
|
196 |
+
st.plotly_chart(fig3d, use_container_width=True)
|
197 |
+
|
198 |
+
elif st.session_state.step == "stats":
|
199 |
+
st.subheader("Step 3: Statistic Analysis")
|
200 |
+
if st.session_state.df_processed is None:
|
201 |
+
st.error("Data has not been processed yet. Please complete the Data Visualization step first.")
|
202 |
+
else:
|
203 |
+
df_result = st.session_state.df_processed
|
204 |
+
anomaly_count = (df_result['anomaly'] == -1).sum()
|
205 |
+
total_count = df_result.shape[0]
|
206 |
+
st.session_state.summary_text = f"Total records: {total_count}\nDetected anomalies: {anomaly_count}"
|
207 |
+
st.markdown("**Anomaly Detection Summary:**")
|
208 |
+
st.text(st.session_state.summary_text)
|
209 |
+
st.markdown("**Detailed Data:**")
|
210 |
+
st.dataframe(df_result.head())
|
211 |
+
st.markdown("**Descriptive Statistics:**")
|
212 |
+
st.dataframe(df_result.describe())
|
213 |
+
|
214 |
+
elif st.session_state.step == "download":
|
215 |
+
st.subheader("Step 4: Download PDF Report")
|
216 |
+
if st.session_state.df_processed is None or (st.session_state.fig2d is None and st.session_state.fig3d is None):
|
217 |
+
st.error("Please complete the previous steps (Upload, Visualization, Statistic Analysis) before downloading the report.")
|
218 |
+
else:
|
219 |
+
pdf_data = generate_pdf_report(st.session_state.summary_text, st.session_state.fig2d, st.session_state.fig3d)
|
220 |
+
st.download_button("β¬οΈ Download PDF Report", data=pdf_data,
|
221 |
+
file_name="wifi_anomaly_report.pdf",
|
222 |
+
mime="application/pdf")
|