Skip to content

Package and register a plugin

Altar discovers installed implementations through Python entry points. This lets applications select an integration by name without importing its package directly.

Model plugins also carry a versioned manifest and run identity. Entry points answer which implementation is installed; the manifest answers whether its plans and stored results are compatible.

Package layout

A binding should be an independently installable distribution that depends on altar, imports only public façade modules, and exposes its implementation from its own namespace.

[project]
name = "altar-example-model"
dependencies = ["altar>=0.1,<1"]

[project.entry-points."altar.model_plugins"]
EXAMPLE = "altar_example_model:ExamplePlugin"

The altar.* names below are the canonical discovery ABI. The discovery namespace used before Altar's first release was removed rather than registered alongside it. Entry-point groups and Python imports share the Altar project name.

Entry-point groups

Group Interface Status
altar.model_plugins model bindings Stable
altar.execution_backends execution backends Stable
altar.score_stores score stores Stable
altar.detail_stores named detail-table stores Stable
altar.annotation_sources annotation sources Stable
altar.variant_gene_link_sources variant–gene link sources Stable
altar.storage object/file storage Stable
altar.job_queues job queues Provisional
altar.auth authentication providers Provisional

The registry discovers and validates all nine groups the same way. The two provisional groups have no public production adapter and no Altar component that consumes them: altar.job_queues has only the InMemoryJobQueue test double, and altar.auth has only the development-only DevAuthProvider. Their contracts (JobQueue, AuthProvider) remain importable for existing hosts, but they may change in a minor release. A provisional group becomes stable when it has a public adapter, an in-repository consumer, documentation, and conformance coverage of that adapter.

Resolve by name

Use the typed registry helper for the known interface:

from altar.models import get_model_plugin

plugin = get_model_plugin("EXAMPLE")

altar.registry.PluginRegistry is available for hosts that need generic discovery or isolated programmatic registration in tests. installed() and names() read distribution metadata without importing target modules. get(name) imports and validates only the requested target. discover() explicitly scans every candidate and returns a PluginDiscoveryReport containing validated plugins and an individual diagnostic for each broken, incompatible, or duplicate candidate.

Duplicate installed names are rejected with both owning distributions and entry-point values. A programmatic registration cannot shadow an installed or earlier programmatic plugin unless the host passes replace=True; the resulting discovery record lists the installed declarations it replaced.

Avoid import-time dependency failures

A binding must remain importable without its heavyweight runtime or provider credentials. Put TensorFlow, PyTorch, model weights, and conflicting scientific environments in a runtime image. Import optional cloud or model SDKs only when the capability is invoked.

Validate the package

Subclass the matching contract from altar.testing, test registry resolution after installing the package, and assert that a clean environment cannot import your private host application. See Validate an implementation.

Migration for downstream hosts

Downstream applications, including private host applications, must update any entry-point declarations and raw get_registry(...) calls to the matching altar.* group. Host-owned replacements must use register(name, implementation, replace=True) and should surface discover().failures in diagnostics. No fallback reads the former namespace, so deployments must update Altar and their host adapters together.

This migration changes discovery metadata only. Durable VCF fields, stored schema identifiers, and existing Public environment variables use the ALTAR_* prefix.