Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
aaxelb committed Jan 26, 2024
1 parent d104605 commit d0eff8e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
20 changes: 17 additions & 3 deletions gravyladle_toolkit/capability.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import inspect
import logging

from gravyvalet.namespaces import GRAVY


_logger = logging.getLogger(__name__)


###
# ONE OPTION: use decorators to declare capability identifiers on interface methods


def immediate_capability(capability_iri, *, requires):
# decorator for capabilities that can be computed immediately,
# without sending any requests or waiting on external resources
Expand Down Expand Up @@ -40,19 +45,22 @@ def _decorator(fn):
###
# helpers for capability methods


def get_supported_capabilities(interface):
return set(_get_capability_method_map(interface).keys())


def get_capability_method(interface_instance, capability_iri):
_methodname = _get_capability_method_map(interface_instance).get(capability_iri)
if _methodname is not None:
return getattr(interface_instance, _methodname)
_method = getattr(interface_instance, _methodname)
# TODO: check whether it's abstract


###
# module-private helpers


def _get_capability_method_map(obj):
try:
return getattr(obj, GRAVY.capability_map)
Expand All @@ -63,16 +71,22 @@ def _get_capability_method_map(obj):
def _compute_capability_method_map(obj):
_capability_method_map = {}
for _methodname, _fn in inspect.getmembers(obj, inspect.ismethod):
# TODO: intent is to make it easy to implement the capabilities you are
# trying to support while ignoring all the rest (until you want them).
# on the base class, declare and decorate methods for each supported
# capability, then implementers may implement (or not implement) any or
# all of them -- this doesn't quite do all that, maybe try from __new__?
try:
_capability_iri = getattr(_fn, GRAVY.capability)
except AttributeError:
pass # not a capability implementation
else:
assert _capability_iri not in _capability_method_map, (
f'duplicate implementations of capability <{_capability_iri}>'
f'(conflicting: {_fn}, {_capability_method_map[_capability_iri]})'
f"duplicate implementations of capability <{_capability_iri}>"
f"(conflicting: {_fn}, {_capability_method_map[_capability_iri]})"
)
_capability_method_map[_capability_iri] = _methodname
_logger.info("found capability methods on %r: %r", obj, _capability_method_map)
setattr(obj, GRAVY.capability_map, _capability_method_map)
return _capability_method_map

Expand Down
17 changes: 13 additions & 4 deletions gravyladle_toolkit/gatherstorage_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@
proxy_act_capability,
proxy_read_capability,
)
from .interfaces import (
BaseAddonInterface,
PagedResult,
)
from .interfaces import PagedResult


# what an example gravy:StorageInterface implementation could be like (class-based)
STORAGE_INTERFACE_NORMS = gather.GatheringNorms(
namestory=(
rdf.Literal("Storage interface norms", language="en"),
rdf.Literal("Norms for an interface with a storage service", language="en"),
),
focustype_iris={},
)


class StorageInterfaceOrganizer(gather.GatheringOrganizer):
norms = STORAGE_INTERFACE_NORMS
thesaurus = {}


class StorageInterface(BaseAddonInterface):
Expand Down
22 changes: 22 additions & 0 deletions gravyladle_toolkit/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,25 @@ async def get_version_ids(self, item_id: str) -> PagedResult[str]:
)
async def pls_restore_version(self, item_id: str, version_id: str):
raise NotImplementedError


if __debug__: # examples

class _ExampleStorageImplementation(StorageInterface):
def item_download_url(self, item_id: str) -> str:
return self._waterbutler_download_url(item_id)

async def get_item_description(self, item_id: str) -> dict:
return item_id # stub

def item_upload_url(self, item_id: str) -> str:
return self._waterbutler_upload_url(item_id)

async def pls_delete_item(self, item_id: str):
raise NotImplementedError

def _waterbutler_download_url(self, item_id):
raise NotImplementedError

def _waterbutler_upload_url(self, item_id):
raise NotImplementedError

0 comments on commit d0eff8e

Please sign in to comment.