Skip to content

climate_ref.cli #

Entrypoint for the CLI

CLIContext #

Context object that can be passed to commands.

The database is created lazily on first access to avoid running migrations and creating backups for commands that don't need the database.

Source code in packages/climate-ref/src/climate_ref/cli/__init__.py
@define
class CLIContext:
    """
    Context object that can be passed to commands.

    The database is created lazily on first access to avoid running
    migrations and creating backups for commands that don't need the database.
    """

    config: Config
    console: Console
    skip_backup: bool = False
    _database: Database | None = field(default=None, alias="_database")
    _database_unmigrated: Database | None = field(default=None, alias="_database_unmigrated")

    @property
    def database(self) -> Database:
        """
        Get the database instance, creating it lazily if needed.

        The database is created on first access, which triggers migrations.
        Backup creation is skipped for read-only commands to reduce overhead.
        """
        if self._database is None:
            self._database = Database.from_config(self.config, skip_backup=self.skip_backup)
        return self._database

    @property
    def database_unmigrated(self) -> Database:
        """
        Get a database instance without running migrations.

        Used by ``db`` subcommands that inspect or manage migration state directly.
        """
        if self._database_unmigrated is None:
            self._database_unmigrated = Database.from_config(self.config, run_migrations=False)
        return self._database_unmigrated

    def close(self) -> None:
        """Close the database connection if it was opened."""
        if self._database is not None:
            self._database.close()
        if self._database_unmigrated is not None:
            self._database_unmigrated.close()

database property #

Get the database instance, creating it lazily if needed.

The database is created on first access, which triggers migrations. Backup creation is skipped for read-only commands to reduce overhead.

database_unmigrated property #

Get a database instance without running migrations.

Used by db subcommands that inspect or manage migration state directly.

close() #

Close the database connection if it was opened.

Source code in packages/climate-ref/src/climate_ref/cli/__init__.py
def close(self) -> None:
    """Close the database connection if it was opened."""
    if self._database is not None:
        self._database.close()
    if self._database_unmigrated is not None:
        self._database_unmigrated.close()

LogLevel #

Bases: str, Enum

Log levels for the CLI

Source code in packages/climate-ref/src/climate_ref/cli/__init__.py
class LogLevel(str, Enum):
    """
    Log levels for the CLI
    """

    Error = "ERROR"
    Warning = "WARNING"
    Debug = "DEBUG"
    Info = "INFO"

build_app() #

Build the CLI app

This registers all the commands and subcommands of the CLI app. Some commands may not be available if certain dependencies are not installed, for example the Celery CLI is only available if the climate-ref-celery package is installed.

Returns:

Type Description
Typer

The CLI app

Source code in packages/climate-ref/src/climate_ref/cli/__init__.py
def build_app() -> typer.Typer:
    """
    Build the CLI app

    This registers all the commands and subcommands of the CLI app.
    Some commands may not be available if certain dependencies are not installed,
    for example the Celery CLI is only available if the `climate-ref-celery` package is installed.

    Returns
    -------
    :
        The CLI app
    """
    # Import here to avoid circular imports since submodules import read_only from this module
    from climate_ref.cli import (
        config,
        datasets,
        db,
        executions,
        providers,
        solve,
        test_cases,
    )

    app = typer.Typer(name="ref", no_args_is_help=True)

    app.command(name="solve")(solve.solve)
    app.add_typer(config.app, name="config")
    app.add_typer(datasets.app, name="datasets")
    app.add_typer(db.app, name="db")
    app.add_typer(executions.app, name="executions")
    app.add_typer(providers.app, name="providers")
    app.add_typer(test_cases.app, name="test-cases")

    try:
        celery_app = importlib.import_module("climate_ref_celery.cli").app

        app.add_typer(celery_app, name="celery")
    except ImportError:
        logger.debug("Celery CLI not available")

    return app

main(ctx, configuration_directory=None, verbose=False, quiet=False, log_level=LogLevel.Info, version=None) #

A CLI for the Assessment Fast Track Rapid Evaluation Framework

This CLI provides a number of commands for managing and executing diagnostics.

Source code in packages/climate-ref/src/climate_ref/cli/__init__.py
@app.callback()
def main(  # noqa: PLR0913
    ctx: typer.Context,
    configuration_directory: Annotated[
        Path | None,
        typer.Option(help="Configuration directory"),
    ] = None,
    verbose: Annotated[
        bool,
        typer.Option("--verbose", "-v", help="Set the log level to DEBUG"),
    ] = False,
    quiet: Annotated[
        bool,
        typer.Option("--quiet", "-q", help="Set the log level to WARNING"),
    ] = False,
    log_level: Annotated[
        LogLevel,
        typer.Option(case_sensitive=False, help="Set the level of logging information to display"),
    ] = LogLevel.Info,
    version: Annotated[
        bool | None,
        typer.Option(
            "--version", callback=_version_callback, is_eager=True, help="Print the version and exit"
        ),
    ] = None,
) -> None:
    """
    A CLI for the Assessment Fast Track Rapid Evaluation Framework

    This CLI provides a number of commands for managing and executing diagnostics.
    """  # noqa: D401
    if quiet:
        log_level = LogLevel.Warning
    if verbose:
        log_level = LogLevel.Debug

    logger.remove()

    config = _load_config(configuration_directory)
    config.log_level = log_level.value

    log_format = config.log_format
    initialise_logging(level=config.log_level, format=log_format, log_directory=config.paths.log)

    logger.debug(f"Configuration loaded from: {config._config_file!s}")

    # Create context with lazy database initialization
    # The database is only created when first accessed
    # Skip backup for read-only commands to reduce overhead
    skip_backup = _is_read_only_command()
    cli_context = CLIContext(config=config, console=_create_console(), skip_backup=skip_backup)
    ctx.obj = cli_context

    # Register cleanup to close database connection when CLI exits
    ctx.call_on_close(cli_context.close)

sub-packages#

Sub-package Description
_git_utils Git utilities for CLI commands.
_utils
config View and update the REF configuration
datasets View and ingest input datasets
db Database management commands
executions View execution groups and their results
providers Manage the REF providers.
solve
test_cases Test data management commands for diagnostic development.