about summary refs log tree commit diff
path: root/gn3/api
diff options
context:
space:
mode:
Diffstat (limited to 'gn3/api')
-rw-r--r--gn3/api/general.py29
-rw-r--r--gn3/api/rqtl2.py61
2 files changed, 90 insertions, 0 deletions
diff --git a/gn3/api/general.py b/gn3/api/general.py
index b984361..fcaf21b 100644
--- a/gn3/api/general.py
+++ b/gn3/api/general.py
@@ -1,5 +1,6 @@
 """General API endpoints.  Put endpoints that can't be grouped together nicely
 here."""
+import os
 from flask import Blueprint
 from flask import current_app
 from flask import jsonify
@@ -68,3 +69,31 @@ def run_r_qtl(geno_filestr, pheno_filestr):
     cmd = (f"Rscript {rqtl_wrapper} "
            f"{geno_filestr} {pheno_filestr}")
     return jsonify(run_cmd(cmd)), 201
+
+
+@general.route("/stream ",  methods=["GET"])
+def stream():
+    """
+    This endpoint streams the stdout content from a file.
+    It expects an identifier to be passed as a query parameter.
+    Example: `/stream?id=<identifier>`
+   The `id` will be used to locate the corresponding file.
+   You can also pass an optional `peak` parameter
+    to specify the file position to start reading from.
+   Query Parameters:
+   - `id` (required): The identifier used to locate the file.
+   - `peak` (optional): The position in the file to start reading from.
+   Returns:
+   - dict with data(stdout), run_id unique id for file,
+    pointer last read position for file
+  """
+    run_id = request.args.get("id", "")
+    output_file = os.path.join(current_app.config.get("TMPDIR"),
+                               f"{run_id}.txt")
+    seek_position = int(request.args.get("peak", 0))
+    with open(output_file) as file_handler:
+        # read to the last position default to 0
+        file_handler.seek(seek_position)
+        return jsonify({"data": file_handler.readlines(),
+                        "run_id": run_id,
+                        "pointer": file_handler.tell()})
diff --git a/gn3/api/rqtl2.py b/gn3/api/rqtl2.py
new file mode 100644
index 0000000..ffa8755
--- /dev/null
+++ b/gn3/api/rqtl2.py
@@ -0,0 +1,61 @@
+""" File contains endpoints for rqlt2"""
+
+import subprocess
+import uuid
+import os
+from flask import current_app
+from flask import jsonify
+from flask import Blueprint
+from flask import request
+
+rqtl2 = Blueprint("rqtl2", __name__)
+
+@rqtl2.route("/compute", methods=["GET"])
+def compute():
+    """Endpoint for computing QTL analysis using R/QTL2"""
+    # get the run id to act as file identifier default to output
+    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 = (
+        f"Rscript ./scripts/rqtl2_wrapper.R "
+        f"-i /home/kabui/r_playground/meta_grav.json "
+        f"-d /home/kabui/r_playground "
+        f"-o /home/kabui/r_playground/rqtl_output.json "
+        f"--nperm 100  --threshold 1 --cores 0"
+    )
+    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+") 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})
+
+
+@rqtl2.route("/stream/<identifier>",  methods=["GET"])
+def stream(identifier="output"):
+    """ This endpoints streams stdout from a file expects
+    the indetifier to be the file """
+    output_file = os.path.join(current_app.config.get("TMPDIR"),
+                               f"{identifier}.txt")
+    seek_position = int(request.args.get("peak", 0))
+    with open(output_file) as file_handler:
+        # read to the last position default to 0
+        file_handler.seek(seek_position)
+        return jsonify({"data": file_handler.readlines(),
+                        "run_id": identifier,
+                        "pointer": file_handler.tell()})