Core Modules

Top-level modules that provide the CLI framework: entry point, dependency injection, output handling, exception hierarchy, and logging configuration.

Entry Point

The CLI entry point with centralized exception handling.

kelvin.sdk.main.main()[source]

Main entry point with centralized exception handling.

Return type:

None

CLI Group

The root Click group definition and global options.

Kelvin CLI group definition and command registration.

Separated from main.py to avoid circular imports: configuration.py needs to import kelvin_cli for shell completion generation, while main.py imports configuration.py to register the command.

kelvin.sdk.cli_group.get_resolved_json_mode()[source]

Return the resolved –json flag value.

Return type:

bool

kelvin.sdk.cli_group.get_resolved_verbose()[source]

Return the resolved –verbose flag value.

Return type:

bool

kelvin.sdk.cli_group.set_resolved_json_mode(value)[source]

Update the resolved –json flag (called by @global_options).

Return type:

None

Parameters:

value (bool)

kelvin.sdk.cli_group.set_resolved_verbose(value)[source]

Update the resolved –verbose flag (called by @global_options).

Return type:

None

Parameters:

value (bool)

Services Container

Dependency injection container with lazy service initialization. The container also exposes the Output service for controlling CLI output behavior (JSON vs interactive mode, progress indicators, user confirmations).

Dependency wiring (composition root).

This module is responsible for creating and wiring all services. It’s the single place where dependencies are assembled.

class kelvin.sdk.container.Services(*, json_mode=False, assume_yes=False, verbose=False)[source]

Bases: object

Container for all services with lazy initialization.

Services are created on first access, not at startup. This means: - Faster CLI startup - Commands that don’t need auth won’t fail if no session exists - Services that depend on other services are created in the right order

This is passed via Click context to all commands. Add new services here as your CLI grows.

Parameters:
property output: Output

Output service - always safe to access.

set_verbose(value)[source]

Set verbose flag, propagating to output if already initialized.

Return type:

None

Parameters:

value (bool)

set_json_mode(value)[source]

Set json_mode flag, propagating to output if already initialized.

Return type:

None

Parameters:

value (bool)

set_assume_yes(value)[source]

Set assume_yes flag, propagating to output if already initialized.

Return type:

None

Parameters:

value (bool)

property credential_store: CredentialStore

Credential store - manages secure token storage.

property auth: AuthService

Auth service - handles OAuth/PKCE authentication flow.

property session: SessionService

Session service - manages session state and platform metadata.

property docker: DockerService

Docker service - manages Docker operations.

property schema: SchemaService

Schema service - manages app configuration schemas.

property template: TemplateService

Template service - manages application templates.

property config_service: ConfigService

Config service - manages CLI configuration file.

property auth_commands: AuthCommands

Auth commands - orchestrates auth workflow.

property workload_commands: WorkloadCommands

Workload commands - manages workload operations.

property app_commands: AppCommands

App commands - manages app creation and operations.

Note: api_client and registry_url are NOT passed here to avoid requiring authentication for local-only operations (create, build). The upload command receives them directly from the CLI layer.

property app_image_commands: AppImageCommands

App image commands - manages local Docker image operations.

These are local-only operations that don’t require authentication.

property apps_commands: AppsCommands

Apps commands - manages platform app registry operations.

These are API-based operations that require authentication.

property secret_commands: SecretCommands

Secret commands - manages platform secret operations.

These are API-based operations that require authentication.

property mlflow_service: MLflowService

MLflow service - wraps MLflow registry operations.

This is an optional service that requires the mlflow package.

property mlflow_commands: MLflowCommands

MLflow commands - manages MLflow app creation and model import.

These are local operations that don’t require authentication, but require the mlflow package to be installed.

property api_client: Client

API client - requires valid session and credentials.

Cached after first access. Token is validated and refreshed if needed when the client is first created.

Raises

NotLoggedInError

If no active session exists.

CredentialsExpiredError

If credentials are expired and cannot be refreshed.

kelvin.sdk.container.create_services(json_mode=False, assume_yes=False, verbose=False)[source]

Create services container (lazy initialization).

Services are not created here - they’re created on first access. This makes startup fast and allows commands that don’t need certain services to run without them.

Parameters:
  • json_mode (bool) – Enable JSON output mode.

  • assume_yes (bool) – Skip confirmation prompts.

  • verbose (bool) – Enable verbose/debug output.

Return type:

Services

Returns:

Services container with lazy initialization.

class kelvin.sdk.output.Output(json_mode=False, assume_yes=False, verbose=False, _console=<factory>, _stderr_console=<factory>)[source]

Bases: object

Controls output behavior based on mode.

Parameters:
  • json_mode (bool)

  • assume_yes (bool)

  • verbose (bool)

  • _console (Console)

  • _stderr_console (Console)

json_mode

If True, suppress interactive output and format results as JSON.

assume_yes

If True, skip confirmation prompts (used with –yes flag).

verbose

If True, verbose logging is enabled.

property console: Console

Access the console for advanced formatting (tables, trees, etc.).

status(message)[source]

Print a static status message to stderr, nothing in JSON mode.

This was originally a Rich spinner (Console.status), but structlog messages and subprocess output (e.g. docker buildx) corrupted the spinner rendering. Changing to a static message for now.

Parameters:

message (str) – Status message to display.

Return type:

Iterator[None]

Example

with out.status(“Loading…”):

do_something_slow()

print(*args, **kwargs)[source]

Print to console (suppressed in JSON mode).

Use for interactive output like tables, formatted results, etc.

Return type:

None

Parameters:
print_json(data)[source]

Print JSON output to stdout.

Always prints regardless of mode. Use for command results in –json mode.

Parameters:

data (Any) – Data to serialize as JSON. Can be a dict, list, or dataclass.

Return type:

None

error(message)[source]

Print error to stderr (always visible).

Parameters:

message (str) – Error message to display.

Return type:

None

warning(message)[source]

Print warning to stderr (always visible).

Parameters:

message (str) – Warning message to display.

Return type:

None

warning_detail(message)[source]

Print indented warning detail to stderr (bold).

Parameters:

message (str) – Detail line to display below a warning.

Return type:

None

debug(message)[source]

Print debug info to stderr.

Only shown when verbose mode is enabled.

Parameters:

message (str) – Debug message to display.

Return type:

None

confirm(message, default=False)[source]

Prompt for confirmation.

Behavior: - Interactive mode: prompts user - --yes: returns True - JSON mode without --yes: returns False (no output — caller decides) - Non-interactive without --yes: returns False with stderr hint

Parameters:
  • message (str) – Confirmation prompt message.

  • default (bool) – Default value if user just presses Enter.

Return type:

bool

Returns:

True if confirmed, False otherwise.

abort_if_not_confirmed(message)[source]

Prompt for confirmation, abort if not confirmed.

Like click.confirm(…, abort=True) but JSON-aware. Raises SystemExit(0) if not confirmed.

Parameters:

message (str) – Confirmation prompt message.

Raises:

SystemExit – With code 0 if user cancels.

Return type:

None

success(message)[source]

Print success message to stderr (suppressed in JSON mode).

Parameters:

message (str) – Success message to display.

Return type:

None

prompt(message, default=None, hide_input=False)[source]

Prompt user for input.

In JSON mode, uses default or raises error if no default provided.

Parameters:
  • message (str) – Prompt message.

  • default (Optional[str]) – Default value.

  • hide_input (bool) – If True, hide input (for passwords).

Return type:

str

Returns:

User input string.

Raises:

SystemExit – If in JSON mode with no default.

Exceptions

Shared exception hierarchy for the CLI.

Shared exceptions for the CLI.

Define base exceptions here. Domain-specific exceptions go in their respective command modules (e.g., commands/workloads.py).

exception kelvin.sdk.exceptions.CLIError(message=None, exit_code=None)[source]

Bases: Exception

Base exception for all CLI errors.

Subclass this for errors that should show a friendly message and exit with a specific code.

Parameters:
  • message (str)

  • exit_code (int)

message: str = 'An error occurred'
exit_code: int = 1
exception kelvin.sdk.exceptions.ConfigurationError(message=None, exit_code=None)[source]

Bases: CLIError

Missing or invalid configuration.

Parameters:
  • message (str)

  • exit_code (int)

exit_code: int = 78
exception kelvin.sdk.exceptions.AuthenticationError(message=None, exit_code=None)[source]

Bases: CLIError

Authentication failed or credentials missing.

Parameters:
  • message (str)

  • exit_code (int)

exit_code: int = 77
exception kelvin.sdk.exceptions.NetworkError(message=None, exit_code=None)[source]

Bases: CLIError

Network/API communication error.

Parameters:
  • message (str)

  • exit_code (int)

exit_code: int = 69

Logging

Structured logging configuration using structlog and stdlib logging.

Logging configuration using structlog + stdlib logging.

This module provides structured logging that: - Uses structlog for nice API (key-value logging) - Routes through stdlib logging for library compatibility - Outputs human-readable logs in interactive mode - Outputs JSON logs when –json flag is used - Always logs to stderr (never pollutes stdout)

Usage in commands/:

import structlog

# Use __name__ to get logger under kelvin.* namespace logger = structlog.get_logger(__name__)

def my_function():

logger.info(“doing something”, workload_id=”w1”, action=”delete”)

kelvin.sdk.logging.configure_structlog()[source]

Configure structlog to route through stdlib logging.

MUST be called before any kelvin modules are imported, so that module-level structlog.get_logger() calls create lazy proxies that carry the correct processors and logger factory.

This is format-agnostic — the JSON vs console choice is made later in setup_logging() on the stdlib handler’s ProcessorFormatter.

Return type:

None

kelvin.sdk.logging.setup_logging(verbose=False, json_mode=False)[source]

Configure stdlib logging handler and format.

Log level from -v only affects kelvin.* loggers. The root logger stays at WARNING so third-party libs stay quiet.

Parameters:
  • verbose (bool) – Enable debug logging for kelvin.* loggers.

  • json_mode (bool) – If True, output logs as JSON. Otherwise human-readable.

Return type:

None