Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,32 @@ The sanity checks implemented are based on experience and the bcl2fastq document

# Local instance

git clone https://github.com/sequana/webapp_samplesheet check_my_sample_sheet
cd check_my_sample_sheet
## Using local python

# You will need to install requirements (sequana and streamlit)
pip install --file requirements.txt
If you'd like to run a local instance, you could either install streamlit and run it directly (python virtual environment is highly recommended):

# and should ne ready to test the appliction locally in your browser
streamlit run app.py
```bash
git clone https://github.com/sequana/webapp_samplesheet check_my_sample_sheet
cd check_my_sample_sheet/app
pip install -r requirements.txt
python -m streamlit run app.py
```

## Using singularity

Or if you'd like to run an instance on a web server, there is a singularity definition file (requires singularity and docker to build, only singularity to run):

```bash
git clone https://github.com/sequana/webapp_samplesheet check_my_sample_sheet
singularity build --build-arg SERVER_ADDRESS=127.0.0.1 --fakeroot sample_sheet_validator_1.0.0.sif samplesheet_validator.def
```

You can change the IP address you're listening to to suit your needs, and then run an instance of the app:

```bash
singularity instance start sample_sheet_validator_1.0.0.sif samplesheet_validatord
```

Please note: if using singularity, make sure that both `/tmp` and `$HOME` are writable. You can either set `mount tmp = yes` and `mount home = yes` in `/etc/singularity/singularity.conf`, or you can set the binds manually.

By default, the app will be served on port 8501, so if you'd like to redirect http traffic through a reverse proxy, you can specify the IP address and port 8501 as the target.
52 changes: 37 additions & 15 deletions app.py → app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@

import requests
import streamlit as st
from sequana.iem import SampleSheet
from samplesheet import SampleSheet
from streamlit_option_menu import option_menu

st.set_page_config(
page_title="Illumina Sample Sheet Validator",
page_icon="imgs/logo_256x256.png",
layout="wide",
menu_items={"Report a bug": "https://github.com/sequana/webapp_samplesheet/issues/new/choose"},
menu_items={
"Report a bug": "https://github.com/sequana/webapp_samplesheet/issues/new/choose"
},
)

version = "1.0.0"
Expand Down Expand Up @@ -104,7 +106,9 @@ def add_legend(success, warning, error):
error = counter["Error"] / S * 100

completed = min(round(100 * (S / float(N))), 100)
bar_placeholder.markdown(colored_bar(success, warning, error, completed), unsafe_allow_html=True)
bar_placeholder.markdown(
colored_bar(success, warning, error, completed), unsafe_allow_html=True
)

# finally add the legend
_, col2, _ = st.columns([1, 4, 1])
Expand All @@ -126,7 +130,9 @@ def add_legend(success, warning, error):


def main():
st.sidebar.write("Provided by the [Sequana teams](https://github.com/sequana/sequana)")
st.sidebar.write(
"Provided by the [Sequana teams](https://github.com/sequana/sequana)"
)
st.sidebar.image("imgs/logo_256x256.png")
st.title(f"Sample Sheet and Design Validator (v{version})")

Expand All @@ -135,7 +141,11 @@ def main():
# 1. as sidebar menu
with st.sidebar:
choice = option_menu(
"Main Menu", menu, icons=["gear", "gear", "cloud-upload", ""], menu_icon="cast", default_index=0
"Main Menu",
menu,
icons=["gear", "gear", "cloud-upload", ""],
menu_icon="cast",
default_index=0,
)

if choice == "Sample Sheet Validation (Illumina)":
Expand All @@ -149,15 +159,21 @@ def main():
col1, col2, col3 = st.columns([4, 1, 4])
with col1:
data_file = st.file_uploader(
"Drop a sample sheet below and press the **Process** button. ", type=["csv", "txt"]
"Drop a sample sheet below and press the **Process** button. ",
type=["csv", "txt"],
)
with col2:
# Centered "OR" text
st.markdown("<div style='text-align: center;'><br><br>OR</div>", unsafe_allow_html=True)
st.markdown(
"<div style='text-align: center;'><br><br>OR</div>",
unsafe_allow_html=True,
)

with col3:
code = st.text_area(
"Paste your code here and press the **Process** button.", value=st.session_state.code, key="code_area"
"Paste your code here and press the **Process** button.",
value=st.session_state.code,
key="code_area",
)

if st.button(":gear: Process :gear:"):
Expand Down Expand Up @@ -216,9 +232,7 @@ def main():
st.code(data, language="bash")

st.subheader("3 - [Data] section with single-index and a [Settings] section")
url = (
"https://raw.githubusercontent.com/sequana/webapp_samplesheet/main/examples/sample_sheet_settings_index.csv"
)
url = "https://raw.githubusercontent.com/sequana/webapp_samplesheet/main/examples/sample_sheet_settings_index.csv"
r = requests.get(url, allow_redirects=True)
data = r.content.decode()
st.code(data, language="bash")
Expand All @@ -229,7 +243,9 @@ def main():
data = r.content.decode()
st.code(data, language="bash")

st.subheader("5 - Example of an erroneous sample sheet (extra semicolons at the end)")
st.subheader(
"5 - Example of an erroneous sample sheet (extra semicolons at the end)"
)
url = "https://raw.githubusercontent.com/sequana/webapp_samplesheet/main/examples/Bad_SampleSheet_extra_semicolons.csv"
r = requests.get(url, allow_redirects=True)
data = r.content.decode()
Expand All @@ -249,7 +265,9 @@ def main():
)
else:
st.subheader("How to cite ? ")
st.info("Check My Sample Sheet application (this website):\n\nLemée L. et al [researchsquare](https://www.researchsquare.com/article/rs-5268893/v1)")
st.info(
"Check My Sample Sheet application (this website):\n\nLemée L. et al [researchsquare](https://www.researchsquare.com/article/rs-5268893/v1)"
)

st.info(
"The Sequana application to check the sample sheet: \n\nCokelaer T. et al, (2017), 'Sequana': a Set of Snakemake NGS pipelines, Journal of Open Source Software, 2(16), 352, JOSS DOI [doi:10.21105/joss.00352](https://joss.theoj.org/papers/10.21105/joss.00352)"
Expand All @@ -272,11 +290,15 @@ def process_sample_sheet(data_file, samplesheet):
None
"""
if data_file is not None:
file_details = {"Filename": data_file.name, "FileType": data_file.type, "FileSize": data_file.size}
file_details = {
"Filename": data_file.name,
"FileType": data_file.type,
"FileSize": data_file.size,
}
else:
pass

if 1 == 1:
if True:

# read to save locally
# samplesheet = data_file.read().decode()
Expand Down
58 changes: 58 additions & 0 deletions app/checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#
# This file is part of Sequana software
#
# Copyright (c) 2018-2022 - Sequana Development Team
#
# Distributed under the terms of the 3-clause BSD license.
# The full license is in the LICENSE file, distributed with this software.
#
# website: https://github.com/sequana/sequana
# documentation: http://sequana.readthedocs.io
#
##############################################################################

import colorlog

logger = colorlog.getLogger(__name__)


class Checker:
"""Utility to hold checks


The method :meth:`~sequana.utils.checks.Checke./tryme` calls the method or function
provided. This method is expected to return a dictionary
with 2 keys called status and msg. Status should be
in 'Error', 'Warning', 'Success'.

The attributes hold all calls to :meth:`tryme`

Given that func returns a dictionary as explained here above, you can run this code
::

checks = Checker()
checks.tryme(func)

checks contains the status and mesg of each function called by checks.tryme.


"""

def __init__(self):

self.results = []

def tryme(self, meth):
try:
status = meth()
if "msg" in status and "status" in status:
self.results.append(status)
else:
self.results.append({"status": "Success", "msg": status})
except Exception as err: # pragma: no cover
self.results.append(
{"msg": err, "status": "Error", "caller": str(meth.__name__)}
)
self.results.append(
{"msg": err, "status": "Error", "caller": str(meth.__name__)}
)
File renamed without changes.
File renamed without changes
2 changes: 1 addition & 1 deletion requirements.txt → app/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
sequana==0.17.1
streamlit_option_menu
colorlog
Loading