Skip to content

Commit

Permalink
Move reports path definition closer to representation; Update singlec…
Browse files Browse the repository at this point in the history
…ell summary reports to return more than one report per sample if needed
  • Loading branch information
aanil committed Jan 28, 2025
1 parent 3d842f9 commit 067cd6e
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 44 deletions.
6 changes: 4 additions & 2 deletions run_dir/design/project_samples_old.html
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,10 @@ <h4>User project description
{% end %}
{% if 'sample_summary_reports' in reports %}
<h6 class="dropdown-header">Single Cell Sample Summary</h6>
{% for sample in reports['sample_summary_reports'] %}
<a class="dropdown-item" href="/singlecell_sample_summary_report/{{ project }}/{{ sample }}" target="_blank"> {{ sample}} </a>
{% for sample, values in reports['sample_summary_reports'].items() %}
{% for method, report in values.items() %}
<a class="dropdown-item" href="/singlecell_sample_summary_report/{{ project }}/{{ sample }}/{{ report }}" target="_blank"> {{ sample }} {{ method }} </a>
{% end %}
{% end %}
{% end %}
</div>
Expand Down
17 changes: 7 additions & 10 deletions status/flowcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,9 @@ def __init__(self, application, request, **kwargs):
super(SafeHandler, self).__init__(application, request, **kwargs)

def get(self, name):
reports_dir = os.path.join(self.application.reports_path, "minknow_reports")
report_path = os.path.join(reports_dir, f"report_{name}.html")
report_path = os.path.join(
self.application.report_path["minknow"], f"report_{name}.html"
)

self.write(open(report_path).read())

Expand All @@ -483,10 +484,9 @@ def __init__(self, application, request, **kwargs):
super(SafeHandler, self).__init__(application, request, **kwargs)

def get(self, name):
reports_dir = os.path.join(
self.application.reports_path, "other_reports", "toulligqc_reports"
report_path = os.path.join(
self.application.report_path["toulligqc"], f"report_{name}.html"
)
report_path = os.path.join(reports_dir, f"report_{name}.html")

self.write(open(report_path).read())

Expand Down Expand Up @@ -761,16 +761,13 @@ def get(self, name):
args=self.fetch_args(name),
has_minknow_report=os.path.exists(
os.path.join(
self.application.reports_path,
"minknow_reports",
self.application.report_path["minknow"],
f"report_{name}.html",
)
),
has_toulligqc_report=os.path.exists(
os.path.join(
self.application.reports_path,
"other_reports",
"toulligqc_reports",
self.application.report_path["tooulligqc"],
f"report_{name}.html",
)
),
Expand Down
15 changes: 14 additions & 1 deletion status/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import itertools
import json
import logging
import re
from collections import OrderedDict

import dateutil.parser
Expand Down Expand Up @@ -972,7 +973,19 @@ def get(self, project):
)
)
if sample_summary_reports:
reports["sample_summary_reports"] = sample_summary_reports
group_summary_reports = {}
for report in sample_summary_reports:
# Match report names in the format <sample_id(projid_int)>_(<Method>_<(optional)>)_report.html/pdf
match = re.match(
rf"^({project}_\d+)_([^_]+(_[^_]+)?)_report\.(pdf|html)", report
)
if match:
sample_id = match.group(1)
method = match.group(2)
if sample_id not in group_summary_reports:
group_summary_reports[sample_id] = {}
group_summary_reports[sample_id][method] = report
reports["sample_summary_reports"] = group_summary_reports
self.write(
t.generate(
gs_globals=self.application.gs_globals,
Expand Down
71 changes: 41 additions & 30 deletions status/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def get_multiqc(
project_name = query_res["rows"][0]["value"]

if project_name:
multiqc_path = os.path.join(app.reports_path, "mqc_reports") or ""
multiqc_path = app.report_path["multiqc"] or ""
for report_type in ["_", "_qc_", "_pipeline_"]:
multiqc_name = f"{project_name}{report_type}multiqc_report.html"
multiqc_file_path = os.path.join(multiqc_path, multiqc_name)
Expand Down Expand Up @@ -89,8 +89,7 @@ def get_summary_report(

if project_name:
report_path = os.path.join(
app.reports_path,
"yggdrasil",
app.report_path["yggdrasil"],
project_id,
f"{project_name}_project_summary.html",
)
Expand All @@ -107,17 +106,20 @@ def get_summary_report(
class SingleCellSampleSummaryReportHandler(SafeHandler):
"""Handler for Single Cell sample summary reports generated using yggdrasil"""

def get(self, project_id: str, sample_id: str) -> None:
def get(self, project_id: str, sample_id: str, rep_name: str) -> None:
report = self.get_sample_summary_report(
self.application, project_id, sample_id=sample_id
self.application, project_id, sample_id=sample_id, rep_name=rep_name
)
if report:
self.set_header("Content-Type", "application/pdf")
self.set_header(
"Content-Disposition",
f"inline; filename={sample_id}_single_cell_sample_summary_report.pdf",
)
self.write(report)
if "html" in rep_name:
self.write(report)
elif "pdf" in rep_name:
self.set_header("Content-Type", "application/pdf")
self.set_header(
"Content-Disposition",
f"inline; filename={sample_id}_single_cell_sample_summary_report.pdf",
)
self.write(report)
else:
t = self.application.loader.load("error_page.html")
self.write(
Expand All @@ -131,36 +133,45 @@ def get(self, project_id: str, sample_id: str) -> None:

@staticmethod
def get_sample_summary_report(
app: Any, project_id: str, sample_id: Optional[str] = None
app: Any,
project_id: str,
sample_id: Optional[str] = None,
rep_name: Optional[str] = None,
) -> Union[bytes, list[str], None]:
"""Returns a list of sample summary reports for the requested project if sample_id is None,
otherwise returns the report for the requested sample"""

sample_summary_reports_path = os.path.join(
app.reports_path, "yggdrasil", project_id
)
proj_path = os.path.join(app.report_path["yggdrasil"], project_id)
if sample_id:
report_path = os.path.join(
sample_summary_reports_path, sample_id, f"{sample_id}_report.pdf"
)
file_type = rep_name.split(".")[-1]
mode = "rb" if file_type == "pdf" else "r"
encoding = None if file_type == "pdf" else "utf-8"
report_path = os.path.join(proj_path, sample_id, rep_name)
if os.path.exists(report_path):
with open(report_path, "rb") as report_file:
with open(report_path, mode, encoding=encoding) as report_file:
return report_file.read()
else:
return None

else:
reports = []
if os.path.exists(sample_summary_reports_path):
for item in os.listdir(sample_summary_reports_path):
if os.path.isdir(
os.path.join(sample_summary_reports_path, item)
) and item.startswith(f"{project_id}_"):
if os.path.exists(
os.path.join(
sample_summary_reports_path, item, f"{item}_report.pdf"
)
):
reports.append(item)

if os.path.exists(proj_path):
for item in os.listdir(proj_path):
if os.path.isdir(os.path.join(proj_path, item)) and item.startswith(
f"{project_id}_"
):
sample_path = os.path.join(proj_path, item)
if os.path.exists(sample_path):
# Reports will be named as <sample_id>_<Method>_<(optional)>_report.html/pdf
reports = [
f
for f in os.listdir(sample_path)
if os.path.isfile(os.path.join(sample_path, f))
and (
f.startswith(f"{item}_")
and f.endswith(("_report.pdf", "_report.html"))
)
]

return reports
9 changes: 8 additions & 1 deletion status_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def __init__(self, settings):
("/sensorpush", SensorpushHandler),
("/sequencing_queues", SequencingQueuesHandler),
(
"/singlecell_sample_summary_report/(P[^/]*)/([^/]*)$",
"/singlecell_sample_summary_report/(P[^/]*)/([^/]*)/([^/]*)$",
SingleCellSampleSummaryReportHandler,
),
("/smartseq3_progress", SmartSeq3ProgressPageHandler),
Expand Down Expand Up @@ -548,6 +548,13 @@ def __init__(self, settings):
# ├── mqc_reports/
# └── yggdrasil/<project_id>/
self.reports_path = settings.get("reports_path")
self.report_path = {}
self.report_path["minknow"] = Path(self.reports_path, "minknow_reports")
self.report_path["multiqc"] = Path(self.reports_path, "mqc_reports")
self.report_path["toullingqc"] = Path(
self.reports_path, "other_reports", "toulligqc_reports"
)
self.report_path["yggdrasil"] = Path(self.reports_path, "yggdrasil")

# lims backend credentials
limsbackend_cred_loc = Path(
Expand Down

0 comments on commit 067cd6e

Please sign in to comment.