mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-05 05:58:12 +08:00
Fix the /health endpoint (#1847)
* Fix the /health endpoint #1846 Keep both the old and new locations until the deployments are upgraded.
This commit is contained in:
+32
-6
@@ -99,6 +99,10 @@ def dataset_index(url_dataroot=None, dataset=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: This route will be deprecated, but needs to be left for a short time until all the
|
||||||
|
# deployments are upgraded to the new location for the health check (or else the upgrade will
|
||||||
|
# fail). Once the upgrade is complete, the deployments can move to the new health check URL
|
||||||
|
# and this route will be removed.
|
||||||
@webbp.route("/health", methods=["GET"])
|
@webbp.route("/health", methods=["GET"])
|
||||||
@cache_control_always(no_store=True)
|
@cache_control_always(no_store=True)
|
||||||
def health():
|
def health():
|
||||||
@@ -224,6 +228,13 @@ def dataroot_index():
|
|||||||
return redirect(config.server_config.multi_dataset__index)
|
return redirect(config.server_config.multi_dataset__index)
|
||||||
|
|
||||||
|
|
||||||
|
class HealthAPI(Resource):
|
||||||
|
@cache_control(no_store=True)
|
||||||
|
def get(self):
|
||||||
|
config = current_app.app_config
|
||||||
|
return health_check(config)
|
||||||
|
|
||||||
|
|
||||||
class DatasetResource(Resource):
|
class DatasetResource(Resource):
|
||||||
"""Base class for all Resources that act on datasets."""
|
"""Base class for all Resources that act on datasets."""
|
||||||
|
|
||||||
@@ -312,8 +323,18 @@ class LayoutObsAPI(DatasetResource):
|
|||||||
return common_rest.layout_obs_put(request, data_adaptor)
|
return common_rest.layout_obs_put(request, data_adaptor)
|
||||||
|
|
||||||
|
|
||||||
def get_api_resources(bp_api, url_dataroot=None):
|
def get_api_base_resources(bp_base):
|
||||||
api = Api(bp_api)
|
"""Add resources that are accessed from the api_base_url"""
|
||||||
|
api = Api(bp_base)
|
||||||
|
|
||||||
|
# Diagnostics routes
|
||||||
|
api.add_resource(HealthAPI, "/health")
|
||||||
|
return api
|
||||||
|
|
||||||
|
|
||||||
|
def get_api_dataroot_resources(bp_dataroot, url_dataroot=None):
|
||||||
|
"""Add resources that refer to a dataset"""
|
||||||
|
api = Api(bp_dataroot)
|
||||||
|
|
||||||
def add_resource(resource, url):
|
def add_resource(resource, url):
|
||||||
"""convenience function to make the outer function less verbose"""
|
"""convenience function to make the outer function less verbose"""
|
||||||
@@ -385,18 +406,23 @@ class Server:
|
|||||||
parse = urlparse(api_base_url)
|
parse = urlparse(api_base_url)
|
||||||
api_path = parse.path
|
api_path = parse.path
|
||||||
|
|
||||||
|
bp_base = Blueprint("bp_base", __name__, url_prefix=api_path)
|
||||||
|
base_resources = get_api_base_resources(bp_base)
|
||||||
|
self.app.register_blueprint(base_resources.blueprint)
|
||||||
|
|
||||||
if app_config.is_multi_dataset():
|
if app_config.is_multi_dataset():
|
||||||
# NOTE: These routes only allow the dataset to be in the directory
|
# NOTE: These routes only allow the dataset to be in the directory
|
||||||
# of the dataroot, and not a subdirectory. We may want to change
|
# of the dataroot, and not a subdirectory. We may want to change
|
||||||
# the route format at some point
|
# the route format at some point
|
||||||
for dataroot_dict in server_config.multi_dataset__dataroot.values():
|
for dataroot_dict in server_config.multi_dataset__dataroot.values():
|
||||||
url_dataroot = dataroot_dict["base_url"]
|
url_dataroot = dataroot_dict["base_url"]
|
||||||
bp_api = Blueprint(
|
bp_dataroot = Blueprint(
|
||||||
f"api_dataset_{url_dataroot}", __name__,
|
f"api_dataset_{url_dataroot}", __name__,
|
||||||
url_prefix=f"{api_path}/{url_dataroot}/<dataset>" + api_version
|
url_prefix=f"{api_path}/{url_dataroot}/<dataset>" + api_version
|
||||||
)
|
)
|
||||||
resources = get_api_resources(bp_api, url_dataroot)
|
dataroot_resources = get_api_dataroot_resources(bp_dataroot, url_dataroot)
|
||||||
self.app.register_blueprint(resources.blueprint)
|
self.app.register_blueprint(dataroot_resources.blueprint)
|
||||||
|
|
||||||
self.app.add_url_rule(
|
self.app.add_url_rule(
|
||||||
f"/{url_dataroot}/<dataset>/",
|
f"/{url_dataroot}/<dataset>/",
|
||||||
f"dataset_index_{url_dataroot}",
|
f"dataset_index_{url_dataroot}",
|
||||||
@@ -412,7 +438,7 @@ class Server:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
bp_api = Blueprint("api", __name__, url_prefix=f"{api_path}{api_version}")
|
bp_api = Blueprint("api", __name__, url_prefix=f"{api_path}{api_version}")
|
||||||
resources = get_api_resources(bp_api)
|
resources = get_api_dataroot_resources(bp_api)
|
||||||
self.app.register_blueprint(resources.blueprint)
|
self.app.register_blueprint(resources.blueprint)
|
||||||
self.app.add_url_rule(
|
self.app.add_url_rule(
|
||||||
"/static/<path:filename>",
|
"/static/<path:filename>",
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class AppConfigTest(unittest.TestCase):
|
|||||||
config = AppConfig()
|
config = AppConfig()
|
||||||
backend_port = find_available_port("localhost", 10000)
|
backend_port = find_available_port("localhost", 10000)
|
||||||
config.update_server_config(
|
config.update_server_config(
|
||||||
app__api_base_url=f"http://localhost:{backend_port}/additional/path/before/dataroot",
|
app__api_base_url=f"http://localhost:{backend_port}/additional/path",
|
||||||
multi_dataset__dataroot=f"{PROJECT_ROOT}/example-dataset"
|
multi_dataset__dataroot=f"{PROJECT_ROOT}/example-dataset"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -151,11 +151,21 @@ class AppConfigTest(unittest.TestCase):
|
|||||||
with test_server(["-p", str(backend_port)], app_config=config) as server:
|
with test_server(["-p", str(backend_port)], app_config=config) as server:
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
self.assertEqual(server, f"http://localhost:{backend_port}")
|
self.assertEqual(server, f"http://localhost:{backend_port}")
|
||||||
response = session.get(f"{server}/additional/path/before/dataroot/d/pbmc3k.h5ad/api/v0.2/config")
|
response = session.get(f"{server}/additional/path/d/pbmc3k.h5ad/api/v0.2/config")
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
data_config = response.json()
|
data_config = response.json()
|
||||||
self.assertEqual(data_config["config"]["displayNames"]["dataset"], "pbmc3k")
|
self.assertEqual(data_config["config"]["displayNames"]["dataset"], "pbmc3k")
|
||||||
|
|
||||||
|
# test the health check at the correct url
|
||||||
|
response = session.get(f"{server}/additional/path/health")
|
||||||
|
assert response.json()["status"] == "pass"
|
||||||
|
|
||||||
|
# also check that the old URL still works.
|
||||||
|
# NOTE: this old URL location will soon be deprecated, and when that happens
|
||||||
|
# this check can be removed.
|
||||||
|
response = session.get(f"{server}/health")
|
||||||
|
assert response.json()["status"] == "pass"
|
||||||
|
|
||||||
def test_configfile_with_specialization(self):
|
def test_configfile_with_specialization(self):
|
||||||
# test that per_dataset_config config load the default config, then the specialized config
|
# test that per_dataset_config config load the default config, then the specialized config
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user