Skip to content

manager

dev_tool.config.manager

log = logging.getLogger(__name__) module-attribute

ConfigEvent

Bases: Enum

An enumeration of configuration change event types.

This enum defines the types of configuration events that can trigger callbacks.

ENV = auto() class-attribute instance-attribute

PYPROJECT = auto() class-attribute instance-attribute

ConfigManager

A singleton class for managing configuration across the application.

This class handles loading, reloading, and providing access to various configuration settings from different sources.

A constructor for the ConfigManager class.

This method initializes all configuration components and sets up file watching if a watcher is provided.

Parameters:

  • watcher (FileWatcherService | None, default: None ) –

    An optional file watcher service for monitoring config changes.

Source code in dev_tool/config/manager.py
def __init__(self, watcher: FileWatcherService | None = None) -> None:
    """
    A constructor for the ConfigManager class.

    This method initializes all configuration components and sets up
    file watching if a watcher is provided.

    :param watcher: An optional file watcher service for monitoring config changes.
    """

    if getattr(self, '_initialized', False):
        return

    self._initialized = True

    self.docker = DockerConfig()
    self.env = EnvConfig()
    self.fs = FilesystemConfig()
    self.pyproject = PyprojectConfig()

    self._listener: dict[ConfigEvent, list[Callable]] = {
        ConfigEvent.ENV: [],
        ConfigEvent.PYPROJECT: []
    }

    self._watcher = watcher
    self.reload_all()

docker = DockerConfig() instance-attribute

env = EnvConfig() instance-attribute

fs = FilesystemConfig() instance-attribute

pyproject = PyprojectConfig() instance-attribute

__new__

The method that implements the singleton pattern.

This method ensures only one instance of ConfigManager exists.

Returns:

  • Self –

    The singleton ConfigManager instance.

Source code in dev_tool/config/manager.py
def __new__(cls) -> Self:
    """
    The method that implements the singleton pattern.

    This method ensures only one instance of ConfigManager exists.

    :return: The singleton ConfigManager instance.
    """

    if cls._instance is None:
        cls._instance = super().__new__(cls)
        cls._instance._initialized = False

    assert isinstance(cls._instance, cls)
    return cls._instance

set_notification classmethod

A class method that sets the notification service for the config manager.

Parameters:

Source code in dev_tool/config/manager.py
@classmethod
def set_notification(cls, notification: NotificationProtocol) -> None:
    """
    A class method that sets the notification service for the config manager.

    :param notification: The notification service to use.
    """

    cls._notification = notification

    if cls._instance is not None:
        cls._instance.docker.set_notification(notification)
        cls._instance.docker.set_resource_path_getter(cls._instance.fs.get_resource_path)
        cls._instance.pyproject.set_notification(notification)

create_default_docker_config

A method that creates a default Docker configuration.

This method generates a complete Docker configuration using the project name and user-provided Docker configuration.

Returns:

  • dict[str, Any] –

    A complete Docker configuration dictionary.

Source code in dev_tool/config/manager.py
def create_default_docker_config(self) -> dict[str, Any]:
    """
    A method that creates a default Docker configuration.

    This method generates a complete Docker configuration using the project name
    and user-provided Docker configuration.

    :return: A complete Docker configuration dictionary.
    """

    return self.docker.create_default_docker_config(
        self.get_project_name(),
        self.get_docker_config(),
        self.get_database_port()
    )

get_app_port

A method that retrieves the host port the project's web server binds to.

In multi-project mode the port is derived from the project name so every project publishes its server on a port of its own. Otherwise it is the default.

Returns:

  • int –

    The host port for the web server.

Source code in dev_tool/config/manager.py
def get_app_port(self) -> int:
    """
    A method that retrieves the host port the project's web server binds to.

    In multi-project mode the port is derived from the project name so every
    project publishes its server on a port of its own. Otherwise it is the default.

    :return: The host port for the web server.
    """

    return self.docker.get_app_port(self.get_project_name(), multi_project=self.is_multi_project())

get_bun_config

A method that retrieves the Bun configuration.

This method gets the Bun configuration section.

Returns:

  • dict[str, Any] –

    The Bun configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_bun_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Bun configuration.

    This method gets the Bun configuration section.

    :return: The Bun configuration as a dictionary.
    """

    return self.pyproject.get_bun_config()

get_coverage_config

A method that retrieves the coverage configuration.

This method gets the coverage configuration section.

Returns:

  • dict[str, Any] –

    The coverage configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_coverage_config(self) -> dict[str, Any]:
    """
    A method that retrieves the coverage configuration.

    This method gets the coverage configuration section.

    :return: The coverage configuration as a dictionary.
    """

    return self.pyproject.get_coverage_config()

get_current_version

A method that retrieves the current version.

This method returns the current version of the application.

Returns:

  • str –

    The version string.

Source code in dev_tool/config/manager.py
def get_current_version(self) -> str:
    """
    A method that retrieves the current version.

    This method returns the current version of the application.

    :return: The version string.
    """

    return __version__

get_database_port

A method that retrieves the host port the project's database is published on.

In multi-project mode the port is derived from the project name unless the environment file names one of its own. Otherwise it is the environment file's port, or the default.

Returns:

  • int –

    The host port for the database.

Source code in dev_tool/config/manager.py
def get_database_port(self) -> int:
    """
    A method that retrieves the host port the project's database is published on.

    In multi-project mode the port is derived from the project name unless the
    environment file names one of its own. Otherwise it is the environment file's
    port, or the default.

    :return: The host port for the database.
    """

    configured = self.env.get_configured_value('DATABASE_PORT', DEVELOPMENT_ENV)

    return self.docker.get_database_port(self.get_project_name(), configured, multi_project=self.is_multi_project())

get_dev_tool_config

A method that retrieves the dev_tool configuration.

This method gets the dev_tool configuration section.

Returns:

  • dict[str, Any] –

    The dev_tool configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_dev_tool_config(self) -> dict[str, Any]:
    """
    A method that retrieves the dev_tool configuration.

    This method gets the dev_tool configuration section.

    :return: The dev_tool configuration as a dictionary.
    """

    return self.pyproject.get_dev_tool_config()

get_dev_tool_port

A method that retrieves the dev_tool port setting.

This method gets the port number configured for the dev_tool.

Returns:

  • str | None –

    The port string, or None if not configured.

Source code in dev_tool/config/manager.py
def get_dev_tool_port(self) -> str | None:
    """
    A method that retrieves the dev_tool port setting.

    This method gets the port number configured for the dev_tool.

    :return: The port string, or None if not configured.
    """

    return self.pyproject.get_dev_tool_port()

get_developer_token

A method that retrieves the developer token.

This method gets the developer token from the token file.

Returns:

  • str | None –

    The developer token string, or None if not available.

Source code in dev_tool/config/manager.py
def get_developer_token(self) -> str | None:
    """
    A method that retrieves the developer token.

    This method gets the developer token from the token file.

    :return: The developer token string, or None if not available.
    """

    return self.fs.get_developer_token(DEVELOPER_TOKEN)

get_django_config

A method that retrieves the Django configuration.

This method gets the Django configuration section.

Returns:

  • dict[str, Any] –

    The Django configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_django_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Django configuration.

    This method gets the Django configuration section.

    :return: The Django configuration as a dictionary.
    """

    return self.pyproject.get_django_config()

get_django_coverage_config

A method that retrieves the Django coverage configuration.

This method gets the Django coverage configuration section.

Returns:

  • dict[str, Any] –

    The Django coverage configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_django_coverage_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Django coverage configuration.

    This method gets the Django coverage configuration section.

    :return: The Django coverage configuration as a dictionary.
    """

    return self.pyproject.get_django_coverage_config()

get_django_unittest_config

A method that retrieves the Django unit test configuration.

This method gets the Django unit test configuration section.

Returns:

  • dict[str, Any] –

    The Django unit test configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_django_unittest_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Django unit test configuration.

    This method gets the Django unit test configuration section.

    :return: The Django unit test configuration as a dictionary.
    """

    return self.pyproject.get_django_unittest_config()

get_docker_authorization

A method that retrieves Docker authorization credentials.

This method gets the username and password for Docker from environment variables.

Returns:

  • tuple[str, str] –

    A tuple containing (username, password).

Source code in dev_tool/config/manager.py
def get_docker_authorization(self) -> tuple[str, str]:
    """
    A method that retrieves Docker authorization credentials.

    This method gets the username and password for Docker from environment variables.

    :return: A tuple containing (username, password).
    """

    return self.env.get_docker_authorization()

get_docker_config

A method that retrieves the Docker configuration.

This method gets the Docker configuration section.

Returns:

  • dict[str, Any] –

    The Docker configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_docker_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Docker configuration.

    This method gets the Docker configuration section.

    :return: The Docker configuration as a dictionary.
    """

    return self.pyproject.get_docker_config()

get_project_config

A method that retrieves a project configuration section.

This method gets a specific section from the project configuration.

Parameters:

  • key (str) –

    The section key to retrieve.

Returns:

  • dict[str, Any] –

    The configuration section as a dictionary.

Source code in dev_tool/config/manager.py
def get_project_config(self, key: str) -> dict[str, Any]:
    """
    A method that retrieves a project configuration section.

    This method gets a specific section from the project configuration.

    :param key: The section key to retrieve.
    :return: The configuration section as a dictionary.
    """

    return self.pyproject.get_project_config(key)

get_project_name

A method that retrieves the project name.

This method gets the project name from the pyproject.toml file.

Returns:

  • str –

    The project name string.

Source code in dev_tool/config/manager.py
def get_project_name(self) -> str:
    """
    A method that retrieves the project name.

    This method gets the project name from the pyproject.toml file.

    :return: The project name string.
    """

    return self.pyproject.get_project_name()

get_python_coverage_config

A method that retrieves the Python coverage configuration.

This method gets the Python coverage configuration section.

Returns:

  • dict[str, Any] –

    The Python coverage configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_python_coverage_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Python coverage configuration.

    This method gets the Python coverage configuration section.

    :return: The Python coverage configuration as a dictionary.
    """

    return self.pyproject.get_python_coverage_config()

get_python_unittest_config

A method that retrieves the Python unittest configuration.

This method gets the Python unittest configuration section.

Returns:

  • dict[str, Any] –

    The Python unittest configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_python_unittest_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Python unittest configuration.

    This method gets the Python unittest configuration section.

    :return: The Python unittest configuration as a dictionary.
    """

    return self.pyproject.get_python_unittest_config()

get_resource_path

A method that resolves a resource path.

This method delegates to the filesystem configuration to resolve paths.

Parameters:

  • path (str) –

    The relative path to the resource.

Returns:

  • Path –

    The absolute Path to the resource.

Source code in dev_tool/config/manager.py
def get_resource_path(self, path: str) -> Path:
    """
    A method that resolves a resource path.

    This method delegates to the filesystem configuration to resolve paths.

    :param path: The relative path to the resource.
    :return: The absolute Path to the resource.
    """

    return self.fs.get_resource_path(path)

get_sass_config

A method that retrieves the Sass configuration.

This method gets the Sass configuration section.

Returns:

  • dict[str, Any] –

    The Sass configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_sass_config(self) -> dict[str, Any]:
    """
    A method that retrieves the Sass configuration.

    This method gets the Sass configuration section.

    :return: The Sass configuration as a dictionary.
    """

    return self.pyproject.get_sass_config()

get_scripting_config

A method that retrieves the scripting configuration.

This method gets the scripting configuration section.

Returns:

  • dict[str, Any] –

    The scripting configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_scripting_config(self) -> dict[str, Any]:
    """
    A method that retrieves the scripting configuration.

    This method gets the scripting configuration section.

    :return: The scripting configuration as a dictionary.
    """

    return self.pyproject.get_scripting_config()

get_ssh_port

A method that retrieves the host port the project's app container exposes SSH on.

In multi-project mode the port is derived from the project name so every project publishes SSH on a port of its own. Otherwise it is the default.

Returns:

  • int –

    The host port for SSH.

Source code in dev_tool/config/manager.py
def get_ssh_port(self) -> int:
    """
    A method that retrieves the host port the project's app container exposes SSH on.

    In multi-project mode the port is derived from the project name so every
    project publishes SSH on a port of its own. Otherwise it is the default.

    :return: The host port for SSH.
    """

    return self.docker.get_ssh_port(self.get_project_name(), multi_project=self.is_multi_project())

is_multi_project

A method that checks whether this machine runs several projects at once.

Multi-project mode is a per-machine choice recorded by a marker file in the Stratus directory. With it, every project derives ports of its own and other projects' containers are left running. Without it, the defaults apply and starting one project stops the others.

Returns:

  • bool –

    True if the marker file exists.

Source code in dev_tool/config/manager.py
def is_multi_project(self) -> bool:
    """
    A method that checks whether this machine runs several projects at once.

    Multi-project mode is a per-machine choice recorded by a marker file in the
    Stratus directory. With it, every project derives ports of its own and other
    projects' containers are left running. Without it, the defaults apply and
    starting one project stops the others.

    :return: True if the marker file exists.
    """

    return MULTI_PROJECT.exists()

get_tool_config

A method that retrieves a tool configuration section.

This method gets a specific section from the tool configuration.

Parameters:

  • key (str) –

    The section key to retrieve.

Returns:

  • dict[str, Any] –

    The configuration section as a dictionary.

Source code in dev_tool/config/manager.py
def get_tool_config(self, key: str) -> dict[str, Any]:
    """
    A method that retrieves a tool configuration section.

    This method gets a specific section from the tool configuration.

    :param key: The section key to retrieve.
    :return: The configuration section as a dictionary.
    """

    return self.pyproject.get_tool_config(key)

get_unittest_config

A method that retrieves the unittest configuration.

This method gets the unittest configuration section.

Returns:

  • dict[str, Any] –

    The unittest configuration as a dictionary.

Source code in dev_tool/config/manager.py
def get_unittest_config(self) -> dict[str, Any]:
    """
    A method that retrieves the unittest configuration.

    This method gets the unittest configuration section.

    :return: The unittest configuration as a dictionary.
    """

    return self.pyproject.get_unittest_config()

get_version

A method that retrieves the current version.

Returns:

  • str –

    The version string.

Source code in dev_tool/config/manager.py
def get_version(self) -> str:
    """
    A method that retrieves the current version.

    :return: The version string.
    """

    return __version__

initialize_watcher

A method that initializes the file watcher.

This method sets up file watching for configuration files with the specified polling interval.

Parameters:

  • interval (float, default: 1.0 ) –

    The polling interval in seconds.

Source code in dev_tool/config/manager.py
def initialize_watcher(self, interval: float = 1.0) -> None:
    """
    A method that initializes the file watcher.

    This method sets up file watching for configuration files with
    the specified polling interval.

    :param interval: The polling interval in seconds.
    """

    if self._watcher is None:
        self._watcher = FileWatcherService(interval=interval)
        self._watcher.watch(DEVELOPMENT_ENV, self._on_env_changed)
        self._watcher.watch(PYPROJECT, self._on_pyproject_changed)

register_listener

A method that registers a callback for configuration change events.

Parameters:

  • event (ConfigEvent) –

    The configuration event to listen for.

  • callback (Callable) –

    The callback function to invoke when the event occurs.

Source code in dev_tool/config/manager.py
def register_listener(self, event: ConfigEvent, callback: Callable) -> None:
    """
    A method that registers a callback for configuration change events.

    :param event: The configuration event to listen for.
    :param callback: The callback function to invoke when the event occurs.
    """

    if event in self._listener:
        self._listener[event].append(callback)

reload_all

A method that reloads all configuration files.

This method refreshes both environment and pyproject configurations.

Source code in dev_tool/config/manager.py
def reload_all(self) -> None:
    """
    A method that reloads all configuration files.

    This method refreshes both environment and pyproject configurations.
    """

    self.reload_env()
    self.reload_pyproject()

    self._export_database_port()

reload_env

A method that reloads environment variables.

This method refreshes environment variables from the .env file.

Source code in dev_tool/config/manager.py
def reload_env(self) -> None:
    """
    A method that reloads environment variables.

    This method refreshes environment variables from the .env file.
    """

    self.env.reload(DEVELOPMENT_ENV)
    self._export_database_port()

reload_pyproject

A method that reloads the pyproject.toml configuration.

This method refreshes configuration from the pyproject.toml file.

Source code in dev_tool/config/manager.py
def reload_pyproject(self) -> None:
    """
    A method that reloads the pyproject.toml configuration.

    This method refreshes configuration from the pyproject.toml file.
    """

    self.pyproject.reload(PYPROJECT)

start_watching

A method that starts the file watcher.

This method begins monitoring configuration files for changes.

Source code in dev_tool/config/manager.py
def start_watching(self) -> None:
    """
    A method that starts the file watcher.

    This method begins monitoring configuration files for changes.
    """

    if self._watcher:
        self._watcher.start()
    else:
        message = 'Unable to initialize the file watcher'
        self._notify_warning(message)
        log.debug(message)

stop_watching

A method that stops the file watcher.

This method ends monitoring of configuration files.

Source code in dev_tool/config/manager.py
def stop_watching(self) -> None:
    """
    A method that stops the file watcher.

    This method ends monitoring of configuration files.
    """

    if self._watcher:
        self._watcher.stop()

unregister_listener

A method that unregisters a callback for configuration change events.

Parameters:

  • event (ConfigEvent) –

    The configuration event to stop listening for.

  • callback (Callable) –

    The callback function to remove.

Source code in dev_tool/config/manager.py
def unregister_listener(self, event: ConfigEvent, callback: Callable) -> None:
    """
    A method that unregisters a callback for configuration change events.

    :param event: The configuration event to stop listening for.
    :param callback: The callback function to remove.
    """

    if event in self._listener and callback in self._listener[event]:
        self._listener[event].remove(callback)

validate_configuration

A method that validates that required configuration files exist.

This method emits warnings for any missing configuration files.

Source code in dev_tool/config/manager.py
def validate_configuration(self) -> None:
    """
    A method that validates that required configuration files exist.

    This method emits warnings for any missing configuration files.
    """

    if not PYPROJECT.exists():
        message = f'"{PYPROJECT.name}" does not exist. Please create one for this project.'
        emit_warning(message)

        log.debug(message)

    if not DEVELOPMENT_ENV.exists():
        message = f'"{DEVELOPMENT_ENV.name}" does not exist. Please create one for this project.'
        emit_warning(message)

        log.debug(message)