mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-11 14:50:56 +08:00
Add backend endpoint
This commit is contained in:
@@ -190,6 +190,11 @@ class SummarizeVarAPI(Resource):
|
|||||||
def post(self, data_adaptor):
|
def post(self, data_adaptor):
|
||||||
return common_rest.summarize_var_post(request, data_adaptor)
|
return common_rest.summarize_var_post(request, data_adaptor)
|
||||||
|
|
||||||
|
class SpatialImageAPI(Resource):
|
||||||
|
@rest_get_data_adaptor
|
||||||
|
def get(self, data_adaptor):
|
||||||
|
return common_rest.spatial_image_get(request, data_adaptor)
|
||||||
|
|
||||||
|
|
||||||
def get_api_base_resources(bp_base):
|
def get_api_base_resources(bp_base):
|
||||||
"""Add resources that are accessed from the api url"""
|
"""Add resources that are accessed from the api url"""
|
||||||
@@ -222,6 +227,8 @@ def get_api_dataroot_resources(bp_dataroot):
|
|||||||
# Computation routes
|
# Computation routes
|
||||||
add_resource(DiffExpObsAPI, "/diffexp/obs")
|
add_resource(DiffExpObsAPI, "/diffexp/obs")
|
||||||
add_resource(LayoutObsAPI, "/layout/obs")
|
add_resource(LayoutObsAPI, "/layout/obs")
|
||||||
|
# Spatial routes
|
||||||
|
add_resource(SpatialImageAPI, "/spatial/image")
|
||||||
return api
|
return api
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+37
-1
@@ -5,7 +5,7 @@ from http import HTTPStatus
|
|||||||
import zlib
|
import zlib
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from flask import make_response, jsonify, current_app, abort
|
from flask import make_response, jsonify, current_app, abort, send_file
|
||||||
from werkzeug.urls import url_unquote
|
from werkzeug.urls import url_unquote
|
||||||
|
|
||||||
from server.common.config.client_config import get_client_config
|
from server.common.config.client_config import get_client_config
|
||||||
@@ -397,3 +397,39 @@ def summarize_var_post(request, data_adaptor):
|
|||||||
|
|
||||||
key = request.args.get("key", default=None)
|
key = request.args.get("key", default=None)
|
||||||
return summarize_var_helper(request, data_adaptor, key, request.get_data())
|
return summarize_var_helper(request, data_adaptor, key, request.get_data())
|
||||||
|
|
||||||
|
def spatial_image_get(request, data_adaptor):
|
||||||
|
import io
|
||||||
|
import matplotlib.pyplot
|
||||||
|
|
||||||
|
resolution = "hires"
|
||||||
|
spatial = data_adaptor.get_spatial()
|
||||||
|
|
||||||
|
if len(list(spatial)) == 0:
|
||||||
|
return abort_and_log(HTTPStatus.BAD_REQUEST, "uns does not have spatial information")
|
||||||
|
|
||||||
|
library_id = list(spatial)[0]
|
||||||
|
if len(spatial) > 1:
|
||||||
|
current_app.logger.warning(f"More than one library found under uns.spatial, using library '{library_id}'")
|
||||||
|
|
||||||
|
if "images" not in spatial[library_id]:
|
||||||
|
return abort_and_log(HTTPStatus.BAD_REQUEST, "spatial information does not contain images")
|
||||||
|
|
||||||
|
if resolution not in spatial[library_id]["images"]:
|
||||||
|
return abort_and_log(HTTPStatus.BAD_REQUEST, f"spatial information does not contain requested resolution '{resolution}'")
|
||||||
|
|
||||||
|
response_image = io.BytesIO()
|
||||||
|
matplotlib.pyplot.imsave(response_image, spatial[library_id]["images"][resolution])
|
||||||
|
response_image.seek(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return send_file(response_image, attachment_filename=f"{library_id}-{resolution}.png", mimetype="image/png")
|
||||||
|
except (KeyError, DatasetAccessError) as e:
|
||||||
|
return abort_and_log(HTTPStatus.BAD_REQUEST, str(e), include_exc_info=True)
|
||||||
|
except PrepareError:
|
||||||
|
return abort_and_log(
|
||||||
|
HTTPStatus.NOT_IMPLEMENTED,
|
||||||
|
f"No spatial image available {request.path}",
|
||||||
|
loglevel=logging.ERROR,
|
||||||
|
include_exc_info=True,
|
||||||
|
)
|
||||||
|
|||||||
@@ -274,6 +274,9 @@ class AnndataAdaptor(DataAdaptor):
|
|||||||
df = df[fields]
|
df = df[fields]
|
||||||
return encode_matrix_fbs(df, col_idx=df.columns)
|
return encode_matrix_fbs(df, col_idx=df.columns)
|
||||||
|
|
||||||
|
def get_spatial(self):
|
||||||
|
return self.data.uns["spatial"]
|
||||||
|
|
||||||
def get_embedding_names(self):
|
def get_embedding_names(self):
|
||||||
"""
|
"""
|
||||||
Return pre-computed embeddings.
|
Return pre-computed embeddings.
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ flatten-dict>=0.2.0
|
|||||||
fsspec>=0.4.4,<0.8.0
|
fsspec>=0.4.4,<0.8.0
|
||||||
gunicorn>=20.0.4
|
gunicorn>=20.0.4
|
||||||
h5py>=3.0.0
|
h5py>=3.0.0
|
||||||
|
matplotlib>=3.5.0
|
||||||
numba>=0.51.2
|
numba>=0.51.2
|
||||||
numpy>=1.17.5
|
numpy>=1.17.5
|
||||||
packaging>=20.0
|
packaging>=20.0
|
||||||
|
|||||||
Reference in New Issue
Block a user