Romain Graux commited on
Commit
c20d7c1
1 Parent(s): 55a3ffc

Fix user access to workdir in docker + rearange app with example import

Browse files
Files changed (3) hide show
  1. Dockerfile +3 -1
  2. app.py +96 -53
  3. examples/sabatier.csv +13 -0
Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM python:3.11
2
 
3
  RUN useradd -m -u 1000 user
4
  WORKDIR /app
@@ -11,6 +11,8 @@ RUN pip install --no-cache-dir --upgrade -e /app/spock
11
 
12
  COPY --chown=user . /app
13
 
 
 
14
  USER user
15
  EXPOSE 8501
16
  CMD ["streamlit", "run", "/app/app.py", "--server.port", "8501", "--server.enableXsrfProtection", "false"]
 
1
+ FROM python:3.11-slim
2
 
3
  RUN useradd -m -u 1000 user
4
  WORKDIR /app
 
11
 
12
  COPY --chown=user . /app
13
 
14
+ RUN chown -R user:user /app && chmod -R 755 /app
15
+
16
  USER user
17
  EXPOSE 8501
18
  CMD ["streamlit", "run", "/app/app.py", "--server.port", "8501", "--server.enableXsrfProtection", "false"]
app.py CHANGED
@@ -25,12 +25,24 @@ def check_columns(df: pd.DataFrame) -> None:
25
 
26
  # Cache the function to run spock with the provided dataframe and arguments
27
  @st.cache_data(
28
- show_spinner=False, hash_funcs={pd.DataFrame: lambda df: df.to_numpy().tobytes()}
 
29
  )
30
- def run_fn(df, *args, **kwargs) -> str:
31
- check_columns(df)
32
- fig, ax = run_spock_from_args(df, *args, **kwargs)
33
- return fig
 
 
 
 
 
 
 
 
 
 
 
34
 
35
 
36
  # Mock function for testing purposes
@@ -73,11 +85,67 @@ def capture_stdout_with_timestamp():
73
  sys.stdout = old_stdout
74
 
75
 
76
- # Main function to run the Streamlit app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  def main():
78
  st.title("Navicat Spock")
79
- st.subheader("A tool for generating volcano plots from your data")
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  with st.sidebar:
82
  st.header("Settings")
83
 
@@ -123,52 +191,27 @@ def main():
123
  prefit = st.toggle("Prefit", value=False)
124
  setcbms = st.toggle("CBMS", value=True)
125
 
126
- with st.expander("Instructions"):
127
- st.markdown(
128
- """
129
- 1. Upload your data in an Excel or CSV file.
130
- 2. View and curate your data in the table below.
131
- 3. Click "Run Plot" to generate your plot.
132
- 4. View the generated plot and all the associated logs in the respective tabs.
133
- """
134
- )
135
-
136
- uploaded_file = st.file_uploader(
137
- "Choose a file", type=["csv", "xlsx"], accept_multiple_files=False
138
- )
139
-
140
- if uploaded_file is not None:
141
- try:
142
- df = load_data(uploaded_file)
143
- st.markdown("### Data")
144
- st.dataframe(df, use_container_width=True)
145
-
146
- if st.button("Run Plot"):
147
- with st.spinner("Generating plot..."):
148
- with capture_stdout_with_timestamp() as stdout_io:
149
- result = run_fn(
150
- df,
151
- wp=wp,
152
- verb=verb,
153
- imputer_strat=imputer_strat,
154
- plotmode=plotmode,
155
- seed=seed,
156
- prefit=prefit,
157
- setcbms=setcbms,
158
- fig=None,
159
- ax=None,
160
- )
161
-
162
- st.markdown("### Result")
163
- plot, logs = st.tabs(["Plot", "Logs"])
164
- with plot:
165
- st.pyplot(result)
166
- with logs:
167
- st.code(stdout_io.getvalue(), language="bash")
168
- except Exception as e:
169
- st.toast(f":red[{e}]", icon="🚨")
170
- else:
171
- st.write("Please first upload a file to generate the volcano plot.")
172
 
173
 
174
  if __name__ == "__main__":
 
25
 
26
  # Cache the function to run spock with the provided dataframe and arguments
27
  @st.cache_data(
28
+ show_spinner=False,
29
+ # hash_funcs={pd.DataFrame: lambda df: df.to_numpy().tobytes()},
30
  )
31
+ def cached_run_fn(df, wp, verb, imputer_strat, plotmode, seed, prefit, setcbms):
32
+ with capture_stdout_with_timestamp() as stdout_io:
33
+ fig, _ = run_spock_from_args(
34
+ df,
35
+ wp=wp,
36
+ verb=verb,
37
+ imputer_strat=imputer_strat,
38
+ plotmode=plotmode,
39
+ seed=seed,
40
+ prefit=prefit,
41
+ setcbms=setcbms,
42
+ fig=None,
43
+ ax=None,
44
+ )
45
+ return fig, stdout_io.getvalue()
46
 
47
 
48
  # Mock function for testing purposes
 
85
  sys.stdout = old_stdout
86
 
87
 
88
+ @st.experimental_dialog("Import Data")
89
+ def import_data():
90
+ st.write("Choose a dataset or upload your own file")
91
+
92
+ option = st.radio("Select an option:", ["Use example dataset", "Upload file"])
93
+
94
+ if option == "Use example dataset":
95
+ examples = {
96
+ "Sabatier": "examples/sabatier.csv",
97
+ # Add more examples here
98
+ }
99
+ selected_example = st.selectbox(
100
+ "Choose an example dataset", list(examples.keys())
101
+ )
102
+ if st.button("Load Example"):
103
+ df = pd.read_csv(examples[selected_example])
104
+ st.session_state.df = df
105
+ st.rerun()
106
+ else:
107
+ uploaded_file = st.file_uploader(
108
+ "Upload a CSV or Excel file", type=["csv", "xlsx"]
109
+ )
110
+ if uploaded_file is not None:
111
+ try:
112
+ df = load_data(uploaded_file)
113
+ st.session_state.df = df
114
+ st.rerun()
115
+ except Exception as e:
116
+ st.error(f"Error loading file: {e}")
117
+
118
+
119
  def main():
120
  st.title("Navicat Spock")
121
+ st.subheader("Generate volcano plots from your data")
122
 
123
+ # Instructions
124
+ with st.expander("Instructions", expanded=False):
125
+ st.markdown(
126
+ """
127
+ 1. Click "Import Data" to upload a file or select an example dataset.
128
+ 2. Review your data in the table.
129
+ 3. Adjust the plot settings in the sidebar if needed.
130
+ 4. Click "Generate plot" to create your plot.
131
+ 5. View the generated plot and logs in the respective tabs.
132
+ """
133
+ )
134
+
135
+ if "df" not in st.session_state:
136
+ if st.button("Import Data"):
137
+ import_data()
138
+ st.stop()
139
+
140
+ # Display the data
141
+ st.header("Review the data")
142
+ st.dataframe(st.session_state.df, use_container_width=True)
143
+
144
+ # Option to import new data
145
+ if st.button("Import New Data"):
146
+ import_data()
147
+
148
+ # Settings
149
  with st.sidebar:
150
  st.header("Settings")
151
 
 
191
  prefit = st.toggle("Prefit", value=False)
192
  setcbms = st.toggle("CBMS", value=True)
193
 
194
+ # Run the plot
195
+ st.header("Generate plot")
196
+ if st.button("Generate plot"):
197
+ with st.spinner("Generating plot..."):
198
+ fig, logs = cached_run_fn(
199
+ st.session_state.df,
200
+ wp=wp,
201
+ verb=verb,
202
+ imputer_strat=imputer_strat,
203
+ plotmode=plotmode,
204
+ seed=seed,
205
+ prefit=prefit,
206
+ setcbms=setcbms,
207
+ )
208
+
209
+ st.header("Results")
210
+ plot, logs_tab = st.tabs(["Plot", "Logs"])
211
+ with plot:
212
+ st.pyplot(fig)
213
+ with logs_tab:
214
+ st.code(logs, language="bash")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
 
217
  if __name__ == "__main__":
examples/sabatier.csv ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Name, Target Tr, Formate absorption energy
2
+ Au, -521.0658764317129, 61.93145025361211
3
+ Ag, -478.9149164687159, 70.98450104659094
4
+ Pd, -398.488126876612, 78.02480459716048
5
+ Pt, -350.5432865307274, 76.28315184584147
6
+ Ir, -355.8146554089544, 78.23208447987959
7
+ Ru, -389.43687919910315, 82.21257947427425
8
+ Rh, -410.6834591594346, 79.20231739536051
9
+ Cu, -431.11863715829, 90.03245607845905
10
+ Ni, -467.6544603588984, 99.94739606607243
11
+ Co, -487.76037379367654, 100.16204520332087
12
+ Fe, -500.25282814741644, 102.91877356789514
13
+ W, -526.4313208996762, 106.91337990075026