Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "/" GET/HEAD endpoints to check server status #92

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions h5grove/fastapi_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
__all__ = [
"router",
"settings",
"get_root",
"get_attr",
"get_data",
"get_meta",
Expand Down Expand Up @@ -75,6 +76,12 @@ async def add_base_path(file):
return f"{settings.base_dir}/{file}" if settings.base_dir else file


@router.api_route("/", methods=["GET", "HEAD"])
async def get_root():
"""`/` endpoint handler to check server status"""
return Response("ok")


@router.get("/attr/")
async def get_attr(
file: str = Depends(add_base_path),
Expand Down
7 changes: 7 additions & 0 deletions h5grove/flask_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@


__all__ = [
"root_route",
"attr_route",
"data_route",
"meta_route",
Expand Down Expand Up @@ -51,6 +52,11 @@ def create_error(status_code: int, message: str):
)


def root_route():
"""`/` endpoint handler to check server status"""
return "ok"


def attr_route():
"""`/attr/` endpoint handler"""
filename = get_filename(request)
Expand Down Expand Up @@ -110,6 +116,7 @@ def stats_route():


URL_RULES = {
"/": root_route,
"/attr/": attr_route,
"/data/": data_route,
"/meta/": meta_route,
Expand Down
22 changes: 17 additions & 5 deletions h5grove/tornado_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .utils import parse_bool_arg

__all__ = [
"RootHandler",
"BaseHandler",
"AttributeHandler",
"DataHandler",
Expand Down Expand Up @@ -69,6 +70,16 @@ def write_error(self, status_code: int, **kwargs: Any) -> None:
self.finish({"message": self._reason})


class RootHandler(BaseHandler):
"""`/` endpoint handler to check server status"""

def get(self):
self.finish("ok")

def head(self):
self.finish()


class ContentHandler(BaseHandler):
def get_response(
self, full_file_path: str, path: Optional[str], resolve_links: Optional[str]
Expand All @@ -85,7 +96,7 @@ def get_content_response(self, content: EntityContent) -> Response:


class AttributeHandler(ContentHandler):
"""/attr/ endpoint handler"""
"""`/attr/` endpoint handler"""

def get_content_response(self, content: EntityContent) -> Response:
assert isinstance(content, ResolvedEntityContent)
Expand All @@ -96,7 +107,7 @@ def get_content_response(self, content: EntityContent) -> Response:


class DataHandler(ContentHandler):
"""/data/ endpoint handler"""
"""`/data/` endpoint handler"""

def get_content_response(self, content: EntityContent) -> Response:
dtype = self.get_query_argument("dtype", None)
Expand All @@ -112,14 +123,14 @@ def get_content_response(self, content: EntityContent) -> Response:


class MetadataHandler(ContentHandler):
"""/meta/ endpoint handler"""
"""`/meta/` endpoint handler"""

def get_content_response(self, content: EntityContent) -> Response:
return encode(content.metadata())


class StatisticsHandler(ContentHandler):
"""/stats/ endpoint handler"""
"""`/stats/` endpoint handler"""

def get_content_response(self, content: EntityContent) -> Response:
selection = self.get_query_argument("selection", None)
Expand All @@ -140,14 +151,15 @@ def get_response(

# TODO: Setting the return type raises mypy errors
def get_handlers(base_dir: Optional[str], allow_origin: Optional[str] = None):
"""Build h5grove handlers (`/attr`, `/data`, `/meta` and `/stats`).
"""Build h5grove handlers (`/`, `/attr/`, `/data/`, `/meta/` and `/stats/`).
:param base_dir: Base directory from which the HDF5 files will be served
:param allow_origin: Allowed origins for CORS
:return type: List[Tuple[str, BaseHandler, dict]]
"""
init_args = {"base_dir": base_dir, "allow_origin": allow_origin}
return [
(r"/", RootHandler, init_args),
(r"/attr/.*", AttributeHandler, init_args),
(r"/data/.*", DataHandler, init_args),
(r"/meta/.*", MetadataHandler, init_args),
Expand Down
5 changes: 5 additions & 0 deletions test/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ def server(self) -> Generator[BaseServer, None, None]:
"""Override in subclass with a fixture providing a :class:`BaseServer`"""
raise NotImplementedError()

def test_ping(self, server):
"""Test / endpoint used for checking server status"""
get_response = server.get("/")
assert get_response.content == b"ok"

def test_attr_on_root(self, server):
"""Test /attr/ endpoint on root group"""
# Test condition
Expand Down
Loading