Use plugin collections for advanced querying¶
core.list() returns a PluginCollection — a snapshot of all registered plugins
with pre-built indexes for fast querying. Use it when you need to filter, inspect,
or call across multiple plugins at once.
Get the collection¶
- Call
core.list()after starting the core.
from uxok import Core
core = Core()
await core.start()
plugins = await core.list()
print(plugins.names) # ['auth', 'database', 'cache']
print(plugins.count) # 3
Filter by capability¶
- Use
collection.capability.provides()to find plugins that advertise a capability, orcollection.capability.consumes()to find plugins that declare a requirement.
# Plugins that provide the "storage" capability
storage_providers = plugins.capability.provides("storage")
# Plugins that require the "database" capability
database_consumers = plugins.capability.consumes("database")
# Inspect the first match descriptively
view = storage_providers.first()
if view:
print(view.name, view.provides)
A PluginView is a description, not a handle — it has no get_object()/call().
To resolve a provider to a live, usable object, request the capability itself:
Filter by hook or event¶
- Use
.hookand.eventthe same way:.provides()for plugins that register the point,.consumes()for plugins that listen to it.
# Plugins that register the "authenticate" hook
auth_hook_owners = plugins.hook.provides("authenticate")
# Plugins subscribed to "system.shutdown" events
shutdown_listeners = plugins.event.consumes("system.shutdown")
Narrow to active plugins¶
- Prepend
.activeto restrict a query to plugins currently in the"active"state.
.active is a synchronous property — no await needed.
Filter by uptime¶
- Call
await collection.uptime_over(seconds)to keep only plugins that have been running longer than the given threshold. Stale plugins (torn down since the snapshot was taken) are silently excluded.
Look up a plugin by name or ID¶
- Use
by_name()orby_id()for direct O(1) lookup against the root collection's pre-built indexes. Both return aPluginVieworNone.
view = plugins.by_name("auth")
if view and view.ready:
print(f"{view.name} is active")
view = plugins.by_id(some_uuid)
The view tells you a plugin exists and what it declares; to invoke it, obtain the
live instance via the kernel.lifecycle grant (get_plugin) or resolve the
capability it provides.
Inspect a view's metadata¶
- Read descriptive fields on any
PluginViewto understand what a plugin declares without loading it.
from uxok import StalePluginError
for view in plugins:
print(view.name, view.provides, view.requires)
print(view.hooks_provided, view.events_published)
print("ready:", view.ready)
try:
print(f"uptime: {await view.uptime():.1f}s")
except StalePluginError:
print("(plugin gone)")
Warning
view.uptime() raises StalePluginError when the plugin was unregistered after
the collection was fetched. Always catch it.
Introspect capability providers¶
- Use
collection.capability.info(name)to get the full provider picture for a capability: who provides it, how many providers exist, which one is currently selected, and whether the capability was registered with a Protocol type.
from uxok.registry import CapabilityInfo
info = plugins.capability.info("storage")
if info:
print(info.selected_provider)
print([p["name"] for p in info.providers])
print(info.typed, info.protocol_name)
Discover every capability in the collection¶
- Read
collection.capabilitiesfor a sorted, deduplicated list of every capability name provided by any plugin in the collection.
Act on the plugins you discovered¶
A collection is for discovery, not invocation — PluginView exposes no way to call into or hand back a live instance. Once you have found the plugins you want, act on them through an explicit authority:
- To invoke methods on a discovered plugin, resolve it to a live instance through the
kernel.lifecyclegrant (declarerequires={"kernel.lifecycle"}), then iterate:
lifecycle = await self.get_capability("kernel.lifecycle")
for view in plugins.active.capability.provides("health"):
plugin = await lifecycle.get_plugin(view.name)
if plugin is not None:
await plugin.health_check()
For most cases, prefer resolving the capability a plugin provides
(await self.get_capability("storage")) over reaching for the instance directly.
For a complete walkthrough of the lifecycle grant, see Resolve a live plugin instance.
For basic plugin registration, see register and manage plugins. For capability concepts, see the capability system explanation.