Public API and compatibility¶
Altar exposes a deliberately small set of façade modules for binding and backend authors. Import from these modules, not from the files that currently implement them:
from altar.models import ModelPlugin, ScoringRequest
from altar.execution import ContainerTaskSpec, ExecutionBackend
from altar.results import BigQueryDetailStore, DetailStore, ScoreStore
from altar.sources import AnnotationSource, VariantGeneLinkSource
from altar.predicates import Col, Ge, Lit
from altar.scoring import prepare_scoring_batches, run_scoring
from altar.testing import ContainerScorerContract, DetailStoreContract, ModelResultContract
from altar.variants import VariantKey, canonical_variant_id
Every supported module defines an explicit __all__; the API reference documents the symbols in those
lists, py.typed covers their inline annotations, and scripts/check_public_api.py compares their symbols
and signatures with the reviewed snapshot in altar/public-api.json. A few exported names are
provisional and are listed separately in each module's __provisional__.
Inventory and decisions¶
Before adding the façade, extension imports were spread across these implementation areas:
| Existing extension-facing area | Observed consumers | Supported import |
|---|---|---|
altar.plugins.model.* |
model bindings, score drivers, model guide | altar.models |
altar.plugins.execution.*, storage, job queue (provisional) |
backend guides and scoring examples | altar.execution |
| score-store and materialization modules | data-lake backends and examples | altar.results |
| annotation and variant-gene modules | AlphaMissense, SpliceAI, Open Targets E2G | altar.sources |
| predicate implementation | model and annotation bindings | altar.predicates |
| auth implementation (provisional) | auth-provider guide | altar.access |
| registry implementation | extension discovery guide | altar.registry |
| scoring engine | host applications and end-to-end scoring examples | altar.scoring |
| conformance implementation modules | every adjacent binding test suite | altar.testing |
| variant ingestion root | variant runtimes | altar.variants |
The façade forwards to those existing implementations. Plugin discovery uses the canonical altar.*
entry-point groups. The versioned manifest types are exported through altar.models; their
shape, compatibility checks, and registry validation are documented in the
plugin ABI guide.
Compatibility commitment¶
The names in __all__ for altar.access, altar.execution, altar.models, altar.predicates,
altar.registry, altar.results, altar.scoring, altar.sources, altar.testing, and altar.variants are
the supported API, except the names each module lists in __provisional__. Within a major release, Altar
will not remove a stable name or make a stable callable's accepted signature narrower. Additive symbols,
optional parameters with defaults, and backward-compatible typing improvements may ship in minor releases.
Behavior documented on the API reference pages is part of the same commitment.
VariantKey and canonical_variant_id() define the compatibility-controlled join-key encoding shared by
scores, details, and annotations. Source identifiers and genome-build provenance remain separate fields;
changing the canonical text encoding would require an explicit compatibility and migration decision.
Core adapters such as LocalDockerExecutionBackend and SqliteScoreStore are covered only at their Altar
façade import paths. Independently installed integrations expose their own public package namespace; for
example, ChromBPNet and AlphaGenome types are imported from altar_chrombpnet and altar_alphagenome, not
altar.models. Deep implementation-module locations remain private.
Identity package¶
VariantKey and the other identity rules are defined in altar-identity (import altar_identity), a
separate distribution in this repository that altar depends on. The façades re-export its names as the same
objects, so an isinstance check or an except clause behaves the same whichever path imported them:
| Names | Re-exported by |
|---|---|
VariantKey, VariantIdentityError, canonical_chromosome, canonical_variant_id |
altar.models, altar.sources, altar.variants |
has_verification_record, VERIFICATION_RECORD_SUFFIX |
altar.execution |
These re-exports carry the commitment above and are recorded in altar/public-api.json. Bindings import them
through a façade, not from altar_identity. altar.variants.read_variants_frame loads a variant table as a
DataFrame; altar_identity.read_variants yields VariantKey values from a container variant file.
Model runtimes import altar_identity directly, because most of them run on Python versions that cannot
install Altar core. They use the names in its __all__. read_variants, read_variant_rows, and batched
read the variant file Altar stages for a container. sha256_file, verify_file, and the verification-record
helpers check staged resources.
The package makes two promises, and CI checks both whenever it changes: it supports Python 3.9 and later, and
its wheel declares no dependencies. altar pins it with ==, so each Altar release requires exactly one
altar-identity version, and a runtime image built from the same commit runs the same identity code. Names
that no façade re-exports are not recorded in public-api.json and are covered only through that pin.
Provisional names¶
A provisional name is exported from a supported façade, and the registry discovers its entry-point group, but it is excluded from the compatibility commitment above. The definition is mechanical:
- the façade module lists the name in
__provisional__, a tuple that must be a subset of__all__; scripts/check_public_api.pyrecords the tuple underprovisionalfor that module inaltar/public-api.json, and rejects a__provisional__name missing from__all__;- the private
PROVISIONAL_PLUGIN_GROUPSconstant names the matching entry-point groups, and a test requires each group's contract type to be provisional exactly when its group is, and requires the plugin guide to label those groups as provisional.
A provisional name stays importable from the same façade path. Its symbols and signatures are still recorded in the snapshot, so every change is reviewed as an API change and recorded in the changelog. Unlike a stable name, it may be removed or narrowed in a minor release.
A contract is provisional when it lacks what Altar requires of a stable extension seam: a real public adapter,
an in-repository consumer, documentation, and a conformance test run against that adapter. Promotion removes
its names from __provisional__ and its group from PROVISIONAL_PLUGIN_GROUPS in one reviewed change, after
which the full commitment applies.
| Module | Provisional names | Entry-point group | Missing for promotion |
|---|---|---|---|
altar.execution |
JobQueue, get_job_queue_registry |
altar.job_queues |
a public adapter and an Altar consumer; only the InMemoryJobQueue test double exists |
altar.access |
every name: AuthIdentity, AuthProvider, DevAuthProvider, InvalidTokenError, get_auth_registry |
altar.auth |
a public production adapter and an Altar consumer; DevAuthProvider is development-only |
altar.testing |
AuthProviderContract, InMemoryJobQueue, JobQueueContract |
— | promotion of the contracts they exercise |
Experimental and private namespaces¶
altar.agentandaltar.apisare experimental. They may require the[agent]extra, provider credentials, and service access, and may change without the façade compatibility guarantees. They contain no knowledge-graph construction or traversal; hosts supply that context throughaltar.agent.knowledge.AgentKnowledgeProvider.- The web application under
reference/is an experimental reference host, not an importable Altar API. altar.plugins.*,altar.testing.*below the package root, and other implementation modules are private. They remain importable for internal compatibility, but third-party packages must not depend on them.- Console-oriented implementation modules below
altar.variantsare not stable Python imports. The symbols explicitly re-exported byaltar.variantsare stable.
The wheel continues to contain experimental namespaces for now. A base install never imports them from a stable façade, and the installed-wheel gate imports every supported symbol without optional provider SDKs, model frameworks, credentials, or a source checkout.
Typing scope¶
The distribution ships py.typed. Its compatibility promise applies to the façade modules above and to the
types reachable from their exported signatures. Strict mypy checks cover those modules and the adjacent
bindings. Experimental namespaces are deliberately excluded from the strict gate until they graduate into a
documented façade.