operonx.core.registry¶
Resource hub, configuration storage, and op registry.
ResourceHub¶
ResourceHub
¶
Centralized registry for managing application resources.
Features:
- Lazy loading: resources are initialized on first access
- Pluggable storage: YAML, JSON, or custom backend
- Extensible: external packages register their configs and factories
(REGISTRY.register, found through an operonx.resources
entry point when nothing imported the package)
Example
hub = ResourceHub.from_yaml("configs/resources.yaml") llm = hub.get("llm:gpt-4o") index = hub.get("vector_store:docs")
Or use global hub¶
from operonx.core.registry import ResourceHub llm = ResourceHub.instance().get("llm:gpt-4o")
Initialize hub with storage backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
storage
|
ConfigStorage
|
Storage backend for configs |
required |
source_path
|
Optional[Path]
|
Absolute path of the file the storage was loaded
from (set by |
None
|
Source code in operonx/core/registry/resource_hub.py
Attributes¶
Methods:¶
from_yaml
classmethod
¶
Create hub with YAML file storage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to YAML config file |
required |
Returns:
| Type | Description |
|---|---|
ResourceHub
|
ResourceHub instance |
Source code in operonx/core/registry/resource_hub.py
from_json
classmethod
¶
Create hub with JSON file storage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to JSON config file |
required |
Returns:
| Type | Description |
|---|---|
ResourceHub
|
ResourceHub instance |
Source code in operonx/core/registry/resource_hub.py
auto
classmethod
¶
Try to install ResourceHub from ./resources.yaml in CWD.
Behavior:
- If a hub is already installed, return it unchanged (idempotent).
- If ./resources.yaml exists, load it, install the singleton,
and return the new hub.
- If not found, emit a :class:ResourceHubWarning naming the path
checked and return None. No singleton is installed.
Never raises. The warning is the early signal that setup is incomplete; silent miss would defer the problem to first resource resolution.
Source code in operonx/core/registry/resource_hub.py
instance
classmethod
¶
Get the global ResourceHub singleton.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If no hub has been loaded. The message points at
|
Source code in operonx/core/registry/resource_hub.py
set_instance
classmethod
¶
reset_instance
classmethod
¶
alias
¶
Point alias_key at an existing resource, in memory only.
For naming a role at the call site while an operator still chooses the resource that fills it::
hub.alias("llm:scanner", f"llm:{os.environ['LLM_RESOURCE_KEY']}")
# graph stays literal: LLMOp.of(resource="scanner", ...)
That keeps the wiring readable to tooling — which can only see a literal — without freezing the model choice into the graph.
Not :meth:register: that persists through to storage and
rewrites resources.yaml, losing its comments. This touches
nothing on disk and lasts for the life of the hub.
Resolution is one hop, applied on every lookup, so re-aliasing later repoints existing call sites. A cached instance under the old target is unaffected — it is keyed by the real name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alias_key
|
str
|
The name call sites use, e.g. |
required |
target_key
|
str
|
An existing resource key, e.g. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
The alias would point at itself, or target_key is itself an alias — one hop only, so a chain that could silently become a cycle is refused at declaration time rather than hanging at first use. |
Source code in operonx/core/registry/resource_hub.py
aliases
¶
unalias
¶
keys
¶
Every declared key: those in storage, then any registered in
memory only. Parses nothing — :meth:get reports a key that does
not build, and :meth:health_check reports all of them.
Source code in operonx/core/registry/resource_hub.py
declares
¶
Whether key is configured, without loading it.
Unlike :meth:has this parses nothing and caches nothing: a check
made before a project has imported the module that registers a
custom category must not leave that key cached as a raw dict that
:meth:get then refuses.
Source code in operonx/core/registry/resource_hub.py
has
¶
Whether key is configured. The same question as
:meth:declares: it parses nothing, so it neither fails on a
category not registered yet nor caches anything.
get
¶
Get resource instance by key (lazy load on first access).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Registry key of resource |
required |
Returns:
| Type | Description |
|---|---|
Any
|
Initialized resource instance |
Raises:
| Type | Description |
|---|---|
KeyError
|
If key not found, its config does not parse, or the
resource failed to initialize. The message says which,
with |
ResourceCategoryError
|
A |
EnvVarUnsetError
|
If the resource references a |
Source code in operonx/core/registry/resource_hub.py
get_config
¶
Get config object of resource.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Registry key |
required |
Returns:
| Type | Description |
|---|---|
YamlModel
|
Resource config |
Raises:
| Type | Description |
|---|---|
KeyError
|
If key not found |
Source code in operonx/core/registry/resource_hub.py
register
¶
Register new resource config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
YamlModel
|
Resource config object |
required |
registry_key
|
Optional[str]
|
Custom key (auto-generated if not provided) |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Registry key used |
Source code in operonx/core/registry/resource_hub.py
remove
¶
Remove resource from registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Registry key to remove |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if removed, False if not found |
Source code in operonx/core/registry/resource_hub.py
clear
¶
Clear all resources from registry and storage.
close
¶
keycloak
¶
Get KeycloakTokenProvider by key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Keycloak config identifier (e.g., 'myapp') |
required |
Returns:
| Type | Description |
|---|---|
KeycloakTokenProvider
|
KeycloakTokenProvider instance with get_token() method |
Source code in operonx/core/registry/resource_hub.py
oauth2
¶
Get an OAuth2TokenProvider by key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
OAuth2 config identifier (e.g. |
required |
Returns:
| Type | Description |
|---|---|
OAuth2TokenProvider
|
OAuth2TokenProvider instance with a |
Source code in operonx/core/registry/resource_hub.py
warmup
async
¶
Pre-warm a resource's connection (e.g. LLM prompt cache).
Forces lazy-load of the resource, then calls its warmup()
method if it exists. For LLM providers this typically sends a
minimal API request to establish the TCP+TLS connection and
optionally seed the server-side prompt cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Registry key (e.g. |
required |
**kwargs
|
Any
|
Passed to the resource's |
{}
|
Example::
hub = ResourceHub.instance()
await hub.warmup("llm:default", system_prompt=sys_prompt)
Source code in operonx/core/registry/resource_hub.py
health_check
¶
health_check(
keys: Optional[List[str]] = None,
*,
probe: bool = False,
timeout: float = 2.0,
) -> HealthCheckResult
Check all or specified resources: does each build, and answer?
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
Optional[List[str]]
|
Keys to check. None checks every configured resource. |
None
|
probe
|
bool
|
Also open a TCP connection to whatever address the config points at. Building a client opens no socket, so without this a hub full of corporate endpoints reports healthy on a laptop with the VPN down — and the real symptom arrives later as every call timing out one at a time. Resources with no address (in-memory, filesystem) are built and not probed. Off by default: this method has always meant "does it
construct", and flipping that would quietly change the
answer for every existing caller. |
False
|
timeout
|
float
|
Seconds to wait for the connection. Short on purpose: the point is to fail at startup rather than across a batch, so a slow answer is as useful to us as no answer. |
2.0
|
Returns:
| Type | Description |
|---|---|
HealthCheckResult
|
HealthCheckResult. Never raises for an unhealthy resource — see |
HealthCheckResult
|
|
Example
result = hub.health_check() if not result.healthy: print(f"Unhealthy resources: {result.failed}")
Source code in operonx/core/registry/resource_hub.py
require_reachable
¶
Check the named resources and raise if any cannot be reached.
No arguments checks every configured resource::
hub.require_reachable() # all of them
hub.require_reachable("llm:scorer", "embedding:corpus")
Every failure is collected before raising, so one run names everything that is missing rather than the first thing.
Raises:
| Type | Description |
|---|---|
ResourceUnreachable
|
when any checked resource failed. |
Source code in operonx/core/registry/resource_hub.py
Errors and warnings¶
EnvVarUnsetError
¶
Bases: RuntimeError
Raised when a required ${VAR} reference cannot be resolved.
Subclasses RuntimeError so existing except RuntimeError callers
continue to work — this preserves backwards-compatible behavior with
the previous _raise_missing_env_vars helper.
ResourceHubWarning
¶
Bases: UserWarning
Warning emitted by ResourceHub setup (auto / from_yaml / bootstrap).
Subclassing UserWarning lets users silence ResourceHub-specific
warnings without muting unrelated UserWarning traffic::
import warnings
from operonx.core.registry import ResourceHubWarning
warnings.filterwarnings("ignore", category=ResourceHubWarning)
ResourceCategoryError
¶
Bases: KeyError
A resource key's category has no config class to parse it with.
Either no package registers the category, or the package that should
(an operonx.resources entry point) failed to. Subclasses
KeyError because :meth:ResourceHub.get has always raised that
for a resource it cannot build, and callers catch it.
Bootstrap state¶
BOOTSTRAP_ENV_PATHS is populated by operonx.bootstrap
and surfaces in the EnvVarUnsetError message so you can see exactly which
.env paths were searched.