import argparse import dataclasses import os import typing from app import PKG_NAME @dataclasses.dataclass(frozen=True, slots=True) class Parameters: debug: bool = False quiet: bool = False env: str = "production" bind: str = "0.0.0.0" port: int = 5000 workers: int = 4 timeout: int = 120 db_url: str = "postgres://postgres:5432/tout-doux" @classmethod def from_namespace(cls, args: argparse.Namespace) -> Parameters: return Parameters(**vars(args)) def __get_env_str(var: str, default: str) -> str: if (result := os.getenv(var)) is None: return default return result def __get_env_int(var: str, default: int) -> int: value = __get_env_str(var, str(default)) if value.isdecimal(): return int(value) return default def __add_arg_str( parser: argparse.ArgumentParser, *flags: str, env_var: str, default: str, help_txt: str, ) -> None: parser.add_argument( *flags, metavar=env_var, default=__get_env_str(env_var, default), help=f"{help_txt} (default: {default})" if len(default) else help_txt, ) def __add_arg_int( parser: argparse.ArgumentParser, *flags: str, env_var: str, default: int, help_txt: str, ) -> None: parser.add_argument( *flags, type=int, metavar=env_var, default=__get_env_int(env_var, default), help=f"{help_txt} (default: {default})", ) def parse_parameters(args: typing.Sequence[str]) -> Parameters: default_values = Parameters() parser = argparse.ArgumentParser( PKG_NAME, suggest_on_error=True, ) parser.add_argument( "--debug", action=argparse.BooleanOptionalAction, default=default_values.debug ) parser.add_argument( "--quiet", action=argparse.BooleanOptionalAction, default=default_values.quiet ) __add_arg_str( parser, "--env", env_var="APP_ENV", default=default_values.env, help_txt="environnement", ) __add_arg_str( parser, "--bind", env_var="BIND", default=default_values.bind, help_txt="server bind address", ) __add_arg_int( parser, "--port", env_var="PORT", default=default_values.port, help_txt="server http port", ) __add_arg_int( parser, "--workers", env_var="WORKERS", default=default_values.workers, help_txt="WSGI workers", ) __add_arg_int( parser, "--timeout", env_var="TIMEOUT", default=default_values.timeout, help_txt="WSGI timeout", ) __add_arg_str( parser, "--db-url", env_var="DB_URL", default=default_values.db_url, help_txt="database connection url", ) parsed_args = parser.parse_args(args) return Parameters.from_namespace(parsed_args)