mirror of
https://github.com/Novartis/cellxgene-gateway.git
synced 2026-10-04 08:28:12 +08:00
the first commit
This commit is contained in:
+173
@@ -0,0 +1,173 @@
|
||||
# Copyright 2019 Novartis Institutes for BioMedical Research Inc. Licensed
|
||||
# under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
# this file except in compliance with the License. You may obtain a copy
|
||||
# of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless
|
||||
# required by applicable law or agreed to in writing, software distributed
|
||||
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
|
||||
# OR CONDITIONS OF ANY KIND, either express or implied. See the License for
|
||||
# the specific language governing permissions and limitations under the License.
|
||||
|
||||
# import BaseHTTPServer
|
||||
import datetime
|
||||
import os
|
||||
from threading import Thread
|
||||
|
||||
from flask import Flask, redirect, render_template, request, send_from_directory
|
||||
from flask_api import status
|
||||
from werkzeug import secure_filename
|
||||
|
||||
import env
|
||||
from backend_cache import BackendCache
|
||||
from cellxgene_exception import CellxgeneException
|
||||
from dir_util import create_dir, recurse_dir, render_entries
|
||||
from extra_scripts import get_extra_scripts
|
||||
from path_util import get_dataset, get_file_path
|
||||
from process_exception import ProcessException
|
||||
from prune_process_cache import PruneProcessCache
|
||||
from util import current_time_stamp
|
||||
|
||||
app = Flask(__name__)
|
||||
cache = BackendCache()
|
||||
location = f"{env.gateway_protocol}://{env.gateway_host}"
|
||||
|
||||
|
||||
@app.errorhandler(CellxgeneException)
|
||||
def handle_invalid_usage(error):
|
||||
|
||||
message = f"{error.http_status} Error : {error.message}"
|
||||
|
||||
return (
|
||||
render_template(
|
||||
"cellxgene_error.html", extra_scripts=get_extra_scripts(), message=message
|
||||
),
|
||||
error.http_status,
|
||||
)
|
||||
|
||||
|
||||
@app.errorhandler(ProcessException)
|
||||
def handle_invalid_process(error):
|
||||
|
||||
message = []
|
||||
|
||||
message.append(error.message)
|
||||
message.append(f"{error.http_status} Error.")
|
||||
message.append(f"Stdout: {error.stdout}")
|
||||
message.append(f"Stderr: {error.stderr}")
|
||||
|
||||
return (
|
||||
render_template(
|
||||
"process_error.html", extra_scripts=get_extra_scripts(), message=message
|
||||
),
|
||||
error.http_status,
|
||||
)
|
||||
|
||||
|
||||
@app.route("/favicon.ico")
|
||||
def favicon():
|
||||
return send_from_directory(
|
||||
os.path.join(app.root_path, "static"),
|
||||
"nibr.ico",
|
||||
mimetype="image/vnd.microsof.icon",
|
||||
)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
users = [
|
||||
name
|
||||
for name in os.listdir(env.cellxgene_data)
|
||||
if os.path.isdir(os.path.join(env.cellxgene_data, name))
|
||||
]
|
||||
return render_template(
|
||||
"index.html",
|
||||
ip=env.ip,
|
||||
cellxgene_data=env.cellxgene_data,
|
||||
extra_scripts=get_extra_scripts(),
|
||||
users=users,
|
||||
)
|
||||
|
||||
|
||||
@app.route("/make_user", methods=["POST"])
|
||||
def make_user():
|
||||
dir_name = request.form["directory"]
|
||||
|
||||
create_dir(env.cellxgene_data, dir_name)
|
||||
|
||||
return redirect(location, code=302)
|
||||
|
||||
|
||||
@app.route("/make_subdir", methods=["POST"])
|
||||
def make_subdir():
|
||||
parent_path = os.path.join(env.cellxgene_data, request.form["usernames"])
|
||||
dir_name = request.form["directory"]
|
||||
|
||||
create_dir(parent_path, dir_name)
|
||||
|
||||
return redirect(location, code=302)
|
||||
|
||||
|
||||
@app.route("/upload_file", methods=["POST"])
|
||||
def upload_file():
|
||||
upload_dir = request.form["path"]
|
||||
|
||||
full_upload_path = env.cellxgene_data + "/" + upload_dir
|
||||
if os.path.isdir(full_upload_path):
|
||||
if request.method == "POST":
|
||||
if "file" in request.files:
|
||||
f = request.files["file"]
|
||||
if f and f.filename.endswith(".h5ad"):
|
||||
f.save(full_upload_path + "/" + secure_filename(f.filename))
|
||||
return redirect("/filecrawl.html", code=302)
|
||||
else:
|
||||
raise CellxgeneException(
|
||||
"Uploaded file must be in anndata (.h5ad) format.",
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
else:
|
||||
raise CellxgeneException(
|
||||
"A file must be chosen to upload.", status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
else:
|
||||
raise CellxgeneException("Invalid directory.", status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
return redirect(env.location, code=302)
|
||||
|
||||
|
||||
@app.route("/filecrawl.html")
|
||||
def filecrawl():
|
||||
|
||||
entries = recurse_dir(env.cellxgene_data)
|
||||
rendered_html = render_entries(entries)
|
||||
return render_template(
|
||||
"filecrawl.html", extra_scripts=get_extra_scripts(), rendered_html=rendered_html
|
||||
)
|
||||
|
||||
|
||||
@app.route("/view/<path:path>")
|
||||
def do_GET(path):
|
||||
|
||||
dataset = get_dataset(path)
|
||||
file_path = get_file_path(dataset)
|
||||
match = cache.check_entry(dataset)
|
||||
if match is None:
|
||||
uascripts = get_extra_scripts()
|
||||
match = cache.create_entry(dataset, file_path, uascripts)
|
||||
|
||||
match.timestamp = current_time_stamp()
|
||||
|
||||
if match.status == "loaded":
|
||||
return match.serve_content(path)
|
||||
elif match.status == "loading":
|
||||
launch_time = datetime.datetime.fromtimestamp(match.launchtime)
|
||||
return render_template(
|
||||
"loading.html", launchtime=launch_time, all_output=match.all_output
|
||||
)
|
||||
elif match.status == "error":
|
||||
raise ProcessException.from_pid_object(match)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
background_thread = Thread(target=PruneProcessCache(cache))
|
||||
background_thread.start()
|
||||
|
||||
app.run(host="0.0.0.0", port=5005, debug=False)
|
||||
Reference in New Issue
Block a user