Configuration

Configuration centers around the ixmp4.conf.settings.Settings class. When instantiated, this class will read environment variables and .env files to populate the object. Any value can be overridden by passing the appropriate constructor argument:

from ixmp4.conf.settings import Settings
from ixmp4 import Platform

settings = Settings(manager_url="https://dev.manager.ece.iiasa.ac.at")

# use custom manager url for a single platform
mp = Platform("dev-public", settings=settings)

Two nested settings classes ixmp4.conf.settings.ClientSettings and ixmp4.conf.settings.ServerSettings are used to configure the ixmp4.transport.HttpxTransport and ixmp4.server.Ixmp4Server classes respectively,

For the convenience, a local .env file can be used to configure the settings object:

IXMP4_MODE=development
IXMP4_STORAGE_DIRECTORY=~/.local/share/ixmp4/
IXMP4_MANAGER_URL=https://api.manager.ece.iiasa.ac.at/v1/
IXMP4_CHECK_ALEMBIC_VERSION=true

# Server Settings
IXMP4_SERVER__MANAGER_URL=https://api.manager.ece.iiasa.ac.at/v1/
IXMP4_SERVER__TOML_PLATFORMS=/custom/path/to/platforms.toml
IXMP4_SERVER__SECRET_HS256=None
IXMP4_SERVER__MAX_PAGE_SIZE=10000
IXMP4_SERVER__DEFAULT_PAGE_SIZE=5000
IXMP4_SERVER__LOG_EXCEPTIONS=always

# Client Settings
IXMP4_CLIENT__DEFAULT_UPLOAD_CHUNK_SIZE=10000
IXMP4_CLIENT__CONCURRENCY=2
IXMP4_CLIENT__RETRIES=3
IXMP4_CLIENT__TIMEOUT=30
IXMP4_CLIENT__SECRET_HS256=None

Settings

class ixmp4.conf.settings.ClientSettings(_case_sensitive: bool | None = None, _nested_model_default_partial_update: bool | None = None, _env_prefix: str | None = None, _env_prefix_target: EnvPrefixTarget | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_ignore_empty: bool | None = None, _env_nested_delimiter: str | None = None, _env_nested_max_split: int | None = None, _env_parse_none_str: str | None = None, _env_parse_enums: bool | None = None, _cli_prog_name: str | None = None, _cli_parse_args: bool | list[str] | tuple[str, ...] | None = None, _cli_settings_source: CliSettingsSource[Any] | None = None, _cli_parse_none_str: str | None = None, _cli_hide_none_type: bool | None = None, _cli_avoid_json: bool | None = None, _cli_enforce_required: bool | None = None, _cli_use_class_docs_for_groups: bool | None = None, _cli_exit_on_error: bool | None = None, _cli_prefix: str | None = None, _cli_flag_prefix_char: str | None = None, _cli_implicit_flags: bool | Literal['dual', 'toggle'] | None = None, _cli_ignore_unknown_args: bool | None = None, _cli_kebab_case: bool | Literal['all', 'no_enums'] | None = None, _cli_shortcuts: Mapping[str, str | list[str]] | None = None, _secrets_dir: PathType | None = None, _build_sources: tuple[tuple[PydanticBaseSettingsSource, ...], dict[str, Any]] | None = None, *, default_upload_chunk_size: int = 10000, concurrency: Annotated[int, Le(le=4)] = 2, retries: int = 3, timeout: int = 30, secret_hs256: SecretStr | None = None)

Bases: BaseSettings

Client-side runtime settings.

default_upload_chunk_size

Number of records uploaded per client chunk (currently unused). Environment variable: IXMP4_CLIENT__DEFAULT_UPLOAD_CHUNK_SIZE.

Type:

int

concurrency

Maximum number of concurrent client workers. Environment variable: IXMP4_CLIENT__CONCURRENCY.

Type:

int

retries

Number of retry attempts for retryable client requests. Environment variable: IXMP4_CLIENT__RETRIES.

Type:

int

timeout

Request timeout in seconds for client-side HTTP operations. Environment variable: IXMP4_CLIENT__TIMEOUT.

Type:

int

secret_hs256

Shared secret used for self-signed client authentication. Environment variable: IXMP4_CLIENT__SECRET_HS256.

Type:

int

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ixmp4.conf.settings.ServerSettings(_case_sensitive: bool | None = None, _nested_model_default_partial_update: bool | None = None, _env_prefix: str | None = None, _env_prefix_target: EnvPrefixTarget | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_ignore_empty: bool | None = None, _env_nested_delimiter: str | None = None, _env_nested_max_split: int | None = None, _env_parse_none_str: str | None = None, _env_parse_enums: bool | None = None, _cli_prog_name: str | None = None, _cli_parse_args: bool | list[str] | tuple[str, ...] | None = None, _cli_settings_source: CliSettingsSource[Any] | None = None, _cli_parse_none_str: str | None = None, _cli_hide_none_type: bool | None = None, _cli_avoid_json: bool | None = None, _cli_enforce_required: bool | None = None, _cli_use_class_docs_for_groups: bool | None = None, _cli_exit_on_error: bool | None = None, _cli_prefix: str | None = None, _cli_flag_prefix_char: str | None = None, _cli_implicit_flags: bool | Literal['dual', 'toggle'] | None = None, _cli_ignore_unknown_args: bool | None = None, _cli_kebab_case: bool | Literal['all', 'no_enums'] | None = None, _cli_shortcuts: Mapping[str, str | list[str]] | None = None, _secrets_dir: PathType | None = None, _build_sources: tuple[tuple[PydanticBaseSettingsSource, ...], dict[str, Any]] | None = None, *, manager_url: HttpUrl | None = None, toml_platforms: Path | None = None, secret_hs256: SecretStr | None = None, max_page_size: int = 10000, default_page_size: int = 5000, log_exceptions: Literal['never', 'always', 'debug'] = 'always')

Bases: BaseSettings

Server-side runtime settings.

manager_url

Manager service base URL used by the server for outbound calls. Environment variable: IXMP4_SERVER__MANAGER_URL.

Type:

HttpUrl | None

toml_platforms

Path to the TOML file that stores configured platforms. Environment variable: IXMP4_SERVER__TOML_PLATFORMS.

Type:

Path | None

secret_hs256

Shared secret used for self-signed server authentication. Environment variable: IXMP4_SERVER__SECRET_HS256.

Type:

SecretStr | None

max_page_size

Hard upper bound for paginated API responses. Environment variable: IXMP4_SERVER__MAX_PAGE_SIZE.

Type:

int

default_page_size

Default number of items returned by paginated responses. Environment variable: IXMP4_SERVER__DEFAULT_PAGE_SIZE.

Type:

int

log_exceptions

Whether to write exception tracebacks to the server log. Environment variable: IXMP4_SERVER__LOG_EXCEPTIONS.

Type:

Literal[“never”, “always”, “debug”]

setup() ServerSettings

Validate server paging configuration after model initialization.

get_self_signed_auth(secret_hs256: SecretStr) SelfSignedAuth

Build a self-signed authentication strategy for server requests.

get_manager_client(manager_url: HttpUrl, secret_hs256: SecretStr) ManagerClient

Create a manager API client using server self-signed authentication.

get_toml_platforms() TomlPlatforms | None

Load server platform configuration from TOML when available.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ixmp4.conf.settings.Settings(_case_sensitive: bool | None = None, _nested_model_default_partial_update: bool | None = None, _env_prefix: str | None = None, _env_prefix_target: EnvPrefixTarget | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_ignore_empty: bool | None = None, _env_nested_delimiter: str | None = None, _env_nested_max_split: int | None = None, _env_parse_none_str: str | None = None, _env_parse_enums: bool | None = None, _cli_prog_name: str | None = None, _cli_parse_args: bool | list[str] | tuple[str, ...] | None = None, _cli_settings_source: CliSettingsSource[Any] | None = None, _cli_parse_none_str: str | None = None, _cli_hide_none_type: bool | None = None, _cli_avoid_json: bool | None = None, _cli_enforce_required: bool | None = None, _cli_use_class_docs_for_groups: bool | None = None, _cli_exit_on_error: bool | None = None, _cli_prefix: str | None = None, _cli_flag_prefix_char: str | None = None, _cli_implicit_flags: bool | Literal['dual', 'toggle'] | None = None, _cli_ignore_unknown_args: bool | None = None, _cli_kebab_case: bool | Literal['all', 'no_enums'] | None = None, _cli_shortcuts: Mapping[str, str | list[str]] | None = None, _secrets_dir: PathType | None = None, _build_sources: tuple[tuple[PydanticBaseSettingsSource, ...], dict[str, Any]] | None = None, *, mode: ~typing.Literal['production', 'development', 'debug'] = 'production', storage_directory: ~pathlib.Path = PosixPath('~/.local/share/ixmp4'), manager_url: ~pydantic.networks.HttpUrl = HttpUrl('https://api.manager.ece.iiasa.ac.at/v1'), check_alembic_version: bool = True, server: ~ixmp4.conf.settings.ServerSettings = <factory>, client: ~ixmp4.conf.settings.ClientSettings = <factory>, **values: ~typing.Any)

Bases: BaseSettings

Top-level ixmp4 application settings.

All settings use the IXMP4_ prefix. Nested settings use __ as a delimiter, for example IXMP4_SERVER__DEFAULT_PAGE_SIZE.

mode

Environment variable: IXMP4_MODE.

Type:

Runtime mode used to select logging configuration.

storage_directory

files. Environment variable: IXMP4_STORAGE_DIRECTORY.

Type:

Base directory for local ixmp4 state and generated

manager_url

Environment variable: IXMP4_MANAGER_URL.

Type:

Default manager service base URL used by the client.

check_alembic_version

version before using the database. Environment variable: IXMP4_CHECK_ALEMBIC_VERSION.

Type:

Whether to verify the local Alembic migration

server

Environment variables: IXMP4_SERVER__*.

Type:

Nested server configuration namespace.

client

Environment variables: IXMP4_CLIENT__*.

Type:

Nested client configuration namespace.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': 'utf-8', 'env_ignore_empty': False, 'env_nested_delimiter': '__', 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'ixmp4_', 'env_prefix_target': 'variable', 'extra': 'allow', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

setup() Settings

Finalize settings by creating paths, logging, and default platform file.

is_in_interactive_mode() bool

Return True when running in a REPL or IPython-like session.

get_credentials_path() Path

Return the path of the local credentials TOML file.

get_credentials() Credentials

Ensure and return the credentials store wrapper for local credentials.

get_toml_platforms_path() Path

Return the path of the local platform configuration TOML file.

get_toml_platforms() TomlPlatforms

Ensure and return the local TOML-backed platform registry.

setup_directories() None

Create storage, database, and log directories if they do not exist.

classmethod validate_storage_dir(v: Path) Path

Normalize storage path by expanding user home and relative paths.

load_logging_config(config: str) Any

Load a JSON logging configuration by name from conf/logging.

configure_logging(config: str) None

Configure process logging and set concrete log file destinations.

get_database_dir() Path

Returns the path to the local sqlite database directory.

get_database_path(name: str) Path

Returns a Path object for a given sqlite database name. Does not check whether or not the file actually exists.

get_client_auth(credentials: CredentialsDict | None) ManagerAuth | SelfSignedAuth | None

Select the client authentication strategy from settings and credentials.

get_self_signed_auth(secret_hs256: SecretStr) SelfSignedAuth

Create a self-signed authentication object for API communication.

get_manager_auth(manager_url: HttpUrl, credentials: CredentialsDict) ManagerAuth | None

Create manager authentication from username/password credentials.

get_manager_client(credentials: str = 'default') ManagerClient

Build a manager client using a named local credential entry.

get_manager_platforms(credentials: str = 'default') ManagerPlatforms

Return a manager-backed platform registry for a credential profile.

Platforms

ixmp4.conf.platforms.resolve_dsn_env_tokens(dsn: str) str

Replace {env:VAR_NAME} placeholders with environment variable values.

class ixmp4.conf.platforms.PlatformConnectionInfo(*args, **kwargs)

Bases: Protocol

Structural interface for platform connection metadata.

id

Manager platform identifier, if known.

Type:

int | None

name

Human-readable platform name used as the local key.

Type:

str

slug

Stable platform slug used for lookups.

Type:

str

access_group

Manager access group identifier, if known.

Type:

int | None

management_group

Manager management group identifier, if known.

Type:

int | None

accessibility

Platform visibility setting.

Type:

str

dsn

Database connection string for the platform.

Type:

str

url

Optional server URL associated with the platform.

Type:

str

class ixmp4.conf.platforms.PlatformConnections

Bases: ABC

Abstract interface for listing and retrieving platform connections.

abstractmethod list_platforms() Sequence[PlatformConnectionInfo]

Return all available platform connection definitions.

abstractmethod get_platform(name: str) PlatformConnectionInfo

Return a single platform connection definition by name.

class ixmp4.conf.platforms.TomlPlatform(*, id: int | None = None, name: str, slug: str, access_group: int | None = None, management_group: int | None = None, accessibility: str = 'PUBLIC', dsn: str, url: str | None = None)

Bases: BaseModel

Pydantic model for a platform entry stored in TOML configuration.

model_config = {'from_attributes': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ixmp4.conf.platforms.TomlPlatforms(toml_file: Path)

Bases: PlatformConnections

Platform connection registry backed by a local TOML file.

load() None

Load platform definitions from disk into memory.

dump() None

Write the in-memory platform definitions back to disk.

list_platforms() list[TomlPlatform]

Return all configured platforms from the TOML registry.

get_platform(name: str) TomlPlatform

Return one configured platform by name.

Parameters:

name (str) – Platform slug to search for.

Raises:

PlatformNotFound – If the platform with name does not exist.

add_platform(name: str, dsn: str) None

Add a new platform entry and persist the updated registry.

Parameters:
  • name (str) – Slug for the platform to add.

  • dsn (str) – Platform dsn connection string or http url.

Raises:

PlatformNotUnique – If the platform with name already exists.

remove_platform(name: str) None

Remove a platform entry and persist the updated registry.

Parameters:

name (str) – Slug for the platform to delete.

Raises:

PlatformNotFound – If the platform with name does not exist.

class ixmp4.conf.platforms.ManagerPlatforms(manager_client: ManagerClient)

Bases: PlatformConnections

Platform connection registry backed by the manager service API.

list_platforms() list[Ixmp4Instance]

Return all platforms visible from the manager service.

get_platform(name: str) Ixmp4Instance

Return one platform from the manager service registry by slug.

Parameters:

name (str) – Platform slug to search for.

Raises:

PlatformNotFound – If the platform with name does not exist.

Credentials

class ixmp4.conf.credentials.CredentialsDict

Bases: TypedDict

Stored credential fields for a single named service entry.

class ixmp4.conf.credentials.Credentials(toml_file: Path)

Bases: object

Credential store backed by a local TOML file.

credentials
Type:

Mapping of named entries to username/password pairs.

load() None

Load credentials from disk into memory.

dump() None

Write the in-memory credentials back to disk.

get(key: str) CredentialsDict | None

Return stored credentials for a named entry, if present.

set(key: str, username: str, password: str) None

Store credentials for a named entry and persist the change.

clear(key: str) None

Remove stored credentials for a named entry if it exists.