-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
122 lines (107 loc) · 3.8 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# -*- coding: utf-8 -*-
# -*- mode: python -*-
from flask import Flask, request, jsonify, url_for
from lmeasure import command, __version__
app = Flask(__name__)
@app.route('/', methods=["GET"])
def index():
data = {
"info": url_for('info'),
"lmeasure": url_for('lmeasure'),
"convert": url_for('convert')
}
return jsonify(data)
@app.route('/info/', methods=["GET"])
def info():
try:
version = command.get_version()
except RuntimeError as e:
return jsonify({"error": "l-measure failed: {!s}".format(e)}), 400
return jsonify({
"lmeasure-version": command.get_version(),
"lmeasure-svc-version": __version__,
"lmeasure-svc-docs": "https://github.com/melizalab/lmeasure-svc"
})
measure_options = {
"POST": {
"description": "compute morphometrics from neural reconstructions",
"parameters": {
"data": {
"type": "string",
"description": "ASCII-encoded reconstruction. Allowed formats: {}".format(", ".join(command.lm_formats)),
"required": True,
},
"metrics": {
"type": "list",
"description": "list of metrics to calculate. If not supplied, calculates all",
"allowed_values": command.lm_function_names,
"required": False,
},
}
}
}
@app.route('/lmeasure/', methods=["POST", "OPTIONS"])
def lmeasure():
if request.method == "OPTIONS":
resp = jsonify(measure_options)
resp.headers['Allow'] = "POST,OPTIONS"
return resp
elif request.method == "POST":
if request.is_json:
d = request.get_json()
else:
d = request.form
if "data" not in d:
return jsonify({"error": "no 'data' field in request"}), 400
if "metrics" not in d:
metrics = command.lm_function_names
elif isinstance(d["metrics"], str):
metrics = (d["metrics"],)
elif isinstance(d["metrics"], list):
metrics = d["metrics"]
app.logger.debug('requested metrics: %s', metrics)
try:
out, err = command.run_lmeasure(d["data"], *metrics)
app.logger.debug('stdout: %s', out)
app.logger.debug('stderr: %s', err)
command.check_errors(err)
measures = [d for d in command.parse_results(out)]
except KeyError as e:
return jsonify({"error": "bad metric '{}' requested".format(e)}), 400
except RuntimeError as e:
return jsonify({"error": "l-measure failed: {!s}".format(e)}), 400
else:
return jsonify({"error": None, "measures": measures})
convert_options = {
"POST": {
"description": "convert reconstruction data to SWC format",
"parameters": {
"file": {
"type": "string",
"description": "ASCII-encoded reconstruction. Allowed formats: {}".format(", ".join(command.lm_formats)),
"required": True,
},
}
}
}
@app.route('/convert/', methods=["POST", "OPTIONS"])
def convert():
if request.method == "OPTIONS":
resp = jsonify(convert_options)
resp.headers['Allow'] = "POST,OPTIONS"
return resp
elif request.method == "POST":
if request.is_json:
d = request.get_json()
else:
d = request.form
if "data" not in d:
return jsonify({"error": "no 'data' field in request"}), 400
try:
swc = command.run_convert(d["data"])
except RuntimeError as e:
return jsonify({"error": "l-measure failed: {!s}".format(e)}), 400
else:
return jsonify({"error": None, "data": swc})
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)