Skip to content

PackageConfigBase API

Use these APIs when your application collects package settings itself instead of sending the user through omop-config configure.

Validate a complete candidate

StackConfig.tools holds plain dictionaries because oa-configurator cannot know the schemas of packages that are discovered later at runtime. Before accepting a proposed stack, call PackageConfigBase.validate_candidate() on the package class. It applies that package's field and model validators and checks every RefTo against the same proposed stack, without loading or saving a file.

A schema problem raises PackageConfigValidationError. Use tool_name to identify the affected [tools.<name>] section and errors() to attach messages to form fields, including nested fields and model-level errors. These details deliberately omit rejected values and validator context, and the exception does not retain the original pydantic error, so displaying or logging the exception cannot echo a submitted secret. A missing or wrong-kind reference raises ConfigurationError with the package field path.

Plan a change for review

Use plan_configure() when your application needs to preview a change before the user approves it. Pass the current stack and the proposed package values; the function returns a new, fully validated StackConfig and leaves the current object unchanged, even when planning fails. Nested dictionaries can create or update entries reached through RefTo fields, which lets a UI submit one complete proposal instead of reproducing oa-configurator's schema traversal.

Planning never reads or writes the active configuration file. The returned candidate keeps loaded_path as provenance, but your application still decides whether and when to call save_stack_config(). Failures are ordinary ConfigurationError or PackageConfigValidationError exceptions: this API does not print CLI guidance or raise typer.Exit.

Bases: SecretSafeBaseModel

Typed view over a package's [tools.<tool_name>] TOML section.

Subclass this and declare typed fields for whatever this package needs. A field typed Annotated[str, RefTo(CDMDatabaseConfig)] (or RefTo(GenericDatabaseConfig)/ RefTo(ModelConfig)/RefTo(ProviderConfig)/RefTo(ConnectionConfig)) names an entry in that section. omop-config configure resolves it interactively: reuse an existing entry, or create one, recursing into any RefTo fields the target itself has (e.g. a database's own connection). :meth:~oa_configurator.Resolver.resolve_package_config validates that it resolves, raising :exc:ConfigurationError if not. There is no separate "required"/"owned" declaration. The field itself is the declaration, and two packages share an entry simply by their fields resolving to the same name.

Attributes:

Name Type Description
tool_name str

Key used in [tools.<name>]. Must be set on every subclass.

extra_logging_namespaces tuple[str, ...]

Logger namespaces of transitive dependencies to configure alongside this package. The package's own tool_name is always included; only list additional roots here, e.g. ("my_extra_package_to_log",). Missing namespaces are harmless.

configure_logging classmethod

configure_logging(
    config=None, *, verbosity: int = 0, console=None
) -> None

Configure logging for this package and its declared transitive dependencies.

get_config classmethod

get_config() -> Self

Load this package's config from the active stack config file.

get_engine classmethod

get_engine(database: str, **engine_kwargs: Any) -> Any

Create a SQLAlchemy engine for a database.

Parameters:

Name Type Description Default
database str

The database name to resolve, typically read off your own resolved config (e.g. MyPackageConfig.get_config().cdm_db).

required
**engine_kwargs Any

Forwarded to :meth:~oa_configurator.resolver.ResolvedDatabase.create_engine.

{}

resolve_fields classmethod

resolve_fields(
    config: StackConfig,
    *,
    set_dict: dict[str, Any],
    interactive: bool,
    headless: bool = False,
) -> dict[str, Any]

Resolve this package's own fields: flag (--set or the field's own auto-generated flag), then stored, then an interactive prompt (seeded with the stored value as its default when one exists), recursing into any RefTo-marked field via the generic resolver machinery in :mod:~oa_configurator.resolver.

A RefTo-marked field's set_dict value may also be a nested dict instead of a plain string, built from repeated --set field.subfield=value CLI flags. Using a nested dict creates the target entry from those flags in the same call, instead of requiring it to already exist.

Parameters:

Name Type Description Default
config StackConfig

The current StackConfig, used to read any already-stored extras.

required
set_dict dict[str, Any]

Flag values, keyed by field name. Checked first. A value is either the field's plain string value, or (for a RefTo field only) a nested dict of the target's own field values.

required
interactive bool

Whether to prompt for fields not covered by set_dict or stored config, and whether an already-stored value is offered as a re-promptable default rather than reused silently. Non-interactively, fields covered by neither are simply omitted (they fall back to the field's own pydantic default when the config class is loaded).

required
headless bool

Raise library exceptions without printing CLI-oriented errors. Intended for :func:plan_configure; ignored by interactive paths.

False

Returns:

Type Description
dict[str, Any]

Resolved extra field values, keyed by field name.

Raises:

Type Description
ConfigurationError

If headless non-interactive resolution fails.

Exit

If CLI-oriented non-interactive resolution fails.

run_configure classmethod

run_configure(
    set_dict: dict[str, Any], *, interactive: bool
) -> None

Run the configure flow for this package: resolve every one of its own fields (see :meth:resolve_fields) and save to the active stack config file.

to_extra_dict

to_extra_dict() -> dict[str, Any]

Serialize back to the dict stored under [tools.<tool_name>].

validate_candidate classmethod

validate_candidate(config: StackConfig) -> Self

Validate this package's section and references in config.

This is the package-aware apply boundary for the otherwise untyped StackConfig.tools mapping. Field and model-validator failures raise :class:PackageConfigValidationError; reference failures raise :class:ConfigurationError. Neither path performs file I/O.

Bases: _SanitizedValidationErrorMixin, ConfigurationError

A package section failed its concrete pydantic schema.

:meth:errors exposes sanitized pydantic details so field locations, including the empty location used by model-level validators, are preserved without retaining rejected input or validator context.

Errors from the stack file itself

StackConfigValidationError is the whole-file sibling of the above, raised by load_stack_config_from_path() when a file parses as TOML but does not validate as a StackConfig. It sanitizes identically by providing field paths and reasons, never the rejected value, because a stack file holds every password and API key in the deployment.

Bases: _SanitizedValidationErrorMixin, ConfigurationError

The config file parsed as TOML but failed :class:StackConfig validation.

Sibling of :class:PackageConfigValidationError, sharing its sanitising: a stack config holds every connection password and API key in the deployment, so this is the error most likely to be pasted into an issue or a CI log. The message names the file and the offending field paths and nothing else.

Attributes:

Name Type Description
path Path

The file that failed to validate.

Return a complete validated package candidate without file I/O.

The input stack is deep-copied before field resolution, including nested RefTo creation or updates. The returned stack contains pydantic- normalized package values and preserves the input's loaded_path as provenance. The caller's stack remains unchanged on success and failure.