diff --git a/.github/workflows/python-package-ci.yml b/.github/workflows/python-package-ci.yml index 79664ed..2ab2f72 100644 --- a/.github/workflows/python-package-ci.yml +++ b/.github/workflows/python-package-ci.yml @@ -24,7 +24,7 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install flake8 pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + if [ -f requirements.txt ]; then pip install --no-cache-dir -r requirements.txt; fi - name: Verify Streamlit app run: | timeout 10s streamlit run index.py || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5f3148 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.nf-env diff --git a/requirements.txt b/requirements.txt index 8639f6b..61d1f56 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ pandas==2.2.3 -paramiko==3.5.0 +paramiko>3.5.0 streamlit==1.39.0 pre-commit==4.0.1 +pyalma @ git+https://github.com/ICR-RSE-Group/pyalma.git@main diff --git a/shared/ssh.py b/shared/ssh.py deleted file mode 100644 index 2f70114..0000000 --- a/shared/ssh.py +++ /dev/null @@ -1,41 +0,0 @@ -import os -import sys - -import pandas as pd -import paramiko - -dir_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(dir_path) -__file__ - - -class SshConnection: - def __init__(self, source, username, password, server="alma.icr.ac.uk"): - self.source = source.strip() - self.server = server.strip() - self.username = username.strip() - self.password = password.strip() - - def run_cmd(self, cmd, string=True): - if self.source == "local": - return self.run_local(cmd) - else: - try: - with paramiko.SSHClient() as client: - client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - client.connect(self.server, username=self.username, password=self.password) - stdin, stdout, stderr = client.exec_command(cmd, get_pty=True) - err_str = stderr.read().decode("ascii") - - if string: - out_str = stdout.read().decode("ascii") - return out_str, err_str - - else: - from io import BytesIO - - df = pd.read_csv(BytesIO(stdout.read()), sep="|") - return df, err_str - - except Exception as e: - return "", str(e) diff --git a/tabs/tab_command.py b/tabs/tab_command.py index 9697976..3499b1c 100644 --- a/tabs/tab_command.py +++ b/tabs/tab_command.py @@ -1,13 +1,13 @@ -import datetime from contextlib import contextmanager, redirect_stdout from io import StringIO -import pandas as pd import streamlit as st # Initialize session state variables if "run_pipeline_clicked" not in st.session_state: st.session_state.run_pipeline_clicked = False +if "check_queue" not in st.session_state: + st.session_state.check_queue = False @contextmanager @@ -77,22 +77,24 @@ def run_nextflow(): # username, MY_SSH, selected_pipeline, selected_project): ) # develop this st.write("Command used:") st.code(cmd_pipeline) - out_str, err_str = MY_SSH.run_cmd(cmd_pipeline, string=True) + _dict = MY_SSH.run_cmd(cmd_pipeline) def check_queue(): # username): + st.session_state.check_queue = True + + if st.session_state.check_queue: cmd_pipeline = pipe_cmd(username, None, None, cmd_num=1) st.write("Command used:") st.code(cmd_pipeline) - out_str, err_str = MY_SSH.run_cmd(cmd_pipeline, string=True) - if err_str == "": + _dict = MY_SSH.run_cmd(cmd_pipeline) + if _dict["err"] == None: st.write("Output:") - st.code(out_str) + st.code(_dict["output"]) st.write( "If you see '***' job on compute node, that suggests that the job has been sent to the cluster (in the queue (PD) or running (R))" ) - else: - st.error(err_str) + st.error(_dict["err"]) left_column, right_column = st.columns(2) # disable button once the user click a first time. by default it gets disabled after calling the callback diff --git a/tabs/tab_logon.py b/tabs/tab_logon.py index 046f5a1..e63f8d7 100644 --- a/tabs/tab_logon.py +++ b/tabs/tab_logon.py @@ -2,8 +2,7 @@ from io import StringIO import streamlit as st - -import shared.ssh as ssh +from pyalma import LocalFileReader, SshClient @contextmanager @@ -41,21 +40,17 @@ def tab(): OK = True else: with st.spinner("Validating login"): - MY_SSH = ssh.SshConnection("remote", username, password, server=server) - + MY_SSH = SshClient(server, username, password) print("Validating login...") - cmd = "cd ~ && ls -l1" - results_str, error_str = MY_SSH.run_cmd(cmd) - - if error_str: - print("Errors", error_str) - else: - print("Session validated successfully") - OK = error_str == "" + _dict = MY_SSH.run_cmd("cd ~ &ls -l") + OK = _dict["err"] is None if OK: + print("Session validated successfully") st.success("Session validated successfully") else: - st.error("Correct login details and try again") + print("Errors", _dict["err"]) + err_msg = "Connection failed: " + _dict["err"] + st.error(err_msg) return OK, MY_SSH, username diff --git a/views/login.py b/views/login.py index 92e1c4b..5793070 100644 --- a/views/login.py +++ b/views/login.py @@ -5,11 +5,9 @@ import tabs.tab_logon as tl header = """ - - icr -🍃 RUN-NEXTFLOWRUN NEXTFLOW on ALMA🍃- """ st.markdown(header, unsafe_allow_html=True) diff --git a/views/run_pipeline.py b/views/run_pipeline.py index 1b770ac..a661370 100644 --- a/views/run_pipeline.py +++ b/views/run_pipeline.py @@ -16,11 +16,9 @@ def reset_button_state(): header = """ - - icr -🍃 RUN-NEXTFLOWRUN NEXTFLOW on ALMA🍃- """ st.markdown(header, unsafe_allow_html=True)