Source code for eclypse.io.context

"""Import/export context objects used by ECLYPSE IO codecs."""

from __future__ import annotations

from dataclasses import (
    dataclass,
    field,
)
from typing import (
    TYPE_CHECKING,
    Any,
)

from eclypse.graph.assets.defaults import (
    get_default_edge_assets,
    get_default_node_assets,
    get_default_path_aggregators,
)

if TYPE_CHECKING:
    from collections.abc import Callable

    from eclypse.graph.assets import Asset
    from eclypse.remote.service import Service
    from eclypse.utils.types import (
        InitPolicy,
        UpdatePolicies,
    )


[docs] @dataclass(slots=True) class IOContext: """Common customisation context for AssetGraph import and export. The context contains only options that map to the common :class:`~eclypse.graph.asset_graph.AssetGraph` construction and population behaviour. Args: node_assets (dict[str, Asset] | None): Node asset schema used when an import format does not carry asset definitions. edge_assets (dict[str, Asset] | None): Edge asset schema used when an import format does not carry asset definitions. update_policies (UpdatePolicies): Graph update policies attached on import. seed (int | None): Seed forwarded to imported graphs. """ node_assets: dict[str, Asset] | None = None edge_assets: dict[str, Asset] | None = None update_policies: UpdatePolicies = None seed: int | None = None
[docs] @dataclass(slots=True) class InfrastructureContext(IOContext): """Customisation context for infrastructure import and export. Args: strict (bool): Whether imported nodes and edges should be validated strictly. Defaults to ``False``, matching :class:`~eclypse.graph.infrastructure.Infrastructure`. include_default_assets (bool): Whether the imported infrastructure should include default assets when the format does not carry asset definitions. Defaults to ``False``, matching :class:`~eclypse.graph.infrastructure.Infrastructure`. resource_init (InitPolicy): Resource initialisation policy used when a format does not carry one. Defaults to ``"min"``, matching :class:`~eclypse.graph.infrastructure.Infrastructure`. path_assets_aggregators (dict[str, Callable[[list[Any]], Any]] | None): Named path aggregators used to reconstruct infrastructure path-resource aggregation. Defaults to ECLYPSE path aggregators only when ``include_default_assets`` is ``True``. """ strict: bool = False include_default_assets: bool = False resource_init: InitPolicy = "min" path_assets_aggregators: dict[str, Callable[[list[Any]], Any]] | None = None def __post_init__(self): """Fill default assets and path aggregators when requested.""" if not self.include_default_assets: return if self.node_assets is None: self.node_assets = get_default_node_assets() if self.edge_assets is None: self.edge_assets = get_default_edge_assets() if self.path_assets_aggregators is None: self.path_assets_aggregators = get_default_path_aggregators()
[docs] def get_aggregator(self, name: str) -> Callable[[list[Any]], Any]: """Return a registered path aggregator. Args: name (str): The aggregator name. Returns: Callable[[list[Any]], Any]: The registered aggregator. Raises: ValueError: If no aggregator is registered with the given name. """ if self.path_assets_aggregators is None: raise ValueError(f"Unknown path aggregator: {name}") try: return self.path_assets_aggregators[name] except KeyError as exc: raise ValueError(f"Unknown path aggregator: {name}") from exc
[docs] @dataclass(slots=True) class ApplicationContext(IOContext): """Customisation context for application import and export. Args: strict (bool): Whether imported nodes and edges should be validated strictly. Defaults to ``True``, matching :class:`~eclypse.graph.application.Application` through :class:`~eclypse.graph.asset_graph.AssetGraph`. include_default_assets (bool): Whether the imported application should include default assets when the format does not carry asset definitions. Defaults to ``False``, matching :class:`~eclypse.graph.application.Application`. requirement_init (InitPolicy): Requirement initialisation policy used when a format does not carry one. Defaults to ``"min"``, matching :class:`~eclypse.graph.application.Application`. services (dict[str, type[Service]]): Service classes used when an application importer needs to instantiate service implementations. """ strict: bool = True include_default_assets: bool = False requirement_init: InitPolicy = "min" services: dict[str, type[Service]] = field(default_factory=dict) def __post_init__(self): """Fill default assets when requested.""" if not self.include_default_assets: return if self.node_assets is None: self.node_assets = get_default_node_assets() if self.edge_assets is None: self.edge_assets = get_default_edge_assets()
[docs] def get_service(self, name: str) -> type[Service]: """Return a registered service class. Args: name (str): The service registry name. Returns: type[Service]: The registered service class. Raises: ValueError: If no service is registered with the given name. """ try: return self.services[name] except KeyError as exc: raise ValueError(f"Unknown service implementation: {name}") from exc
[docs] @dataclass(slots=True) class DockerComposeContext(ApplicationContext): """Customisation context for Docker Compose application import and export. Args: require_services (bool): Whether imported Docker Compose data must contain the required top-level ``services`` mapping. Defaults to ``True``. require_service_image_or_build (bool): Whether every service must define either ``image`` or ``build``. Defaults to ``True``. allow_image_fallback_to_node (bool): Whether exports may use the ECLYPSE node id as Docker image when neither ``image`` nor ``container_image`` nor ``build`` is present. Defaults to ``False``. """ require_services: bool = True require_service_image_or_build: bool = True allow_image_fallback_to_node: bool = False
[docs] @dataclass(slots=True) class TOSCAApplicationContext(ApplicationContext): """Customisation context for TOSCA application import and export. Args: require_definitions_version (bool): Whether imported TOSCA data must contain the required ``tosca_definitions_version`` field. Defaults to ``True``. require_node_template_types (bool): Whether every imported node template must contain the required ``type`` field. Defaults to ``True``. """ require_definitions_version: bool = True require_node_template_types: bool = True
[docs] @dataclass(slots=True) class TOSCAInfrastructureContext(InfrastructureContext): """Customisation context for TOSCA infrastructure import and export. Args: require_definitions_version (bool): Whether imported TOSCA data must contain the required ``tosca_definitions_version`` field. Defaults to ``True``. require_node_template_types (bool): Whether every imported node template must contain the required ``type`` field. Defaults to ``True``. """ require_definitions_version: bool = True require_node_template_types: bool = True