Skip to content

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.py records the tuple under provisional for that module in altar/public-api.json, and rejects a __provisional__ name missing from __all__;
  • the private PROVISIONAL_PLUGIN_GROUPS constant 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.agent and altar.apis are 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 through altar.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.variants are not stable Python imports. The symbols explicitly re-exported by altar.variants are 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.