m0ksh commited on
Commit
94f3325
·
verified ·
1 Parent(s): ea9947a

Sync from GitHub (preserve manual model files)

Browse files
Files changed (1) hide show
  1. StreamlitApp/StreamlitApp.py +22 -45
StreamlitApp/StreamlitApp.py CHANGED
@@ -5,9 +5,7 @@ import matplotlib.pyplot as plt
5
  import matplotlib.patches as mpatches
6
  import torch
7
  import plotly.express as px
8
- import json
9
  import html as _html
10
- import streamlit.components.v1 as components
11
  from sklearn.manifold import TSNE
12
 
13
  # modular imports
@@ -52,9 +50,9 @@ def _tooltip_label(label: str, tooltip_text: str) -> None:
52
 
53
  def _try_copy_to_clipboard(text: str) -> None:
54
  """
55
- Best-effort clipboard copy.
56
- - If `pyperclip` is available, try server-side copy.
57
- - Also attempts browser-side copy using JS.
58
  """
59
  if pyperclip is not None:
60
  try:
@@ -62,24 +60,6 @@ def _try_copy_to_clipboard(text: str) -> None:
62
  except Exception:
63
  pass
64
 
65
- safe = json.dumps(text)
66
- # JS copy (browser-side). Clipboard access may be blocked by browser policies.
67
- components.html(
68
- f"""
69
- <script>
70
- (function() {{
71
- try {{
72
- const t = {safe};
73
- if (navigator.clipboard && navigator.clipboard.writeText) {{
74
- navigator.clipboard.writeText(t);
75
- }}
76
- }} catch (e) {{}}
77
- }})();
78
- </script>
79
- """,
80
- height=0,
81
- )
82
-
83
  # APP CONFIG
84
  st.set_page_config(page_title="AMP Predictor", layout="wide")
85
 
@@ -161,7 +141,7 @@ model = load_model()
161
 
162
  # PREDICT PAGE
163
  if page == "Predict":
164
- st.header("AMP Prediction")
165
 
166
  preset_cols = st.columns(2)
167
  with preset_cols[0]:
@@ -243,9 +223,9 @@ if page == "Predict":
243
  _try_copy_to_clipboard(seq)
244
  toast_fn = getattr(st, "toast", None)
245
  if toast_fn is not None:
246
- toast_fn("Copied to clipboard")
247
  else:
248
- st.success("Copied to clipboard")
249
  label = top_candidate.get("Prediction", "")
250
  conf_str = format_conf_percent(top_candidate["predicted_confidence"], digits=1)
251
  st.write(f"**{label} with {conf_str} confidence**")
@@ -259,7 +239,7 @@ if page == "Predict":
259
 
260
  # ANALYZE PAGE
261
  elif page == "Analyze":
262
- st.header("Sequence Analysis")
263
 
264
  # show the last saved analyze output if user navigated back
265
  last_seq = st.session_state.analyze_input
@@ -511,25 +491,27 @@ elif page == "Analyze":
511
 
512
  # OPTIMIZE PAGE
513
  elif page == "Optimize":
514
- st.header("AMP Sequence Optimizer")
515
 
516
- # Single entry point: text input retained across navigation
517
- seq = st.text_input(
518
- "Enter a peptide sequence to optimize:",
519
- value=st.session_state.get("optimize_input", ""),
520
- )
 
 
521
 
522
- warn_opt = sequence_length_warning(seq)
523
  if warn_opt:
524
  st.caption(f"Warning: {warn_opt}")
525
 
526
- # Run optimization when user changes input and clicks button
527
- if seq and st.button("Run Optimization"):
528
  st.session_state.optimize_input = seq
529
  progress = st.progress(0.0, text="Optimizing...")
530
  with st.spinner("Optimizing sequence..."):
531
  improved_seq, improved_conf, history = optimize_sequence(seq, model)
532
- orig_label, orig_conf = predict_amp(seq, model)
533
  st.session_state.optimize_output = (seq, orig_conf, improved_seq, improved_conf, history)
534
  progress.progress(1.0, text="Optimization complete")
535
  st.success("Optimization finished.")
@@ -587,7 +569,7 @@ elif page == "Optimize":
587
 
588
  # VISUALIZE PEPTIDE PAGE
589
  elif page == "Visualize Peptide":
590
- st.header("Visualize Peptide")
591
  # Tighter legend expanders (summary row + scrollable body)
592
  st.markdown(
593
  """
@@ -605,15 +587,11 @@ elif page == "Visualize Peptide":
605
  """,
606
  unsafe_allow_html=True,
607
  )
608
- st.caption(
609
- "High-impact single-sequence view. **Blue / red / green / gray** match the 3D model, helical wheel, "
610
- "and functional residue map."
611
- )
612
 
613
  st.checkbox("Auto-run when sequence changes", value=False, key="viz_peptide_auto_run")
614
 
615
  st.text_input(
616
- "Peptide sequence",
617
  key="visualize_peptide_input",
618
  placeholder="Paste or type a one-letter amino-acid sequence",
619
  )
@@ -622,7 +600,6 @@ elif page == "Visualize Peptide":
622
  clean_viz = "".join(c for c in seq_viz.upper() if not c.isspace())
623
  if not clean_viz:
624
  st.session_state.viz_peptide_last_computed = ""
625
- st.info("Enter a sequence above, then click **Run visualization** (or enable **Auto-run**).")
626
  else:
627
  run_viz = st.button("Run visualization", type="primary", key="viz_peptide_run_btn")
628
  auto_on = bool(st.session_state.get("viz_peptide_auto_run"))
@@ -683,7 +660,7 @@ elif page == "Visualize Peptide":
683
 
684
  # VISUALIZE t-SNE PAGE
685
  elif page == "Visualize t-SNE":
686
- st.header("Visualize t-SNE")
687
  st.write("Upload peptide sequences (FASTA or plain list) to embed sequences and explore clusters with t-SNE.")
688
 
689
  uploaded_file = st.file_uploader("Upload FASTA or text file", type=["txt", "fasta"])
 
5
  import matplotlib.patches as mpatches
6
  import torch
7
  import plotly.express as px
 
8
  import html as _html
 
9
  from sklearn.manifold import TSNE
10
 
11
  # modular imports
 
50
 
51
  def _try_copy_to_clipboard(text: str) -> None:
52
  """
53
+ Best-effort clipboard copy (server-side only).
54
+ Avoids streamlit.components.html iframe/JS can fail on Hugging Face Spaces
55
+ (TypeError: Failed to fetch dynamically imported module for static/js chunks).
56
  """
57
  if pyperclip is not None:
58
  try:
 
60
  except Exception:
61
  pass
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  # APP CONFIG
64
  st.set_page_config(page_title="AMP Predictor", layout="wide")
65
 
 
141
 
142
  # PREDICT PAGE
143
  if page == "Predict":
144
+ st.header("AMP Predictor")
145
 
146
  preset_cols = st.columns(2)
147
  with preset_cols[0]:
 
223
  _try_copy_to_clipboard(seq)
224
  toast_fn = getattr(st, "toast", None)
225
  if toast_fn is not None:
226
+ toast_fn("Copied or select the sequence above (Ctrl+C)")
227
  else:
228
+ st.success("Copied or select the sequence above (Ctrl+C)")
229
  label = top_candidate.get("Prediction", "")
230
  conf_str = format_conf_percent(top_candidate["predicted_confidence"], digits=1)
231
  st.write(f"**{label} with {conf_str} confidence**")
 
239
 
240
  # ANALYZE PAGE
241
  elif page == "Analyze":
242
+ st.header("Peptide Analyzer")
243
 
244
  # show the last saved analyze output if user navigated back
245
  last_seq = st.session_state.analyze_input
 
491
 
492
  # OPTIMIZE PAGE
493
  elif page == "Optimize":
494
+ st.header("Peptide Optimizer")
495
 
496
+ # Form: Enter in the text field submits the form (same as clicking Run Optimization).
497
+ with st.form("optimize_form", clear_on_submit=False):
498
+ seq = st.text_input(
499
+ "Enter a peptide sequence to optimize:",
500
+ value=st.session_state.get("optimize_input", ""),
501
+ )
502
+ submitted = st.form_submit_button("Run Optimization")
503
 
504
+ warn_opt = sequence_length_warning(seq) if seq else None
505
  if warn_opt:
506
  st.caption(f"Warning: {warn_opt}")
507
 
508
+ if submitted and seq and str(seq).strip():
509
+ seq = str(seq).strip()
510
  st.session_state.optimize_input = seq
511
  progress = st.progress(0.0, text="Optimizing...")
512
  with st.spinner("Optimizing sequence..."):
513
  improved_seq, improved_conf, history = optimize_sequence(seq, model)
514
+ _ol, orig_conf = predict_amp(seq, model)
515
  st.session_state.optimize_output = (seq, orig_conf, improved_seq, improved_conf, history)
516
  progress.progress(1.0, text="Optimization complete")
517
  st.success("Optimization finished.")
 
569
 
570
  # VISUALIZE PEPTIDE PAGE
571
  elif page == "Visualize Peptide":
572
+ st.header("Peptide Visualizer")
573
  # Tighter legend expanders (summary row + scrollable body)
574
  st.markdown(
575
  """
 
587
  """,
588
  unsafe_allow_html=True,
589
  )
 
 
 
 
590
 
591
  st.checkbox("Auto-run when sequence changes", value=False, key="viz_peptide_auto_run")
592
 
593
  st.text_input(
594
+ "Enter a peptide sequence to visualize:",
595
  key="visualize_peptide_input",
596
  placeholder="Paste or type a one-letter amino-acid sequence",
597
  )
 
600
  clean_viz = "".join(c for c in seq_viz.upper() if not c.isspace())
601
  if not clean_viz:
602
  st.session_state.viz_peptide_last_computed = ""
 
603
  else:
604
  run_viz = st.button("Run visualization", type="primary", key="viz_peptide_run_btn")
605
  auto_on = bool(st.session_state.get("viz_peptide_auto_run"))
 
660
 
661
  # VISUALIZE t-SNE PAGE
662
  elif page == "Visualize t-SNE":
663
+ st.header("t-SNE Visualizer")
664
  st.write("Upload peptide sequences (FASTA or plain list) to embed sequences and explore clusters with t-SNE.")
665
 
666
  uploaded_file = st.file_uploader("Upload FASTA or text file", type=["txt", "fasta"])