import json from os import getenv from typing import Any def _build_mlflow_tracking_url() -> str: """ Compose a single tracking URI for ``SientiaMLflowRepository`` from host and port env vars. If ``MLFLOW_HOST`` already contains a port in the authority (e.g. ``http://tracker:80``), it is returned unchanged so operators can override port logic explicitly. Return: str: Full tracking URL (scheme + host [+ port]). """ mlflow_host = getenv('MLFLOW_HOST', 'http://localhost').rstrip('/') mlflow_port = getenv('MLFLOW_PORT', '5080') # Host already includes an explicit port (e.g. http://tracker:80) host_after_scheme = mlflow_host.split('://', 1)[-1] if ':' in host_after_scheme: return mlflow_host return f'{mlflow_host}:{mlflow_port}' def build_mlflow_config() -> dict[str, Any]: """ Read MLflow tracking and registry credentials from the environment. Used by ``Activities`` when constructing ``SientiaMLflowRepository``. The ``url`` value is the same string workers and notebooks should use for ``MLFLOW_TRACKING_URI``-style clients. Environment Variables: MLFLOW_HOST: Host with scheme; port optional if MLFLOW_PORT is set (default: http://localhost) MLFLOW_PORT: Appended when host has no explicit port (default: 5080) MLFLOW_USERNAME: Basic-auth or service user (default: aignosi) MLFLOW_PASSWORD: Password or token (default: aignosi) Return: dict[str, Any]: ``url``, ``username``, ``password``. """ return { 'url': _build_mlflow_tracking_url(), 'username': getenv('MLFLOW_USERNAME', 'aignosi'), 'password': getenv('MLFLOW_PASSWORD', 'aignosi'), } def build_plugin_store_config() -> dict[str, Any]: """ Collect settings for ``PluginStore`` (Git-backed catalog + runtime install via pip). Mirrors the model-manager service: the worker passes these kwargs into ``PluginStore`` after ``install_runtime`` resolves wheels from the configured PyPI index. Missing optional env vars become ``None`` so the store can run without auth in local dev. Environment Variables: STORE_BASE_URL: Git HTTP(S) server (e.g. Gitea) base URL (default: http://localhost:3000) STORE_OWNER: Namespace or org owning the store repo (default: sientia) STORE_REPO: Repository name (default: model-library-store) STORE_BRANCH: Checkout branch; unset lets the client use default STORE_USERNAME / STORE_PASSWORD: HTTP basic credentials for Git fetch STORE_CACHE_TTL_SECONDS: Optional integer seconds for metadata cache TTL PYPI_SERVER: Index URL for ``pip install`` during runtime install (default: http://localhost:5000) PYPI_USERNAME / PYPI_PASSWORD: Optional index authentication Return: dict[str, Any]: Keys aligned with ``PluginStore`` constructor parameter names. """ cache_ttl_seconds = getenv('STORE_CACHE_TTL_SECONDS') return { 'base_url': getenv('STORE_BASE_URL', 'http://localhost:3000'), 'owner': getenv('STORE_OWNER', 'sientia'), 'repo': getenv('STORE_REPO', 'model-library-store'), 'username': getenv('STORE_USERNAME'), 'password': getenv('STORE_PASSWORD'), 'branch': getenv('STORE_BRANCH'), 'cache_ttl_seconds': int(cache_ttl_seconds) if cache_ttl_seconds else None, 'pypi_index_url': getenv('PYPI_SERVER', 'http://localhost:5000'), 'pypi_username': getenv('PYPI_USERNAME'), 'pypi_password': getenv('PYPI_PASSWORD'), } def build_opc_config() -> dict[str, Any]: """ Build OPC server configuration from environment variables. This function constructs an OPC server configuration dictionary from environment variables. It supports both single server and multi-server configurations with flexible parameter handling. Environment Variables: OPC_CONFIG: JSON string containing multiple OPC server configurations OPC_ID: OPC server ID (fallback, default: 1) OPC_URL: Single OPC server URL (fallback, default: opc.tcp://localhost:4840) OPC_SERVER_URI: Single OPC server URI (fallback, default: opc.tcp://localhost:4840) OPC_CERT_PATH: Client certificate path (fallback, default: None) OPC_PRIVATE_KEY_PATH: Client private key path (fallback, default: None) OPC_SERVER_CERT_PATH: Server certificate path (fallback, default: None) OPC_RECONNECTION_INTERVAL: Reconnection interval in seconds (fallback, default: 120) Returns: dict: OPC server configuration dictionary """ opc_raw = getenv('OPC_CONFIG', None) if opc_raw: return json.loads(opc_raw) return { getenv('OPC_ID', '1'): { 'id': getenv('OPC_ID', '1'), 'server_name': getenv('OPC_SERVER_NAME', 'default_server'), 'url': getenv('OPC_URL', 'opc.tcp://localhost:4840'), 'server_uri': getenv('OPC_SERVER_URI', 'opc.tcp://localhost:4840'), 'cert_path': getenv('OPC_CERT_PATH', None), 'private_key_path': getenv('OPC_PRIVATE_KEY_PATH', None), 'server_cert_path': getenv('OPC_SERVER_CERT_PATH', None), 'reconnection_interval': int(getenv('OPC_RECONNECTION_INTERVAL', '120')), } } def build_minio_config() -> dict[str, Any]: """ Build MinIO (S3-compatible) configuration from environment variables. Environment Variables: MINIO_ENDPOINT_URL: Host:port or URL for the S3 API (default: http://localhost:9000) MINIO_ACCESS_KEY: Access key (default: minioadmin) MINIO_SECRET_KEY: Secret key (default: minioadmin) MINIO_DEFAULT_BUCKET: Default bucket for Laborious payloads (default: laborious) MINIO_RETENTION_HOURS: Offloaded object retention window (default: 24) MINIO_SECURE: If ``true``, use HTTPS (default: false) Return: dict[str, Any]: Keys consumed by ``Activities`` / ``MinioRepository``. """ return { 'endpoint_url': getenv('MINIO_ENDPOINT_URL', 'http://localhost:9000'), 'access_key': getenv('MINIO_ACCESS_KEY', 'minioadmin'), 'secret_key': getenv('MINIO_SECRET_KEY', 'minioadmin'), 'default_bucket': getenv('MINIO_DEFAULT_BUCKET', 'laborious'), 'retention_hours': int(getenv('MINIO_RETENTION_HOURS', '24')), 'secure': getenv('MINIO_SECURE', 'false') == 'true', }