diff --git a/caveclient/endpoints.py b/caveclient/endpoints.py index 044e5f6e..3053ad01 100644 --- a/caveclient/endpoints.py +++ b/caveclient/endpoints.py @@ -299,6 +299,8 @@ skeletonservice_endpoints_v1 = { "get_version": skeleton_common + "/version", "skeleton_info": skeleton_v1 + "/{datastack_name}/precomputed/skeleton/info", + "skeleton_info_versioned": skeleton_v1 + + "/{datastack_name}/precomputed/skeleton/info/{skvn}", "get_skeleton_via_rid": skeleton_v1 + "/{datastack_name}/precomputed/skeleton/{root_id}", "get_skeleton_via_skvn_rid": skeleton_v1 diff --git a/caveclient/skeletonservice.py b/caveclient/skeletonservice.py index f880e8ae..785c451a 100644 --- a/caveclient/skeletonservice.py +++ b/caveclient/skeletonservice.py @@ -5,6 +5,7 @@ from typing import Literal, Optional import pandas as pd +from cachetools import TTLCache, cached from packaging.version import Version try: @@ -187,11 +188,36 @@ def build_endpoint( url = self._endpoints[endpoint].format_map(endpoint_mapping) return url + @cached(TTLCache(maxsize=32, ttl=3600)) + def get_precomputed_skeleton_info( + self, + skvn: int = 0, + datastack_name: Optional[str] = None, + ): + """get's the precomputed skeleton information + Args: + datastack_name (Optional[str], optional): _description_. Defaults to None. + """ + if not self.fc.l2cache.has_cache(): + raise NoL2CacheException("SkeletonClient requires an L2Cache.") + if datastack_name is None: + datastack_name = self._datastack_name + assert datastack_name is not None + + endpoint_mapping = self.default_url_mapping + endpoint_mapping["datastack_name"] = datastack_name + endpoint_mapping["skvn"] = skvn + url = self._endpoints["skeleton_info_versioned"].format_map(endpoint_mapping) + + response = self.session.get(url) + self.raise_for_status(response) + return response.json() + def get_skeleton( self, root_id: int, datastack_name: Optional[str] = None, - skeleton_version: Optional[int] = None, + skeleton_version: Optional[int] = 0, output_format: Literal[ "none", "h5", "swc", "json", "arrays", "precomputed" ] = "none", @@ -227,10 +253,6 @@ def get_skeleton( root_id, datastack_name, skeleton_version, output_format ) - if skeleton_version is None: - # I need code in this repo to access defaults defined in the SkeletonService repo, but wihout necesssarily importing it. - skeleton_version = 2 - response = self.session.get(url) self.raise_for_status(response, log_warning=log_warning) @@ -241,15 +263,10 @@ def get_skeleton( raise ImportError( "'precomputed' output format requires cloudvolume, which is not available." ) - vertex_attributes = [] - if skeleton_version == 2: - # I need code in this repo to access defaults defined in the SkeletonService repo, but wihout necesssarily importing it. - vertex_attributes.append( - {"id": "radius", "data_type": "float32", "num_components": 1} - ) - vertex_attributes.append( - {"id": "compartment", "data_type": "float32", "num_components": 1} - ) + metadata = self.get_precomputed_skeleton_info( + skeleton_version, datastack_name + ) + vertex_attributes = metadata["vertex_attributes"] return cloudvolume.Skeleton.from_precomputed( response.content, vertex_attributes=vertex_attributes )