Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4dc3b48
Bump pygments from 2.19.2 to 2.20.0
dependabot[bot] May 11, 2026
cb3f4f3
Bump requests from 2.32.5 to 2.33.0
dependabot[bot] May 11, 2026
1776a17
Bump mako from 1.3.11 to 1.3.12
dependabot[bot] May 11, 2026
eee9ed0
Bump pytest from 9.0.2 to 9.0.3
dependabot[bot] May 11, 2026
04cb942
Bump black from 26.1.0 to 26.3.1
dependabot[bot] May 11, 2026
08f733c
Bump urllib3 from 2.6.3 to 2.7.0
dependabot[bot] May 11, 2026
5dc88bf
Bump idna from 3.11 to 3.15
dependabot[bot] May 19, 2026
19b4fe0
Bump soupsieve from 2.8.3 to 2.8.4
dependabot[bot] Jul 10, 2026
9085290
insert raw png into report
karlnyr Aug 17, 2026
a3f949c
define jinja globals
karlnyr Aug 17, 2026
4c11c9c
read jpg
karlnyr Aug 17, 2026
49c9086
version
karlnyr Aug 17, 2026
edc3252
multiply artwork for old reports
karlnyr Aug 18, 2026
1e16e2c
Merge pull request #253 from Clinical-Genomics/dependabot/uv/soupsiev…
karlnyr Aug 18, 2026
416d33c
Merge pull request #251 from Clinical-Genomics/dependabot/uv/urllib3-…
karlnyr Aug 18, 2026
9791e1a
Merge pull request #250 from Clinical-Genomics/dependabot/uv/black-26…
karlnyr Aug 18, 2026
2b2cb52
Merge pull request #249 from Clinical-Genomics/dependabot/uv/pytest-9…
karlnyr Aug 18, 2026
afc99b9
Merge pull request #248 from Clinical-Genomics/dependabot/uv/mako-1.3.12
karlnyr Aug 18, 2026
7a003a1
Merge pull request #247 from Clinical-Genomics/dependabot/uv/requests…
karlnyr Aug 18, 2026
ff3ce5a
Merge pull request #246 from Clinical-Genomics/dependabot/uv/pygments…
karlnyr Aug 18, 2026
b5f9bb9
Merge pull request #252 from Clinical-Genomics/dependabot/uv/idna-3.15
karlnyr Aug 19, 2026
9bbbcce
Potential fix for pull request finding
karlnyr Aug 19, 2026
8df029f
fix imports
karlnyr Aug 19, 2026
8be40a0
fix readme
karlnyr Aug 19, 2026
be8af7f
remove scrap
karlnyr Aug 20, 2026
ab0a864
remove emf file
karlnyr Aug 20, 2026
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
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![Build status](https://github.com/clinical-genomics/microsalt/actions/workflows/run_tests.yml/badge.svg)](https://github.com/clinical-genomics/microsalt/actions/workflows/run_tests.yml)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4026043.svg)](https://doi.org/10.5281/zenodo.4026043)
[![DOI](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.4026043-blue)](https://doi.org/10.5281/zenodo.4026043)

<p align="center">
<a href="https://github.com/Clinical-Genomics/microSALT">
Expand Down Expand Up @@ -32,8 +32,8 @@ microSALT requires a SLURM cluster._
### Manual install

1. Clone the repository and enter the directory
2. Checkout the desired branch
3. install package using `uv pip install .`
1. Checkout the desired branch
1. install package using `uv pip install .`

## Configuration

Expand All @@ -48,26 +48,28 @@ Copy the configuration file anywhere and.

microSALT uses [Singularity](https://sylabs.io/singularity/) containers to run the various tools used in the analysis. These containers are available on Clinical Genomics' DockerHub, and can be pulled using the following command:

`singularity pull docker://clinicalgenomics/microsalt-blast:latest`
`singularity pull docker://clinicalgenomics/microsalt-bwa:latest`
`singularity pull docker://clinicalgenomics/microsalt-picard:latest`
`singularity pull docker://clinicalgenomics/microsalt-quast:latest`
`singularity pull docker://clinicalgenomics/microsalt-samtools:latest`
`singularity pull docker://clinicalgenomics/microsalt-skesa:latest`
`singularity pull docker://clinicalgenomics/microsalt-trimmomatic:latest`
```Console
singularity pull docker://clinicalgenomics/microsalt-blast:latest
singularity pull docker://clinicalgenomics/microsalt-bwa:latest
singularity pull docker://clinicalgenomics/microsalt-picard:latest
singularity pull docker://clinicalgenomics/microsalt-quast:latest
singularity pull docker://clinicalgenomics/microsalt-samtools:latest
singularity pull docker://clinicalgenomics/microsalt-skesa:latest
singularity pull docker://clinicalgenomics/microsalt-trimmomatic:latest
```

> [!NOTE]
> Remember to enter the correct path to the singularity images in the configuration file.

## Usage

- `microsalt analyse` contains functions to start sbatch job(s) & produce
output to `folders['results']`. Afterwards the parsed results are uploaded
to the SQL back-end and produce reports (HTML), which are then automatically
e-mailed to the user.
output to `folders['results']`. Afterwards the parsed results are uploaded
to the SQL back-end and produce reports (HTML), which are then automatically
e-mailed to the user.
- `microsalt utils` contains various functionality, including generating the
sample description json, manually adding new reference organisms and
re-generating reports.
sample description JSON, manually adding new reference organisms and
re-generating reports.

## Setup

Expand Down
Binary file added artwork/microsalt.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added artwork/swedac-old.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added artwork/swedac.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion microSALT/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

__version__ = "5.0.0"
__version__ = "5.0.1"

logger = None

Expand Down
3 changes: 1 addition & 2 deletions microSALT/server/templates/STtracker_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
<!-- Summary pages -->
<footer>
<div class="panel"><div class="panel-body">
<a href="https://github.com/Clinical-Genomics/microSALT"><img src="https://github.com/Clinical-Genomics/microSALT/blob/master/artwork/microsalt.jpg?raw=true" alt="MicroSALT Logo" align="left" style="position:absolute;left:15px;width:400px;height:100px;display:flex;"></a>
<!--<img src="swedac.jpg" alt="Swedac Logo" align="right" style="display:flex;">-->
<a href="https://github.com/Clinical-Genomics/microSALT"><img src="{{read_jpg(file_path=microsalt_logo_path)}}" alt="MicroSALT Logo" align="left" style="position:absolute;left:15px;width:400px;height:100px;display:flex;"></a>
<h2 class="page-header">
<small><br><br><br>Sekvenstypsuppdateringar</small>
<small><p align="center">Rapport genererad: {{date}}</p></small></h2>
Expand Down
2 changes: 1 addition & 1 deletion microSALT/server/templates/alignment_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<footer>
<div class="panel"><div class="panel-body">
<a href="https://github.com/Clinical-Genomics/microSALT">
<img src="https://github.com/Clinical-Genomics/microSALT/blob/master/artwork/microsalt.jpg?raw=true" \
<img src="{{read_jpg(file_path=microsalt_logo_path)}}" \
alt="MicroSALT Logo" align="left" \
style="position:absolute;left:15px;width:400px;height:100px;display:flex;"></a>
<h2 class="page-header">
Expand Down
6 changes: 3 additions & 3 deletions microSALT/server/templates/typing_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
<footer>
<div class="panel"><div class="panel-body">
<a href="https://github.com/Clinical-Genomics/microSALT">
<img src="https://github.com/Clinical-Genomics/microSALT/blob/master/artwork/microsalt.jpg?raw=true" \
<img src="{{read_jpg(file_path=microsalt_logo_path)}}" \
alt="MicroSALT Logo" align="left" \
style="position:absolute;left:15px;width:400px;height:100px;display:flex;"></a>
{% if topsample.application_tag and 'MW' in topsample.application_tag %}
<img src="https://github.com/Clinical-Genomics/microSALT/blob/master/artwork/swedac.jpg?raw=true" alt="Swedac Logo" align="right" style="display:flex;">
<img src="{{read_jpg(file_path=swedac_logo_path)}}" alt="Swedac Logo" align="right" style="display:flex;">
{% endif %}
<h2 class="page-header">
<small><br><br><br>Typningsrapport</small>
Expand Down Expand Up @@ -263,7 +263,7 @@ <h3>Signatur f&ouml;r godk&auml;nnande av rapport<br></h3>
<h2 class="page-header"><div class="row"></div>Detaljresultat
{% if sample.organism is not none %}
{% if sample.priority == 'standard' and sample.organism.replace('_', ' ').capitalize() in verified_organisms %}
<img src="https://github.com/Clinical-Genomics/microSALT/blob/master/artwork/swedac.jpg?raw=true" alt="Swedac Logo" \
<img src="{{read_jpg(file_path=swedac_logo_path)}}" alt="Swedac Logo" \
align="right" style="width:40px;height:60px;display:flex;">
{% endif %}
{% endif %}
Expand Down
13 changes: 13 additions & 0 deletions microSALT/server/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import base64
from importlib.resources import files
from importlib.resources.abc import Traversable

SWEDAC_LOGO_PATH: Traversable = files("microSALT").joinpath("artwork", "swedac.jpg")
MICROSALT_LOGO_PATH: Traversable = files("microSALT").joinpath("artwork", "microsalt.jpg")


def read_jpg(file_path: Traversable) -> str:
"""Return a base64-encoded data URI for a JPEG image."""
with file_path.open("rb") as jpg_file:
encoded_string: str = base64.b64encode(jpg_file.read()).decode("utf-8")
return f"data:image/jpeg;base64,{encoded_string}"
47 changes: 31 additions & 16 deletions microSALT/server/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

from microSALT import __version__
from microSALT.config import Threshold
from microSALT.server.utils import MICROSALT_LOGO_PATH, SWEDAC_LOGO_PATH, read_jpg
from microSALT.store.database import get_session
from microSALT.store.orm_models import (
Collections,
Reports,
Samples,
Versions,
)

from microSALT.store.database import get_session

# Removes server start messages
log = logging.getLogger("werkzeug")
log.setLevel(logging.CRITICAL)
Expand Down Expand Up @@ -48,6 +48,10 @@ def render_template(template_folder, template_name, **context):
"""Renders a template using Jinja2 directly to avoid Flask overhead"""
template_loader = FileSystemLoader(searchpath=str(template_folder))
jinja_env = Environment(loader=template_loader)
jinja_env.globals["read_jpg"] = read_jpg
jinja_env.globals["microsalt_logo_path"] = MICROSALT_LOGO_PATH
jinja_env.globals["swedac_logo_path"] = SWEDAC_LOGO_PATH

template = jinja_env.get_template(template_name)
if "url_for" not in context:
context["url_for"] = _make_url_for()
Expand Down Expand Up @@ -93,7 +97,13 @@ def render_alignment_page(project, threshold: Threshold, template_folder: Path =
return alignment_page(project, threshold=threshold, template_folder=template_folder)


def typing_page(project, organism_group, threshold: Threshold, verified_organisms: list, template_folder: Path = TEMPLATE_FOLDER):
def typing_page(
project,
organism_group,
threshold: Threshold,
verified_organisms: list,
template_folder: Path = TEMPLATE_FOLDER,
):
sample_info = gen_reportdata(project, organism_group, threshold=threshold)

return render_template(
Expand All @@ -111,8 +121,20 @@ def typing_page(project, organism_group, threshold: Threshold, verified_organism
)


def render_typing_page(project, organism_group, threshold: Threshold, verified_organisms: list, template_folder: Path = TEMPLATE_FOLDER):
return typing_page(project, organism_group, threshold=threshold, verified_organisms=verified_organisms, template_folder=template_folder)
def render_typing_page(
project,
organism_group,
threshold: Threshold,
verified_organisms: list,
template_folder: Path = TEMPLATE_FOLDER,
):
return typing_page(
project,
organism_group,
threshold=threshold,
verified_organisms=verified_organisms,
template_folder=template_folder,
)


def STtracker_page(customer, threshold: Threshold, template_folder: Path = TEMPLATE_FOLDER):
Expand All @@ -123,7 +145,7 @@ def STtracker_page(customer, threshold: Threshold, template_folder: Path = TEMPL
if s.pubmlst_ST != -1 and s.ST < 0:
final_samples.append(s)

final_samples = sorted(final_samples, key=lambda sample: (sample.CG_ID_sample))
final_samples = sorted(final_samples, key=lambda sample: sample.CG_ID_sample)

return render_template(
template_folder=template_folder,
Expand Down Expand Up @@ -219,8 +241,7 @@ def gen_add_info(sample_info=dict(), threshold: Optional[Threshold] = None):
seq_type.st_predictor
and seq_type.identity >= threshold.mlst_novel_id
and threshold.mlst_id > seq_type.identity
and 1 - abs(1 - seq_type.span)
>= (threshold.mlst_span / 100.0)
and 1 - abs(1 - seq_type.span) >= (threshold.mlst_span / 100.0)
):
near_hits = near_hits + 1
elif (
Expand All @@ -245,18 +266,12 @@ def gen_add_info(sample_info=dict(), threshold: Optional[Threshold] = None):
# Resistence filter
if threshold is not None:
for r in s.resistances:
if (
r.identity >= threshold.motif_id
and r.span >= threshold.motif_span / 100.0
):
if r.identity >= threshold.motif_id and r.span >= threshold.motif_span / 100.0:
r.threshold = "Passed"
else:
r.threshold = "Failed"
for v in s.expacs:
if (
v.identity >= threshold.motif_id
and v.span >= threshold.motif_span / 100.0
):
if v.identity >= threshold.motif_id and v.span >= threshold.motif_span / 100.0:
v.threshold = "Passed"
else:
v.threshold = "Failed"
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ include = ["microSALT*"]

[dependency-groups]
dev = [
"black>=23.0",
"black>=26.3.1",
"flake8>=6.0",
"gitlint>=0.19.1",
"pytest>=7.4",
"pytest>=9.0.3",
"pylint>=3.0",
"yamllint>=1.32",
]
Loading
Loading