Skip to content

Commit

Permalink
couple collection_id and layer_group_id; better error responses
Browse files Browse the repository at this point in the history
  • Loading branch information
akhileshh committed Aug 24, 2024
1 parent e107efb commit 6becd9b
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 25 deletions.
9 changes: 8 additions & 1 deletion web_api/app/annotations.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# pylint: disable=all # type: ignore
from typing import Annotated

from fastapi import FastAPI, Query
from fastapi import FastAPI, Query, Request

from zetta_utils.db_annotations.annotation import (
add_annotation,
Expand All @@ -15,9 +15,16 @@
update_annotations,
)

from .utils import generic_exception_handler

api = FastAPI()


@api.exception_handler(Exception)
async def generic_handler(request: Request, exc: Exception):
return generic_exception_handler(request, exc)


@api.get("/single/{annotation_id}")
async def read_single(annotation_id: str):
return read_annotation(annotation_id)
Expand Down
14 changes: 12 additions & 2 deletions web_api/app/collections.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# pylint: disable=all # type: ignore
from typing import Annotated

from fastapi import FastAPI, Query
from fastapi import FastAPI, HTTPException, Query, Request

from zetta_utils.db_annotations.collection import (
add_collection,
Expand All @@ -12,17 +12,27 @@
update_collection,
)

from .utils import generic_exception_handler

api = FastAPI()


@api.exception_handler(Exception)
async def generic_handler(request: Request, exc: Exception):
return generic_exception_handler(request, exc)


@api.get("/single/{collection_id}")
async def read_single(collection_id: str):
return read_collection(collection_id)


@api.post("/single")
async def add_single(name: str, user: str, comment: str | None = None):
return add_collection(name, user, comment=comment)
try:
return add_collection(name, user, comment=comment)
except KeyError:
raise HTTPException(status_code=409, detail=f"`{name}` exists.")


@api.put("/single")
Expand Down
20 changes: 16 additions & 4 deletions web_api/app/layer_groups.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# pylint: disable=all # type: ignore
from typing import Annotated

from fastapi import FastAPI, Query
from fastapi import FastAPI, HTTPException, Query, Request

from zetta_utils.db_annotations.layer_group import (
add_layer_group,
Expand All @@ -12,9 +12,16 @@
update_layer_group,
)

from .utils import generic_exception_handler

api = FastAPI()


@api.exception_handler(Exception)
async def generic_handler(request: Request, exc: Exception):
return generic_exception_handler(request, exc)


@api.get("/single/{layer_group_id}")
async def read_single(layer_group_id: str):
return read_layer_group(layer_group_id)
Expand All @@ -28,9 +35,14 @@ async def add_single(
layers: list[str] | None = None,
comment: str | None = None,
):
return add_layer_group(
name=name, collection_id=collection_id, user=user, layers=layers, comment=comment
)
try:
return add_layer_group(
name=name, collection_id=collection_id, user=user, layers=layers, comment=comment
)
except KeyError:
raise HTTPException(
status_code=409, detail=f"`{collection_id}` already has layer group `{name}`."
)


@api.put("/single")
Expand Down
9 changes: 8 additions & 1 deletion web_api/app/layers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# pylint: disable=all # type: ignore
from typing import Annotated

from fastapi import FastAPI, Query
from fastapi import FastAPI, Query, Request

from zetta_utils.db_annotations.layer import (
add_layer,
Expand All @@ -10,9 +10,16 @@
update_layer,
)

from .utils import generic_exception_handler

api = FastAPI()


@api.exception_handler(Exception)
async def generic_handler(request: Request, exc: Exception):
return generic_exception_handler(request, exc)


@api.get("/single/{layer_id}")
async def read_single(layer_id: str):
return read_layer(layer_id)
Expand Down
23 changes: 7 additions & 16 deletions web_api/app/painting.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@
from zetta_utils.geometry import Vec3D
from zetta_utils.layer.volumetric import VolumetricIndex
from zetta_utils.layer.volumetric.cloudvol import build_cv_layer
from zetta_utils.log import get_logger

logger = get_logger("zetta_ai")
from .utils import generic_exception_handler

api = FastAPI()


@api.exception_handler(Exception)
async def generic_handler(request: Request, exc: Exception):
return generic_exception_handler(request, exc)


@api.get("/cutout")
async def read_cutout(
path: Annotated[str, Query()],
Expand All @@ -25,19 +30,13 @@ async def read_cutout(
is_fortran: Annotated[bool, Query()] = True,
):
index = VolumetricIndex.from_coords(bbox_start, bbox_end, Vec3D(*resolution))
logger.info(f"Index: {index}")
layer = build_cv_layer(path, readonly=True)

data = np.ascontiguousarray(layer[index])
logger.info(f"Data shape: {data.shape}")
if is_fortran:
data = einops.rearrange(data, "C X Y Z -> Z Y X C")
logger.info(f"Data shape after rearrange: {data.shape}")
data_bytes = data.tobytes()
logger.info(f"Num bytes: {len(data_bytes)}")
compressed_data = gzip.compress(data_bytes)
logger.info(f"Num compressed bytes: {len(data_bytes)}")

return Response(content=compressed_data)


Expand All @@ -51,24 +50,16 @@ async def write_cutout(
is_fortran: Annotated[bool, Query()] = True,
):
index = VolumetricIndex.from_coords(bbox_start, bbox_end, Vec3D(*resolution))
logger.info(f"Index: {index}")
cv_kwargs = {"non_aligned_writes": True}
layer = build_cv_layer(path, cv_kwargs=cv_kwargs)
logger.info(f"Non aligned writes enabled: {layer.backend.enforce_chunk_aligned_writes}")
shape = [layer.backend.num_channels, *(np.array(bbox_end) - np.array(bbox_start))]

logger.info(f"Expected shape: {shape}")
data = await request.body()
logger.info(f"Compressed data len: {len(data)}")
# Decompress the gzipped data
data = gzip.decompress(data)
logger.info(f"Decompressed data len: {len(data)}")

if not is_fortran:
data_arr = np.frombuffer(data, dtype=layer.backend.dtype).reshape(shape)
else:
data_arr = np.frombuffer(data, dtype=layer.backend.dtype).reshape(shape[::-1])
data_arr = einops.rearrange(data_arr, "Z Y X C -> C X Y Z")

logger.info(f"Final data shape: {data_arr.shape}")
layer[index] = data_arr
17 changes: 17 additions & 0 deletions web_api/app/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# pylint: disable=all # type: ignore

import traceback

from fastapi import Request, Response

from zetta_utils.log import get_logger

logger = get_logger("web_api")


def generic_exception_handler(request: Request, exc: Exception):
logger.error(traceback.format_exc())
if isinstance(exc, KeyError):
if request.method == "GET":
return Response(status_code=404, content=repr(exc))
return Response(status_code=500, content=traceback.format_exc())
2 changes: 1 addition & 1 deletion zetta_utils/db_annotations/layer_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def add_layer_group(
layers: list[str] | None = None,
comment: str | None = None,
) -> str:
layer_group_id = name
layer_group_id = f"{collection_id}:{name}"
if layer_group_id in LAYER_GROUPS_DB:
raise KeyError(f"{layer_group_id} already exists.")
col_keys = INDEXED_COLS + NON_INDEXED_COLS
Expand Down

0 comments on commit 6becd9b

Please sign in to comment.