Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5a1e3bc
update dependencies
axelwalter Jul 3, 2024
cc4e1a0
update raw data viewer
axelwalter Jul 9, 2024
a551818
move captcha control to page_setup
axelwalter Jul 9, 2024
694becb
docs in one page
axelwalter Jul 9, 2024
3f0a089
rework multipage app
axelwalter Jul 9, 2024
f54f404
remove name-main in topp workflow to work with st.navigation
axelwalter Jul 9, 2024
0774086
update sidebar
axelwalter Jul 9, 2024
b8d2828
update TOPP workflow example
axelwalter Jul 10, 2024
a886fec
TOPP workflow start-stop button alignement
axelwalter Jul 10, 2024
1034a86
remove unused file
axelwalter Jul 10, 2024
d43264b
quickstart page
axelwalter Jul 10, 2024
eb17009
fallback mzML files for TOPP workflow example
axelwalter Jul 10, 2024
7eff2d6
use fragments in TOPP workflow
axelwalter Jul 10, 2024
ee6b68e
update quickstart page
axelwalter Jul 10, 2024
76082f8
pylint errors
axelwalter Jul 10, 2024
85b9a1e
rename pages directory due to streamlit warning
axelwalter Jul 10, 2024
f2dc41f
fix pages directory name in executable workflow
axelwalter Jul 11, 2024
3b4f8fb
fix file upload in TOPP workflow
axelwalter Jul 11, 2024
ceefccb
replace 0 and O in captcha
axelwalter Jul 11, 2024
ab90dfe
TOPP file upload
axelwalter Jul 11, 2024
60e2102
merge download section
axelwalter Jul 23, 2024
ceb19d0
sort result sets to show most recent first
axelwalter Jul 24, 2024
66bb5ca
Update content/documentation.py
axelwalter Jul 24, 2024
432e872
Update content/documentation.py
axelwalter Jul 24, 2024
bbedd94
move content of documentation pages to docs directory
axelwalter Jul 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-windows-executable-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ jobs:
mv python-${{ env.PYTHON_VERSION }} streamlit_exe
mv run_app.bat streamlit_exe
cp -r src streamlit_exe
cp -r pages streamlit_exe
cp -r content streamlit_exe
cp -r assets streamlit_exe
cp -r example-data streamlit_exe
cp -r .streamlit streamlit_exe
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ COPY app.py /app/app.py
COPY src/ /app/src
COPY assets/ /app/assets
COPY example-data/ /app/example-data
COPY pages/ /app/pages
COPY content/ /app/pages
# For streamlit configuration
COPY .streamlit/config.toml /app/.streamlit/config.toml
COPY clean-up-workspaces.py /app/clean-up-workspaces.py
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile_simple
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ COPY app.py /app/app.py
COPY src/ /app/src
COPY assets/ /app/assets
COPY example-data/ /app/example-data
COPY pages/ /app/pages
COPY content/ /app/pages
# For streamlit configuration
COPY .streamlit/config.toml /app/.streamlit/config.toml

Expand Down
108 changes: 23 additions & 85 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,87 +1,25 @@
"""
Main page for the OpenMS Template App.

This module sets up and displays the Streamlit app for the OpenMS Template App.
It includes:
- Setting the app title.
- Displaying a description.
- Providing a download button for the Windows version of the app.

Usage:
Run this script to launch the OpenMS Template App.

Note:
- If run in local mode, the CAPTCHA control is not applied.
- If not in local mode, CAPTCHA control is applied to verify the user.

Returns:
None
"""

import sys

from pathlib import Path
import streamlit as st
from pathlib import Path

from src.captcha_ import captcha_control
from src.common import page_setup, save_params

params = page_setup(page="main")


def main():
"""
Display main page content.
"""
st.title("OpenMS Streamlit Template App")
st.info("""
This repository contains a template app for OpenMS workflows in a web application using the **streamlit** framework. It serves as a foundation for apps ranging from simple workflows with **pyOpenMS** to complex workflows utilizing **OpenMS TOPP tools** with parallel execution. It includes solutions for handling user data and parameters in workspaces as well as deployment with docker-compose.
""")
st.subheader("Features")
st.markdown("""
- Workspaces for user data with unique shareable IDs
- Persistent parameters and input files within a workspace
- Captcha control
- Packaged executables for Windows
- framework for workflows with OpenMS TOPP tools
- Deployment [with docker-compose](https://github.com/OpenMS/streamlit-deployment)
""")
st.subheader("Quick Start")
if Path("OpenMS-App.zip").exists():
st.markdown("""
Download the latest version for Windows here by clicking the button below.
""")
with open("OpenMS-App.zip", "rb") as file:
st.download_button(
label="Download for Windows",
data=file,
file_name="OpenMS-App.zip",
mime="archive/zip",
type="primary",
)
st.markdown("""
Extract the zip file and run the executable (.exe) file to launch the app. Since every dependency is compressed and packacked the app will take a while to launch (up to one minute).
""")
st.markdown("""
Check out the documentation for **users** and **developers** is included as pages indicated by the 📖 icon

Try the example pages **📁 mzML file upload**, **👀 visualization** and **example workflows**.
""")
save_params(params)


# Check if the script is run in local mode (e.g., "streamlit run app.py local")
if "local" in sys.argv:
# In local mode, run the main function without applying captcha
main()

# If not in local mode, assume it's hosted/online mode
else:
# WORK LIKE MULTIPAGE APP
if "controllo" not in st.session_state or st.session_state["controllo"] is False:
# Apply captcha control to verify the user
captcha_control()

else:
# Run the main function
main()
pages = {
"OpenMS Web App" : [
st.Page(Path("content", "quickstart.py"), title="Quickstart", icon="👋"),
st.Page(Path("content", "documentation.py"), title="Documentation", icon="📖"),
],
"TOPP Workflow Framework": [
st.Page(Path("content", "topp_workflow.py"), title="TOPP Workflow", icon="🚀"),
],
"pyOpenMS Workflow" : [
st.Page(Path("content", "file_upload.py"), title="File Upload", icon="📂"),
st.Page(Path("content", "raw_data_viewer.py"), title="View MS data", icon="👀"),
st.Page(Path("content", "run_example_workflow.py"), title="Run Workflow", icon="⚙️"),
st.Page(Path("content", "download_section.py"), title="Download Results", icon="⬇️"),
],
"Others Topics": [
st.Page(Path("content", "simple_workflow.py"), title="Simple Workflow", icon="⚙️"),
st.Page(Path("content", "run_subprocess.py"), title="Run Subprocess", icon="🖥️"),
]
}

pg = st.navigation(pages)
pg.run()
1 change: 1 addition & 0 deletions content/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/*
109 changes: 109 additions & 0 deletions content/documentation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import streamlit as st
from src.common import page_setup
from pathlib import Path
from docs.toppframework import content as topp_framework_content

page_setup()


st.title("Documentation")

cols = st.columns(2)

pages = [
"User Guide",
"Installation",
"Developers Guide: How to build app based on this template",
"Developers Guide: TOPP Workflow Framework",
"Developer Guide: Windows Executables",
"Developers Guide: Deployment",
]
page = cols[0].selectbox(
"**Content**",
pages,
)

#############################################################################################
# User Guide
#############################################################################################

if page == pages[0]:
with open(Path("docs", "user_guide.md"), "r", encoding="utf-8") as f:
content = f.read()
st.markdown(content)

#############################################################################################
# Installation
#############################################################################################

if page == pages[1]:
if Path("OpenMS-App.zip").exists():
st.markdown(
"""
Download the latest version for **Windows** here clicking the button below.
"""
)
with open("OpenMS-App.zip", "rb") as file:
st.download_button(
label="Download for Windows",
data=file,
file_name="OpenMS-App.zip",
mime="archive/zip",
type="primary",
)
with open(Path("docs", "installation.md"), "r", encoding="utf-8") as f:
content = f.read()
st.markdown(content)

#############################################################################################
# Developer Overview, how to build app based on Template
#############################################################################################

if page == pages[2]:
with open(Path("docs", "build_app.md"), "r", encoding="utf-8") as f:
content = f.read()
st.markdown(content)

#############################################################################################
# TOPP Workflow Framework
#############################################################################################

if page == pages[3]:
topp_framework_content()

#############################################################################################
# Windows Executables
#############################################################################################

if page == pages[4]:
st.markdown(
"""
## 💻 How to package everything for Windows executables

This guide explains how to package OpenMS apps into Windows executables using two different methods:
"""
)

tabs = ["**embeddable Python**", "**PyInstaller**"]
tabs = st.tabs(tabs)

# window executable with embeddable python
with tabs[0]:
with open(Path("docs", "win_exe_with_embed_py.md"), "r", encoding="utf-8") as f:
content = f.read()
st.markdown(content)

# window executable with pyinstaller
with tabs[1]:
with open(Path("docs", "win_exe_with_pyinstaller.md"), "r", encoding="utf-8") as f:
content = f.read()
st.markdown(content)

#############################################################################################
# Deployment
#############################################################################################

if page == pages[5]:
with open(Path("docs", "deployment.md"), "r", encoding="utf-8") as f:
content = f.read()
st.markdown(content)
72 changes: 72 additions & 0 deletions content/download_section.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import streamlit as st

from pathlib import Path
import shutil

from src.common import page_setup
from zipfile import ZipFile, ZIP_DEFLATED

page_setup()

# Define output folder here; all subfolders will be handled as downloadable
# directories
output_folder = 'mzML-workflow-results'


# Generate full path
dirpath = Path(st.session_state["workspace"], output_folder)

# Detect downloadable content
if dirpath.exists():
directories = sorted(
[entry for entry in dirpath.iterdir() if not entry.is_file()]
)
else:
directories = []

# Show error if no content is available for download
if len(directories) == 0:
st.error('No results to show yet. Please run a workflow first!')
else:
# Table Header
columns = st.columns(3)
columns[0].write('**Run**')
columns[1].write('**Download**')
columns[2].write('**Delete Result Set**')

# Table Body
for i, directory in enumerate(directories):
st.divider()
columns = st.columns(3)
columns[0].empty().write(directory.name)

with columns[1]:
button_placeholder = st.empty()

# Show placeholder button before download is prepared
clicked = button_placeholder.button('Prepare Download', key=i, use_container_width=True)
if clicked:
button_placeholder.empty()
with st.spinner():
# Create ZIP file
out_zip = Path(dirpath, directory, 'output.zip')
if not out_zip.exists():
with ZipFile(out_zip, 'w', ZIP_DEFLATED) as zip_file:
for output in Path(dirpath, directory).iterdir():
try:
with open(Path(dirpath, directory, output), 'r') as f:
zip_file.writestr(output.name, f.read())
except:
continue
# Show download button after ZIP file was created
with open(out_zip, 'rb') as f:
button_placeholder.download_button(
"Download ⬇️", f,
file_name = f'{directory}.zip',
use_container_width=True
)

with columns[2]:
if st.button(f"🗑️ {directory.name}", use_container_width=True):
shutil.rmtree(directory)
st.rerun()
6 changes: 0 additions & 6 deletions pages/10_📁_File_Upload.py → content/file_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@
import streamlit as st
import pandas as pd

from src.captcha_ import captcha_control
from src.common import page_setup, save_params, v_space, show_table
from src import fileupload

params = page_setup()

# If run in hosted mode, show captcha as long as it has not been solved
if "controllo" not in st.session_state or params["controllo"] is False:
# Apply captcha by calling the captcha_control function
captcha_control()

st.title("File Upload")

tabs = ["File Upload", "Example Data"]
Expand Down
Loading