Source code for buildcompiler.sbol.resolver

"""SBOL document resolver with deterministic pull policy."""

from __future__ import annotations

from enum import Enum
from typing import Any, Callable

import sbol2


[docs] class PullPolicy(str, Enum): """Resolver behavior for remote pull attempts.""" NEVER = "never" MISSING_ONLY = "missing_only" ALWAYS_REFRESH = "always_refresh"
[docs] class SbolResolver: """Resolve SBOL objects by identity from a local document with optional pull fallback.""" def __init__( self, document: sbol2.Document, *, pull_policy: PullPolicy = PullPolicy.MISSING_ONLY, pull_client: Callable[[str], Any] | None = None, ) -> None: self.document = document self.pull_policy = pull_policy self.pull_client = pull_client
[docs] def maybe_pull(self, identity: str) -> Any | None: if self.pull_policy == PullPolicy.NEVER: return None if self.pull_client is None: return None return self.pull_client(identity)
def _get(self, identity: str, expected_type: type) -> Any: if self.pull_policy == PullPolicy.ALWAYS_REFRESH: pulled = self.maybe_pull(identity) if isinstance(pulled, expected_type): return pulled obj = self.document.find(identity) if isinstance(obj, expected_type): return obj if self.pull_policy == PullPolicy.MISSING_ONLY: pulled = self.maybe_pull(identity) if isinstance(pulled, expected_type): return pulled obj = self.document.find(identity) if isinstance(obj, expected_type): return obj raise LookupError( f"Could not resolve {expected_type.__name__} with identity '{identity}'" )
[docs] def get_component(self, identity: str) -> sbol2.ComponentDefinition: return self._get(identity, sbol2.ComponentDefinition)
[docs] def get_module(self, identity: str) -> sbol2.ModuleDefinition: return self._get(identity, sbol2.ModuleDefinition)
[docs] def get_combinatorial_derivation( self, identity: str ) -> sbol2.CombinatorialDerivation: return self._get(identity, sbol2.CombinatorialDerivation)
[docs] def get_implementation(self, identity: str) -> sbol2.Implementation: return self._get(identity, sbol2.Implementation)