about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gn3/api/rqtl2.py74
1 files changed, 38 insertions, 36 deletions
diff --git a/gn3/api/rqtl2.py b/gn3/api/rqtl2.py
index e26b9ed..dbbb536 100644
--- a/gn3/api/rqtl2.py
+++ b/gn3/api/rqtl2.py
@@ -1,47 +1,49 @@
 """ File contains endpoints for rqlt2"""
-
-import subprocess
-import os
+import shutil
+from pathlib import Path
 from flask import current_app
 from flask import jsonify
 from flask import Blueprint
 from flask import request
-
+from gn3.computations.rqtl2 import compose_rqtl2_cmd
+from gn3.computations.rqtl2 import prepare_files
+from gn3.computations.rqtl2 import validate_required_keys
+from gn3.computations.rqtl2 import write_input_file
+from gn3.computations.streaming import run_process
 rqtl2 = Blueprint("rqtl2", __name__)
 
 
-@rqtl2.route("/compute", methods=["GET"])
+@rqtl2.route("/compute", methods=["POST"])
 def compute():
     """Endpoint for computing QTL analysis using R/QTL2"""
-    # get the run id to act as file identifier default to output
+    data = request.json
+    # main requirements for creating the cross
+    required_keys = ["crosstype", "geno_data","pheno_data", "geno_codes"]
+    valid, error = validate_required_keys(required_keys,data)
+    if not valid:
+        return jsonify({"Error" : error}), 400
+    # Users should provide atleast the one of this
+    if "pheno_map_data" not in data and "geno_map_data" not in data:
+        return jsonify({ "Error":"You need to Provide\
+        Either the Pheno map or Geno Map data"}), 400
     run_id = request.args.get("id", "output")
-    output_file = os.path.join(current_app.config.get("TMPDIR"),
-                               f"{run_id}.txt")
-    # this should be computed locally not via files
-    rscript_cmd = (
-        "Rscript ./scripts/rqtl2_wrapper.R "
-        "-i /home/kabui/r_playground/meta_grav.json "
-        "-d /home/kabui/r_playground "
-        "-o /home/kabui/r_playground/rqtl_output.json "
-        "--nperm 100  --threshold 1 --cores 0"
-    )
-    # pylint: disable=consider-using-with
-    process = subprocess.Popen(
-        rscript_cmd, shell=True,
-        stdout=subprocess.PIPE,
-        stderr=subprocess.STDOUT
-    )
-    for line in iter(process.stdout.readline, b""):
-        # these allow endpoint stream to read the file since
-        # no read and write file same tiem
-        with open(output_file, "a+", encoding="utf-8") as file_handler:
-            file_handler.write(line.decode("utf-8"))
-    process.stdout.close()
-    process.wait()
-    if process.returncode == 0:
-        return jsonify({"msg": "success",
-                        "results": "file_here",
-                        "run_id": run_id})
-    return jsonify({"msg": "fail",
-                    "error": "Process failed",
-                    "run_id": run_id})
+    # prepare necessary files and dir for computation
+    (workspace_dir, input_file,
+     output_file, log_file) = prepare_files(current_app.config.get("TMPDIR"))
+    # write the input file with data required for creating the cross
+    write_input_file(input_file, workspace_dir, data)
+    # check if the rscript cmd command  exist
+    rqtl_path =Path(__file__).absolute().parent.parent.parent.joinpath("scripts/rqtl2_wrapper.R")
+    if not rqtl_path.is_file():
+        return jsonify({"error" : f"The script {rqtl_path} does not exists"}), 400
+    rqtl2_cmd = compose_rqtl2_cmd(rqtl_path, input_file,
+                                  output_file, workspace_dir,
+                                  data, current_app.config)
+    # run the rscript in as a subprocess which capture stdout in the log file
+    process_output = run_process(rqtl2_cmd.split(),log_file, run_id)
+    if process_output["code"]!=0:
+        return jsonify(process_output), 400
+    # TODO: process the results and return results to gn2
+    # rm the workspace directory
+    shutil.rmtree(workspace_dir, ignore_errors=True, onerror=None)
+    return process_output