From d02cef83c3c0b3f3098df1a7e7eeaf90430f784a Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Thu, 8 Feb 2024 15:54:32 +0300 Subject: R/qtl2 QC: Set up scaffolding for QC UI Set up the scaffolding for the flows and UI that will be used when running QC against the uploaded R/qtl2 bundle. This will be fleshed out later, and the UI is likely to change somewhat, down the line. --- qc_app/upload/rqtl2.py | 63 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 18 deletions(-) (limited to 'qc_app/upload') diff --git a/qc_app/upload/rqtl2.py b/qc_app/upload/rqtl2.py index 9d787e1..afe0c2e 100644 --- a/qc_app/upload/rqtl2.py +++ b/qc_app/upload/rqtl2.py @@ -18,8 +18,6 @@ from flask import ( current_app as app) from r_qtl import r_qtl2 -from r_qtl import r_qtl2_qc as rqc -from r_qtl.errors import InvalidFormat from qc_app import jobs from qc_app.files import save_file, fullpath @@ -135,12 +133,6 @@ class __RequestError__(Exception): #pylint: disable=[invalid-name] methods=["GET", "POST"]) def upload_rqtl2_bundle(species_id: int, population_id: int): """Allow upload of R/qtl2 bundle.""" - this_page_with_errors = redirect(url_for("upload.rqtl2.upload_rqtl2_bundle", - species_id=species_id, - population_id=population_id, - pgsrc="error"), - code=307) - with database_connection(app.config["SQL_URI"]) as conn: species = species_by_id(conn, species_id) population = population_by_species_and_id( @@ -171,17 +163,52 @@ def upload_rqtl2_bundle(species_id: int, population_id: int): if not is_zipfile(str(the_file)): raise __RequestError__("Invalid file! Expected a zip file.") + redisuri = app.config["REDIS_URL"] + with Redis.from_url(redisuri, decode_responses=True) as rconn: + jobid = str(uuid4()) + redis_ttl_seconds = app.config["JOBS_TTL_SECONDS"] + jobs.launch_job( + jobs.initialise_job( + rconn, + jobs.jobsnamespace(), + jobid, + [sys.executable, "-m", "scripts.qc_on_rqtl2_bundle", + app.config["SQL_URI"], app.config["REDIS_URL"], + jobs.jobsnamespace(), jobid, "--redisexpiry", + str(redis_ttl_seconds)], + "rqtl2-bundle-qc-job", + redis_ttl_seconds, + {}), + redisuri, + f"{app.config['UPLOAD_FOLDER']}/job_errors") + return redirect(url_for( + "upload.rqtl2.rqtl2_bundle_qc_status", jobid=jobid)) + +@rqtl2.route("/upload/species/rqtl2-bundle/qc-status/", + methods=["GET", "POST"]) +def rqtl2_bundle_qc_status(jobid: UUID): + """Check the status of the QC jobs.""" + with Redis.from_url(app.config["REDIS_URL"], decode_responses=True) as rconn: try: - with ZipFile(str(the_file), "r") as zfile: - rqc.validate_bundle(zfile) - return render_template( - "rqtl2/upload-rqtl2-bundle-step-02.html", - species=species, - population=population, - rqtl2_bundle_file=the_file.name)#type: ignore[union-attr] - except (InvalidFormat, __RequestError__) as exc: - flash("".join(exc.args), "alert-error error-rqtl2") - return this_page_with_errors + thejob = jobs.job(rconn, jobs.jobsnamespace(), jobid) + messagelistname = thejob.get("log-messagelist") + logmessages = (rconn.lrange(messagelistname, 0, -1) + if bool(messagelistname) else []) + jobstatus = thejob["status"] + if jobstatus == "error": + return render_template("rqtl2/rqtl2-qc-job-error.html", + job=thejob, + messages=logmessages) + if jobstatus == "success": + return render_template("rqtl2/rqtl2-qc-job-results.html", + job=thejob, + messages=logmessages) + + return render_template("rqtl2/rqtl2-qc-job-status.html", + job=thejob, + messages=tuple()) + except jobs.JobNotFound: + return render_template("rqtl2/no-such-job.html", jobid=jobid) def check_errors(conn, *args, **kwargs):#pylint: disable=[too-many-return-statements] """Check for select errors in the forms and return a page to redirect to.""" -- cgit v1.2.3