Canstralian commited on
Commit
9a084f0
1 Parent(s): ab9047c

Fix Streamlit duplicate element ID error and enhance CyberOps Dashboard with graphical navigation

Browse files

Resolved the StreamlitDuplicateElementId error by assigning unique keys to each file_uploader and other Streamlit elements.
- Added unique keys to all file_uploader elements to ensure distinct identifiers.
- Added an introductory section on the main frame to describe the purpose of the application.
- Introduced a graphical navigation system using Streamlit buttons within columns for better user experience.
- Data Upload: Allows users to upload CSV files.
- Data Visualization: Enables users to select columns for plotting.
- Analysis Tools: Provides options for combinatorial analysis.
- Maintained core functionality including file upload, data visualization, combinatorial analysis, and grouping/aggregation.
- Ensured compatibility with larger datasets using Dask for efficient data processing.
- Updated the sidebar to support new navigation features and options.
- Improved the user experience by providing a more reliable and error-free navigation system.

Files changed (1) hide show
  1. app.py +98 -7
app.py CHANGED
@@ -1,9 +1,100 @@
1
- StreamlitDuplicateElementId: There are multiple file_uploader elements with the same auto-generated ID. When this element is created, it is assigned an internal ID based on the element type and provided parameters. Multiple elements with the same type and parameters will cause this error.
 
 
 
 
 
 
 
2
 
3
- To fix this error, please pass a unique key argument to the file_uploader element.
 
4
 
5
- Traceback:
6
- File "/home/user/app/app.py", line 101, in <module>
7
- main()
8
- File "/home/user/app/app.py", line 45, in main
9
- st.sidebar.file_uploader("Select a CSV file:", type=["csv"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ import pandas as pd
4
+ import matplotlib.pyplot as plt
5
+ import dask.dataframe as dd
6
+ from dotenv import load_dotenv
7
+ from itertools import combinations
8
+ from collections import defaultdict
9
 
10
+ # Load environment variables
11
+ load_dotenv()
12
 
13
+ # Configuration from environment variables
14
+ FILE_UPLOAD_LIMIT = int(os.getenv('FILE_UPLOAD_LIMIT', 200))
15
+ EXECUTION_TIME_LIMIT = int(os.getenv('EXECUTION_TIME_LIMIT', 300))
16
+ RESOURCE_LIMIT = int(os.getenv('RESOURCE_LIMIT', 1024)) # in MB
17
+ DATA_DIR = os.getenv('DATA_DIR', './data')
18
+ CONFIG_FLAG = os.getenv('CONFIG_FLAG', 'default')
19
+
20
+ # Main application logic
21
+ def main():
22
+ st.title("CyberOps Dashboard")
23
+
24
+ # Sidebar for user inputs
25
+ st.sidebar.header("Options")
26
+
27
+ # Main frame for introduction and navigation
28
+ with st.container():
29
+ st.subheader("Welcome to CyberOps Dashboard")
30
+ st.write("""
31
+ The CyberOps Dashboard is designed to assist cybersecurity professionals in analyzing and visualizing data efficiently.
32
+ With this tool, you can upload CSV files, visualize data trends, and perform advanced data analysis.
33
+ """)
34
+
35
+ # Navigation section
36
+ st.subheader("Navigation")
37
+ st.write("Use the buttons below to navigate to different sections:")
38
+ col1, col2, col3 = st.columns(3)
39
+
40
+ with col1:
41
+ if st.button("Data Upload"):
42
+ uploaded_file = st.sidebar.file_uploader("Select a CSV file:", type=["csv"], key="file_uploader_data_upload")
43
+
44
+ with col2:
45
+ if st.button("Data Visualization"):
46
+ st.sidebar.selectbox('Select X-axis:', [], key="data_visualization_x")
47
+ st.sidebar.selectbox('Select Y-axis:', [], key="data_visualization_y")
48
+
49
+ with col3:
50
+ if st.button("Analysis Tools"):
51
+ st.sidebar.multiselect('Select columns for combinations:', [], key="analysis_tools_columns")
52
+
53
+ uploaded_file = st.sidebar.file_uploader("Select a CSV file:", type=["csv"], key="file_uploader_main")
54
+
55
+ if uploaded_file:
56
+ @st.cache_data
57
+ def load_csv(file):
58
+ return pd.read_csv(file)
59
+
60
+ @st.cache_data
61
+ def load_dask_csv(file):
62
+ return dd.read_csv(file)
63
+
64
+ if os.path.getsize(uploaded_file) < RESOURCE_LIMIT * 1024 * 1024:
65
+ df = load_csv(uploaded_file)
66
+ else:
67
+ df = load_dask_csv(uploaded_file)
68
+
69
+ if not df.empty:
70
+ st.write("Data Preview:")
71
+ st.dataframe(df.compute() if isinstance(df, dd.DataFrame) else df)
72
+
73
+ # Select columns for plotting
74
+ x_column = st.sidebar.selectbox('Select X-axis:', df.columns, key="x_column_plot")
75
+ y_column = st.sidebar.selectbox('Select Y-axis:', df.columns, key="y_column_plot")
76
+
77
+ # Plotting
78
+ fig, ax = plt.subplots()
79
+ ax.plot(df[x_column], df[y_column], marker='o')
80
+ ax.set_xlabel(x_column)
81
+ ax.set_ylabel(y_column)
82
+ ax.set_title(f"{y_column} vs {x_column}")
83
+ st.pyplot(fig)
84
+
85
+ # Combinatorial analysis
86
+ col_combinations = st.sidebar.multiselect('Select columns for combinations:', df.columns, key="col_combinations")
87
+ if col_combinations:
88
+ st.write("Column Combinations:")
89
+ comb = list(combinations(col_combinations, 2))
90
+ st.write(comb)
91
+
92
+ # Grouping and aggregation
93
+ group_by_column = st.sidebar.selectbox('Select column to group by:', df.columns, key="group_by_column")
94
+ if group_by_column:
95
+ grouped_df = df.groupby(group_by_column).agg(list)
96
+ st.write("Grouped Data:")
97
+ st.dataframe(grouped_df.compute() if isinstance(grouped_df, dd.DataFrame) else grouped_df)
98
+
99
+ if __name__ == "__main__":
100
+ main()