from pathlib import Path from typing import Annotated, Type from pydantic import AfterValidator from pydantic_settings import BaseSettings, CliSettingsSource, SettingsConfigDict def is_valid_host(value: str) -> str: if not value: raise ValueError('Host cannot be empty') return value def is_valid_port(value: int) -> int: if not (0 < value < 65536): raise ValueError('Port must be between 1 and 65535') return value def is_valid_streamname(value: str) -> str: if len(value) > 16: raise ValueError('Stream name cannot be longer than 16 characters') return value class Settings(BaseSettings): host: Annotated[str, AfterValidator(is_valid_host)] = 'localhost' port: Annotated[int, AfterValidator(is_valid_port)] = 6980 streamname: Annotated[str, AfterValidator(is_valid_streamname)] = 'Command1' model_config = SettingsConfigDict( env_file=( '.env', Path.home() / '.config' / 'vban-tui' / 'config.env', ), env_file_encoding='utf-8', env_prefix='VBAN_TUI_', cli_prefix='', cli_parse_args=True, cli_implicit_flags=True, validate_assignment=True, frozen=False, ) @classmethod def settings_customise_sources( cls, settings_cls: Type[BaseSettings], init_settings: ..., env_settings: ..., dotenv_settings: ..., file_secret_settings: ..., ) -> tuple: return ( CliSettingsSource(settings_cls), env_settings, dotenv_settings, init_settings, )