mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-08 23:48:12 +08:00
Consistency with quotes
' -> "
This commit is contained in:
@@ -34,7 +34,7 @@ app.config.update(
|
|||||||
DATASET_TITLE=TITLE
|
DATASET_TITLE=TITLE
|
||||||
)
|
)
|
||||||
|
|
||||||
app.config['PROFILE'] = True
|
app.config["PROFILE"] = True
|
||||||
# app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[15])
|
# app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[15])
|
||||||
|
|
||||||
# Application Data
|
# Application Data
|
||||||
@@ -54,8 +54,8 @@ docs.append(resources.get_swagger_doc())
|
|||||||
app.register_blueprint(webapp.bp)
|
app.register_blueprint(webapp.bp)
|
||||||
app.register_blueprint(resources.blueprint)
|
app.register_blueprint(resources.blueprint)
|
||||||
app.register_blueprint(
|
app.register_blueprint(
|
||||||
get_swagger_blueprint(docs, '/api/swagger', produces=["application/json"], title="cellxgene rest api",
|
get_swagger_blueprint(docs, "/api/swagger", produces=["application/json"], title="cellxgene rest api",
|
||||||
description='An API connecting ExpressionMatrix2 clustering algorithm to cellxgene'))
|
description="An API connecting ExpressionMatrix2 clustering algorithm to cellxgene"))
|
||||||
|
|
||||||
|
|
||||||
app.add_url_rule('/', endpoint='index')
|
app.add_url_rule("/", endpoint="index")
|
||||||
|
|||||||
+61
-61
@@ -9,14 +9,14 @@ from ..util.filter import parse_filter
|
|||||||
|
|
||||||
class InitializeAPI(Resource):
|
class InitializeAPI(Resource):
|
||||||
@swagger.doc({
|
@swagger.doc({
|
||||||
'summary': 'get metadata schema, ranges for values, and cell count to initialize cellxgene app',
|
"summary": "get metadata schema, ranges for values, and cell count to initialize cellxgene app",
|
||||||
'tags': ['initialize'],
|
"tags": ["initialize"],
|
||||||
'parameters': [],
|
"parameters": [],
|
||||||
'responses': {
|
"responses": {
|
||||||
'200': {
|
"200": {
|
||||||
'description': 'initialization data for UI',
|
"description": "initialization data for UI",
|
||||||
'examples': {
|
"examples": {
|
||||||
'application/json': {
|
"application/json": {
|
||||||
"data": {
|
"data": {
|
||||||
"cellcount": 3589,
|
"cellcount": 3589,
|
||||||
"options": {
|
"options": {
|
||||||
@@ -101,21 +101,21 @@ class InitializeAPI(Resource):
|
|||||||
|
|
||||||
class CellsAPI(Resource):
|
class CellsAPI(Resource):
|
||||||
@swagger.doc({
|
@swagger.doc({
|
||||||
'summary': 'filter based on metadata fields to get a subset cells, expression data, and metadata',
|
"summary": "filter based on metadata fields to get a subset cells, expression data, and metadata",
|
||||||
'tags': ['cells'],
|
"tags": ["cells"],
|
||||||
'description': "Cells takes query parameters defined in the schema retrieved from the /initialize enpoint. "
|
"description": "Cells takes query parameters defined in the schema retrieved from the /initialize enpoint. "
|
||||||
"<br>For categorical metadata keys filter based on `key=value` <br>"
|
"<br>For categorical metadata keys filter based on `key=value` <br>"
|
||||||
" For continuous metadata keys filter by `key=min,max`<br> Either value "
|
" For continuous metadata keys filter by `key=min,max`<br> Either value "
|
||||||
"can be replaced by a \*. To have only a minimum value `key=min,\*` To have only a maximum "
|
"can be replaced by a \*. To have only a minimum value `key=min,\*` To have only a maximum "
|
||||||
"value `key=\*,max` <br>Graph data (if retrieved) is normalized"
|
"value `key=\*,max` <br>Graph data (if retrieved) is normalized"
|
||||||
" To only retrieve cells that don't have a value for the key filter by `key`",
|
" To only retrieve cells that don't have a value for the key filter by `key`",
|
||||||
'parameters': [],
|
"parameters": [],
|
||||||
|
|
||||||
'responses': {
|
"responses": {
|
||||||
'200': {
|
"200": {
|
||||||
'description': 'initialization data for UI',
|
"description": "initialization data for UI",
|
||||||
'examples': {
|
"examples": {
|
||||||
'application/json': {
|
"application/json": {
|
||||||
"data": {
|
"data": {
|
||||||
"badmetadatacount": 0,
|
"badmetadatacount": 0,
|
||||||
"cellcount": 0,
|
"cellcount": 0,
|
||||||
@@ -185,8 +185,8 @@ class CellsAPI(Resource):
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
'400': {
|
"400": {
|
||||||
'description': 'bad query params',
|
"description": "bad query params",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -212,21 +212,21 @@ class CellsAPI(Resource):
|
|||||||
|
|
||||||
class ExpressionAPI(Resource):
|
class ExpressionAPI(Resource):
|
||||||
@swagger.doc({
|
@swagger.doc({
|
||||||
'summary': 'Json with gene list and expression data by cell, limited to first 40 cells',
|
"summary": "Json with gene list and expression data by cell, limited to first 40 cells",
|
||||||
'tags': ['expression'],
|
"tags": ["expression"],
|
||||||
'parameters': [
|
"parameters": [
|
||||||
{
|
{
|
||||||
'name': 'include_unexpressed_genes',
|
"name": "include_unexpressed_genes",
|
||||||
'description': "Include genes that have 0 expression across all cells in set",
|
"description": "Include genes that have 0 expression across all cells in set",
|
||||||
'in': 'path',
|
"in": "path",
|
||||||
'type': 'bool',
|
"type": "bool",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'responses': {
|
"responses": {
|
||||||
'200': {
|
"200": {
|
||||||
'description': 'Json for heatmap',
|
"description": "Json for heatmap",
|
||||||
'examples': {
|
"examples": {
|
||||||
'application/json': {
|
"application/json": {
|
||||||
"data": {
|
"data": {
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
@@ -258,12 +258,12 @@ class ExpressionAPI(Resource):
|
|||||||
return make_payload(expression_data)
|
return make_payload(expression_data)
|
||||||
|
|
||||||
@swagger.doc({
|
@swagger.doc({
|
||||||
'summary': 'Json with gene list and expression data by cell',
|
"summary": "Json with gene list and expression data by cell",
|
||||||
'tags': ['expression'],
|
"tags": ["expression"],
|
||||||
'parameters': [
|
"parameters": [
|
||||||
{
|
{
|
||||||
'name': 'body',
|
"name": "body",
|
||||||
'in': 'body',
|
"in": "body",
|
||||||
"schema": {
|
"schema": {
|
||||||
"example": {
|
"example": {
|
||||||
"celllist": ["1001000173.G8", "1001000173.D4"],
|
"celllist": ["1001000173.G8", "1001000173.D4"],
|
||||||
@@ -275,11 +275,11 @@ class ExpressionAPI(Resource):
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'responses': {
|
"responses": {
|
||||||
'200': {
|
"200": {
|
||||||
'description': 'Json for expressiondata',
|
"description": "Json for expressiondata",
|
||||||
'examples': {
|
"examples": {
|
||||||
'application/json': {
|
"application/json": {
|
||||||
"data": {
|
"data": {
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
@@ -305,24 +305,24 @@ class ExpressionAPI(Resource):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'400': {
|
"400": {
|
||||||
'description': 'Required parameter missing/incorrect',
|
"description": "Required parameter missing/incorrect",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
def post(self):
|
def post(self):
|
||||||
from app import data
|
from app import data
|
||||||
args = request.get_json()
|
args = request.get_json()
|
||||||
cell_list = args.get('celllist', [])
|
cell_list = args.get("celllist", [])
|
||||||
gene_list = args.get('genelist', [])
|
gene_list = args.get("genelist", [])
|
||||||
if not cell_list and not gene_list:
|
if not cell_list and not gene_list:
|
||||||
return make_payload([], "must include celllist and/or genelist parameter", 400)
|
return make_payload([], "must include celllist and/or genelist parameter", 400)
|
||||||
|
|
||||||
expression_data = data.expression(cell_list, gene_list)
|
expression_data = data.expression(cell_list, gene_list)
|
||||||
|
|
||||||
if cell_list and len(expression_data['cells']) < len(cell_list):
|
if cell_list and len(expression_data["cells"]) < len(cell_list):
|
||||||
return make_payload([], "Some cell ids not available", 400)
|
return make_payload([], "Some cell ids not available", 400)
|
||||||
if gene_list and len(expression_data['genes']) < len(gene_list):
|
if gene_list and len(expression_data["genes"]) < len(gene_list):
|
||||||
return make_payload([], "Some genes not available", 400)
|
return make_payload([], "Some genes not available", 400)
|
||||||
|
|
||||||
return make_payload(expression_data)
|
return make_payload(expression_data)
|
||||||
@@ -330,13 +330,13 @@ class ExpressionAPI(Resource):
|
|||||||
|
|
||||||
class DifferentialExpressionAPI(Resource):
|
class DifferentialExpressionAPI(Resource):
|
||||||
@swagger.doc({
|
@swagger.doc({
|
||||||
'summary': 'Get the top expressed genes for two cell sets. Calculated using t-test',
|
"summary": "Get the top expressed genes for two cell sets. Calculated using t-test",
|
||||||
'tags': ['expression'],
|
"tags": ["expression"],
|
||||||
'parameters': [
|
"parameters": [
|
||||||
{
|
{
|
||||||
'name': 'body',
|
"name": "body",
|
||||||
'in': 'body',
|
"in": "body",
|
||||||
'schema': {
|
"schema": {
|
||||||
"example": {
|
"example": {
|
||||||
"celllist1": ["1001000176.C12", "1001000176.C7", "1001000177.F11"],
|
"celllist1": ["1001000176.C12", "1001000176.C7", "1001000177.F11"],
|
||||||
"celllist2": ["1001000012.D2", "1001000017.F10", "1001000033.C3", "1001000229.D4"],
|
"celllist2": ["1001000012.D2", "1001000017.F10", "1001000033.C3", "1001000229.D4"],
|
||||||
@@ -347,10 +347,10 @@ class DifferentialExpressionAPI(Resource):
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
'200': {
|
"200": {
|
||||||
'description': 'top expressed genes for cellset1, cellset2',
|
"description": "top expressed genes for cellset1, cellset2",
|
||||||
'examples': {
|
"examples": {
|
||||||
'application/json': {
|
"application/json": {
|
||||||
"data": {
|
"data": {
|
||||||
"celllist1": {
|
"celllist1": {
|
||||||
"ave_diff": [
|
"ave_diff": [
|
||||||
@@ -419,10 +419,10 @@ class DifferentialExpressionAPI(Resource):
|
|||||||
def post(self):
|
def post(self):
|
||||||
from app import data
|
from app import data
|
||||||
args = request.get_json()
|
args = request.get_json()
|
||||||
cell_list_1 = args.get('celllist1', [])
|
cell_list_1 = args.get("celllist1", [])
|
||||||
cell_list_2 = args.get('celllist2', [])
|
cell_list_2 = args.get("celllist2", [])
|
||||||
num_genes = args.get("num_genes", 7)
|
num_genes = args.get("num_genes", 7)
|
||||||
pval = args.get('pval', 0.5)
|
pval = args.get("pval", 0.5)
|
||||||
if not (cell_list_1 and cell_list_2):
|
if not (cell_list_1 and cell_list_2):
|
||||||
return make_payload([],
|
return make_payload([],
|
||||||
"must include celllist1 and celllist2 parameters",
|
"must include celllist1 and celllist2 parameters",
|
||||||
@@ -432,7 +432,7 @@ class DifferentialExpressionAPI(Resource):
|
|||||||
|
|
||||||
|
|
||||||
def get_api_resources():
|
def get_api_resources():
|
||||||
bp = Blueprint('api', __name__, url_prefix='/api/v2.0')
|
bp = Blueprint("api", __name__, url_prefix="/api/v2.0")
|
||||||
api = Api(bp, add_api_spec_resource=False)
|
api = Api(bp, add_api_spec_resource=False)
|
||||||
api.add_resource(InitializeAPI, "/initialize")
|
api.add_resource(InitializeAPI, "/initialize")
|
||||||
api.add_resource(CellsAPI, "/cells")
|
api.add_resource(CellsAPI, "/cells")
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ class ScanpyEngine(CXGDriver):
|
|||||||
return data_schema
|
return data_schema
|
||||||
|
|
||||||
def _set_cell_ids(self):
|
def _set_cell_ids(self):
|
||||||
self.data.obs['cxg_cell_id'] = list(range(self.data.obs.shape[0]))
|
self.data.obs["cxg_cell_id"] = list(range(self.data.obs.shape[0]))
|
||||||
self.data.obs["cell_name"] = list(self.data.obs.index)
|
self.data.obs["cell_name"] = list(self.data.obs.index)
|
||||||
self.data.obs.set_index('cxg_cell_id', inplace=True)
|
self.data.obs.set_index("cxg_cell_id", inplace=True)
|
||||||
|
|
||||||
def cells(self):
|
def cells(self):
|
||||||
return list(self.data.obs.index)
|
return list(self.data.obs.index)
|
||||||
@@ -78,7 +78,7 @@ class ScanpyEngine(CXGDriver):
|
|||||||
if self.schema[field]["variabletype"] == "categorical":
|
if self.schema[field]["variabletype"] == "categorical":
|
||||||
group_by = field
|
group_by = field
|
||||||
if group_by == "CellName":
|
if group_by == "CellName":
|
||||||
group_by = 'cell_name'
|
group_by = "cell_name"
|
||||||
metadata_ranges[field] = {"options": df.obs.groupby(group_by).size().to_dict()}
|
metadata_ranges[field] = {"options": df.obs.groupby(group_by).size().to_dict()}
|
||||||
else:
|
else:
|
||||||
metadata_ranges[field] = {
|
metadata_ranges[field] = {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ from flask import (
|
|||||||
Blueprint, render_template, url_for, current_app
|
Blueprint, render_template, url_for, current_app
|
||||||
)
|
)
|
||||||
|
|
||||||
bp = Blueprint('webapp', __name__, template_folder='templates')
|
bp = Blueprint("webapp", __name__, template_folder="templates")
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/')
|
@bp.route("/")
|
||||||
def index():
|
def index():
|
||||||
url_base = current_app.config["CXG_API_BASE"]
|
url_base = current_app.config["CXG_API_BASE"]
|
||||||
dataset_title = current_app.config["DATASET_TITLE"]
|
dataset_title = current_app.config["DATASET_TITLE"]
|
||||||
@@ -13,12 +13,12 @@ def index():
|
|||||||
|
|
||||||
|
|
||||||
# renders swagger documentation
|
# renders swagger documentation
|
||||||
@bp.route('/swagger')
|
@bp.route("/swagger")
|
||||||
def swag():
|
def swag():
|
||||||
return render_template("swagger.html")
|
return render_template("swagger.html")
|
||||||
|
|
||||||
|
|
||||||
# renders swagger documentation
|
# renders swagger documentation
|
||||||
@bp.route('/favicon.png')
|
@bp.route("/favicon.png")
|
||||||
def favicon():
|
def favicon():
|
||||||
return url_for("static", filename="img/favicon.png")
|
return url_for("static", filename="img/favicon.png")
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
from app import app
|
from app import app
|
||||||
|
|
||||||
app.run(host='0.0.0.0', debug=True, port=5005)
|
app.run(host="0.0.0.0", debug=True, port=5005)
|
||||||
|
|||||||
Reference in New Issue
Block a user