diff options
author | Frederick Muriuki Muriithi | 2024-02-05 07:00:01 +0300 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-02-05 07:00:01 +0300 |
commit | ab71b34b97f3f1eee52b5688f41644541535f281 (patch) | |
tree | 4ae94d1957a62bd739203eddc4c157d2701461e4 | |
parent | 635cf832f4717da6e8e7ef273a675a4ceea42ed0 (diff) | |
download | gn-uploader-ab71b34b97f3f1eee52b5688f41644541535f281.tar.gz |
Do general bundle validation and show errors
* Display any and all errors on the UI
* Move `validate_bundle` to QC module and refactor to use
`missing_files`
-rw-r--r-- | qc_app/templates/rqtl2/upload-rqtl2-bundle-step-01.html | 6 | ||||
-rw-r--r-- | qc_app/templates/rqtl2/upload-rqtl2-bundle-step-02.html | 3 | ||||
-rw-r--r-- | qc_app/upload/rqtl2.py | 10 | ||||
-rw-r--r-- | r_qtl/errors.py | 6 | ||||
-rw-r--r-- | r_qtl/r_qtl2.py | 22 | ||||
-rw-r--r-- | r_qtl/r_qtl2_qc.py | 9 |
6 files changed, 26 insertions, 30 deletions
diff --git a/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-01.html b/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-01.html index 6491e6b..64fcdcd 100644 --- a/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-01.html +++ b/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-01.html @@ -1,5 +1,5 @@ {%extends "base.html"%} -{%from "flash_messages.html" import flash_messages%} +{%from "flash_messages.html" import flash_all_messages%} {%block title%}Upload R/qtl2 Bundle{%endblock%} @@ -16,12 +16,12 @@ <input type="hidden" name="population_id" value="{{population.InbredSetId}}" /> - {{flash_messages("error-rqtl2")}} + {{flash_all_messages()}} <fieldset> <legend>file upload</legend> <label for="file:rqtl2-bundle">R/qtl2 bundle</label> - <input type="file" id="file:rqtl2-bundle" name="rqtl2_bundle" + <input type="file" id="file:rqtl2-bundle" name="rqtl2_bundle_file" accept="application/zip, .zip" required="required" /> <span class="form-input-help"><p>Provide a valid R/qtl2 zip file here. In diff --git a/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-02.html b/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-02.html index 9269a3c..01721e9 100644 --- a/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-02.html +++ b/qc_app/templates/rqtl2/upload-rqtl2-bundle-step-02.html @@ -1,5 +1,5 @@ {%extends "base.html"%} -{%from "flash_messages.html" import flash_messages%} +{%from "flash_messages.html" import flash_all_messages%} {%block title%}Upload R/qtl2 Bundle{%endblock%} @@ -20,6 +20,7 @@ population_id=population.InbredSetId)}}" method="POST" enctype="multipart/form-data"> + {{flash_all_messages()}} <input type="hidden" name="species_id" value="{{species.SpeciesId}}" /> <input type="hidden" name="population_id" value="{{population.InbredSetId}}" /> diff --git a/qc_app/upload/rqtl2.py b/qc_app/upload/rqtl2.py index eea49e1..2d032f8 100644 --- a/qc_app/upload/rqtl2.py +++ b/qc_app/upload/rqtl2.py @@ -18,6 +18,8 @@ from flask import ( current_app as app) from r_qtl import r_qtl2 +from r_qtl import errors as rqe +from r_qtl import r_qtl2_qc as rqc from r_qtl.errors import InvalidFormat from qc_app import jobs @@ -157,11 +159,11 @@ def upload_rqtl2_bundle(species_id: int, population_id: int): species=species, population=population) - if not bool(request.files.get("rqtl2_bundle")): + if not bool(request.files.get("rqtl2_bundle_file")): raise __RequestError__("No R/qtl2 zip bundle provided.") - the_file = save_file( - request.files["rqtl2_bundle"], Path(app.config["UPLOAD_FOLDER"])) + the_file = save_file(request.files["rqtl2_bundle_file"], + Path(app.config["UPLOAD_FOLDER"])) if not bool(the_file): raise __RequestError__("Please provide a valid R/qtl2 zip bundle.") @@ -170,7 +172,7 @@ def upload_rqtl2_bundle(species_id: int, population_id: int): try: with ZipFile(str(the_file), "r") as zfile: - r_qtl2.validate_bundle(zfile) + rqc.validate_bundle(zfile) return render_template( "rqtl2/upload-rqtl2-bundle-step-02.html", species=species, diff --git a/r_qtl/errors.py b/r_qtl/errors.py index 20c5ced..417eb58 100644 --- a/r_qtl/errors.py +++ b/r_qtl/errors.py @@ -5,3 +5,9 @@ class RQTLError(Exception): class InvalidFormat(RQTLError): """Raised when the format of the file(s) is invalid.""" + +class MissingFileError(InvalidFormat): + """ + Raise when at least one file listed in the control file is missing from the + R/qtl2 bundle. + """ diff --git a/r_qtl/r_qtl2.py b/r_qtl/r_qtl2.py index c2828d2..f8c08d9 100644 --- a/r_qtl/r_qtl2.py +++ b/r_qtl/r_qtl2.py @@ -288,28 +288,6 @@ def sex_information(zfile: ZipFile, cdata: dict) -> Iterator[dict]: key: chain(value, partial(replace_sex_info, cdata=cdata)) for key, value in row.items() if key not in ci_fields} -def validate_bundle(zfile: ZipFile): - """Ensure the R/qtl2 bundle is valid.""" - cdata = control_data(zfile) - def __member_exists_p__(zfile, member): - if isinstance(member, str): - zfile.getinfo(member) - else: - for inner in member: - zfile.getinfo(inner) - - try: - for member in (key for key in cdata.keys() if key in __FILE_TYPES__): - __member_exists_p__(zfile, cdata[member]) - - if "file" in cdata.get("sex", {}): - __member_exists_p__(zfile, cdata["sex"]["file"]) - - if "file" in cdata.get("cross_info", {}): - __member_exists_p__(zfile, cdata["cross_info"]["file"]) - except KeyError as kerr: - raise InvalidFormat(*kerr.args) from kerr - def genotype_data(zfile: ZipFile): """Convenience function to genotype data from R/qtl2 bundle.""" cdata = control_data(zfile) diff --git a/r_qtl/r_qtl2_qc.py b/r_qtl/r_qtl2_qc.py index f666f40..261d300 100644 --- a/r_qtl/r_qtl2_qc.py +++ b/r_qtl/r_qtl2_qc.py @@ -3,6 +3,7 @@ from zipfile import ZipFile from functools import reduce from typing import Union, Sequence +from r_qtl import errors as rqe from r_qtl import r_qtl2 as rqtl2 from r_qtl.r_qtl2 import __FILE_TYPES__ @@ -45,3 +46,11 @@ def missing_files(zfile: ZipFile) -> tuple[str]: return tuple(filter(__missing_p__, bundle_files_list(zfile, rqtl2.control_data(zfile)))) + +def validate_bundle(zfile: ZipFile): + """Ensure the R/qtl2 bundle is valid.""" + missing = missing_files(zfile) + if len(missing) > 0: + raise rqe.MissingFileError( + "The following files do not exist in the bundle: " + + ", ".join(missing)) |