mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-23 09:48:12 +08:00
Style guide cleanup
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
import os
|
||||
|
||||
from flask import Flask, url_for, g
|
||||
from flask import Flask
|
||||
from flask_compress import Compress
|
||||
from flask_cors import CORS
|
||||
from flask_restful_swagger_2 import get_swagger_blueprint
|
||||
|
||||
# from werkzeug.contrib.profiler import ProfilerMiddleware
|
||||
|
||||
from .web import webapp
|
||||
from .rest_api.rest import get_api_resources
|
||||
|
||||
@@ -14,11 +12,12 @@ app = Flask(__name__)
|
||||
Compress(app)
|
||||
CORS(app)
|
||||
|
||||
#Config
|
||||
# Config
|
||||
CONFIG_FILE = os.environ.get("CXG_CONFIG_FILE", default="scanpy-test.cfg")
|
||||
CXG_DIR = os.environ.get("CXG_DIRECTORY", default="/Users/charlotteweaver/Documents/Git/cxg-v2/data/")
|
||||
SECRET_KEY = os.environ.get("CXG_SECRET_KEY", default="SparkleAndShine")
|
||||
ENGINE = os.environ.get("CXG_ENGINE", default="scanpy")
|
||||
TITLE = os.environ.get("DATASET_TITLE", default="PBMC 3K")
|
||||
# TODO remove the 2 when this is prod
|
||||
CXG_API_BASE = os.environ.get("CXG_API_BASE2", default="http://0.0.0.0:5005/api/")
|
||||
|
||||
@@ -30,7 +29,8 @@ app.config.update(
|
||||
SECRET_KEY=SECRET_KEY,
|
||||
CXG_API_BASE=CXG_API_BASE,
|
||||
ENGINE=ENGINE,
|
||||
DATA=CXG_DIR
|
||||
DATA=CXG_DIR,
|
||||
DATASET_TITLE=TITLE
|
||||
)
|
||||
|
||||
app.config['PROFILE'] = True
|
||||
@@ -52,12 +52,13 @@ docs.append(resources.get_swagger_doc())
|
||||
|
||||
app.register_blueprint(webapp.bp)
|
||||
app.register_blueprint(resources.blueprint)
|
||||
app.register_blueprint(get_swagger_blueprint(docs, '/api/swagger', produces=["application/json"], title="cellxgene rest api",
|
||||
description='An API connecting ExpressionMatrix2 clustering algorithm to cellxgene'))
|
||||
app.register_blueprint(
|
||||
get_swagger_blueprint(docs, '/api/swagger', produces=["application/json"], title="cellxgene rest api",
|
||||
description='An API connecting ExpressionMatrix2 clustering algorithm to cellxgene'))
|
||||
|
||||
|
||||
app.add_url_rule('/', endpoint='index')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='0.0.0.0', debug=True, port=5005)
|
||||
app.run(host='0.0.0.0', debug=True, port=5005)
|
||||
|
||||
@@ -2,7 +2,6 @@ from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
class CXGDriver(metaclass=ABCMeta):
|
||||
|
||||
def __init__(self, data, schema=None, graph_method=None, diffexp_method=None):
|
||||
self.data = self._load_data(data)
|
||||
|
||||
@@ -51,10 +50,8 @@ class CXGDriver(metaclass=ABCMeta):
|
||||
:param fields: list of keys for metadata to return, returns all metadata values if not set.
|
||||
:return: Iterator for cellid + list of cells metadata values ex. [cell-id, val1, val2, val3]
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@abstractmethod
|
||||
def create_graph(self, df):
|
||||
"""
|
||||
@@ -64,7 +61,6 @@ class CXGDriver(metaclass=ABCMeta):
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@abstractmethod
|
||||
def diffexp(self, df1, df2):
|
||||
"""
|
||||
@@ -72,7 +68,8 @@ class CXGDriver(metaclass=ABCMeta):
|
||||
|
||||
:param df1: First set of cells
|
||||
:param df2: Second set of cells
|
||||
:return: Up in the air: I recommend [gene name, mean_expression_cells1, mean_expression_cells2, average_difference, statistic_value]
|
||||
:return: Up in the air: I recommend [gene name, mean_expression_cells1,
|
||||
mean_expression_cells2, average_difference, statistic_value]
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ class ExpressionAPI(Resource):
|
||||
args = request.get_json()
|
||||
cell_list = args.get('celllist', [])
|
||||
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)
|
||||
|
||||
expression_data = data.expression(cell_list, gene_list)
|
||||
@@ -327,6 +327,7 @@ class ExpressionAPI(Resource):
|
||||
|
||||
return make_payload(expression_data)
|
||||
|
||||
|
||||
class DifferentialExpressionAPI(Resource):
|
||||
@swagger.doc({
|
||||
'summary': 'Get the top expressed genes for two cell sets. Calculated using t-test',
|
||||
@@ -429,6 +430,7 @@ class DifferentialExpressionAPI(Resource):
|
||||
data = data.diffexp(cell_list_1, cell_list_2, pval, num_genes)
|
||||
return make_payload(data)
|
||||
|
||||
|
||||
def get_api_resources():
|
||||
bp = Blueprint('api', __name__, url_prefix='/api/v2.0')
|
||||
api = Api(bp, add_api_spec_resource=False)
|
||||
@@ -436,4 +438,4 @@ def get_api_resources():
|
||||
api.add_resource(CellsAPI, "/cells")
|
||||
api.add_resource(ExpressionAPI, "/expression")
|
||||
api.add_resource(DifferentialExpressionAPI, "/diffexp")
|
||||
return api
|
||||
return api
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import scanpy.api as sc
|
||||
import numpy as np
|
||||
from scipy import stats
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import scanpy.api as sc
|
||||
from scipy import stats
|
||||
|
||||
from ..util.schema_parse import parse_schema
|
||||
from ..driver.driver import CXGDriver
|
||||
|
||||
@@ -14,12 +15,10 @@ class ScanpyEngine(CXGDriver):
|
||||
self.schema = self._load_or_infer_schema(data, schema)
|
||||
self._set_cell_ids()
|
||||
self.cell_count = self.data.shape[0]
|
||||
# TODO Do I need this?
|
||||
self.gene_count = self.data.shape[1]
|
||||
self.graph_method = graph_method
|
||||
self.diffexp_method = diffexp_method
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _load_data(data):
|
||||
return sc.read(os.path.join(data, "data.h5ad"))
|
||||
@@ -30,7 +29,7 @@ class ScanpyEngine(CXGDriver):
|
||||
if not schema:
|
||||
pass
|
||||
else:
|
||||
data_schema = parse_schema(os.path.join(data,schema))
|
||||
data_schema = parse_schema(os.path.join(data, schema))
|
||||
return data_schema
|
||||
|
||||
def _set_cell_ids(self):
|
||||
@@ -102,7 +101,6 @@ class ScanpyEngine(CXGDriver):
|
||||
metadata[idx]["CellName"] = metadata[idx].pop("cell_name", None)
|
||||
return metadata
|
||||
|
||||
|
||||
def create_graph(self, df):
|
||||
"""
|
||||
Computes a n-d layout for cells through dimensionality reduction.
|
||||
@@ -112,12 +110,11 @@ class ScanpyEngine(CXGDriver):
|
||||
normalized_graph = (graph - graph.min()) / (graph.max() - graph.min())
|
||||
return np.hstack((df.obs["cell_name"].values.reshape(len(df.obs.index), 1), normalized_graph)).tolist()
|
||||
|
||||
|
||||
def diffexp(self, cell_list_1, cell_list_2, pval, num_genes):
|
||||
cells_idx_1 = np.in1d(self.data.obs["cell_name"], cell_list_1)
|
||||
cells_idx_2 = np.in1d(self.data.obs["cell_name"], cell_list_2)
|
||||
expression_1 = self.data.X[cells_idx_1,:]
|
||||
expression_2 = self.data.X[cells_idx_2,:]
|
||||
expression_1 = self.data.X[cells_idx_1, :]
|
||||
expression_2 = self.data.X[cells_idx_2, :]
|
||||
diff_exp = stats.ttest_ind(expression_1, expression_2)
|
||||
set1 = np.logical_and(diff_exp.pvalue < pval, diff_exp.statistic > 0)
|
||||
set2 = np.logical_and(diff_exp.pvalue < pval, diff_exp.statistic < 0)
|
||||
@@ -151,7 +148,7 @@ class ScanpyEngine(CXGDriver):
|
||||
"ave_diff": mean_diff2.tolist()[:num_genes]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def expression(self, cells=None, genes=None):
|
||||
"""
|
||||
:param df:
|
||||
@@ -185,11 +182,3 @@ class ScanpyEngine(CXGDriver):
|
||||
"cells": cell_data,
|
||||
"nonzero_gene_count": int(np.sum(expression.any(axis=0)))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class QueryStringError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def _convert_variable(datatype, variable):
|
||||
"""
|
||||
Convert variable to number (float/int)
|
||||
@@ -19,6 +20,7 @@ def _convert_variable(datatype, variable):
|
||||
except ValueError:
|
||||
raise
|
||||
|
||||
|
||||
def parse_filter(filter, schema):
|
||||
"""
|
||||
{key: variable_type
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import json
|
||||
|
||||
from numpy import float32, integer
|
||||
from flask import make_response, jsonify, Response
|
||||
|
||||
|
||||
class Float32JSONEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if isinstance(obj, float32):
|
||||
@@ -10,6 +12,7 @@ class Float32JSONEncoder(json.JSONEncoder):
|
||||
return int(obj)
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
|
||||
|
||||
def make_payload(data, errormessage="", errorcode=200):
|
||||
"""
|
||||
Creates JSON respons for requests
|
||||
@@ -31,13 +34,7 @@ def make_payload(data, errormessage="", errorcode=200):
|
||||
}
|
||||
}), errorcode)
|
||||
|
||||
|
||||
def make_streaming_response(data_generator, errorcode=200, content_type="application/json"):
|
||||
# TODO headers
|
||||
return Response(data_generator, status=errorcode, content_type=content_type)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from flask import (
|
||||
Blueprint, render_template, request, url_for, current_app
|
||||
Blueprint, render_template, url_for, current_app
|
||||
)
|
||||
|
||||
bp = Blueprint('webapp', __name__, template_folder='templates')
|
||||
|
||||
|
||||
@bp.route('/')
|
||||
def index():
|
||||
url_base = current_app.config["CXG_API_BASE"]
|
||||
@@ -16,6 +17,7 @@ def index():
|
||||
def swag():
|
||||
return render_template("swagger.html")
|
||||
|
||||
|
||||
# renders swagger documentation
|
||||
@bp.route('/favicon.png')
|
||||
def favicon():
|
||||
|
||||
+898
-3
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user