Source code for cfgtree.types

# coding: utf-8

# Standard Libraries
import argparse
from typing import Any
import logging
import os

log = logging.getLogger(__name__)
_UNDEFINED = object()

# flake8: E741


[docs]class _CfgBase(object): default = None # type: Any """Default value""" name = None # type: str """name of the item""" xpath = None # type: atr """xpath to reach this element""" arg_type = None # type: str """argument type""" environ_var_prefix = None # type: str """prefix to use for environemn""" ignore_in_cfg = False # type: bool """ """ ignore_in_args = False # type: bool """ """ ignore_in_envvars = False # type: bool """ """ def __init__(self, long_param: str = None, description: str = None, short_param: str = None, summary: str = None, required: bool = False, default: Any = _UNDEFINED): # Note: self.name should come later by ConfigBaseModel._inject_names() self.short_param = short_param self.summary = summary self.description = description self.required = required self.forced_long_param = long_param if default != _UNDEFINED: self.default = default self._value = self.default
[docs] def set_value(self, value): """ Setter method used in `set_node_by_xpath`. """ self._value = value
@property def value(self): return self._value @value.setter def value(self, value): self.set_value(value) @property def environ_var(self): if self.environ_var_prefix: return self.environ_var_prefix + self.cmd_line_name.upper()
[docs] def get_cmd_line_params(self): a = [] if self.short_param: a.append(self.short_param) if self.name: a.append(self.long_param) return a
@property def _environ_var_value(self): return os.environ.get(self.environ_var, _UNDEFINED)
[docs] def read_environ_var(self): return str(self._environ_var_value)
@property def long_param(self): if self.forced_long_param: return self.forced_long_param if not self.xpath: return "--" + self.name.lower().replace("_", "-") return "--" + self.xpath.replace('.', '-').replace('_', '-') @property def cmd_line_name(self): return self.xpath.lower().replace("-", "_").replace(".", "_") @property def action(self): return 'store' @property def n_args(self): return None @property def safe_value(self): """ Return value as a string without compromizing information. """ return self.value @property def cfgfile_value(self): """ Return value to save in config file. """ return self.value if self.value is not None else "" @property def metavar(self): return self.name.upper()
[docs]class StringCfg(_CfgBase): """String value Example:: "a value" """ default = "" def read_environ_var(self): return str(self._environ_var_value)
[docs]class IPCfg(StringCfg): """IPv4 or IPv6 value Example:: "192.168.0.1" """
[docs]class ListOfStringCfg(_CfgBase): """ Comma separated list of string (1 argument). Example:: "a,b,c,d" """ def __init__(self, *args, **kwargs): self.default = [] super(ListOfStringCfg, self).__init__(*args, **kwargs) def read_environ_var(self): ls = self._environ_var_value return ls.split(",") @property def cfgfile_value(self): """ Return value to save in config file. """ return ",".join(self.value) @staticmethod def arg_type(string): return string.split(",")
[docs]class IntCfg(_CfgBase): """Integer value Example:: 123 """ default = 0 def read_environ_var(self): return int(self._environ_var_value)
[docs]class PortCfg(IntCfg): """Port value, with range from 1 to 65535 Example:: 49670 """
[docs]class FloatCfg(_CfgBase): """Float or double value Example:: 1,23 """ default = 0 def read_environ_var(self): return float(self._environ_var_value)
[docs]class HardcodedCfg(_CfgBase): """ Placeholder only used to store application value. It does not present an environment variable nor a command line argument. """ default = None ignore_in_args = True ignore_in_envvars = True def get_cmd_line_params(self): return [] def read_environ_var(self): return None @property def long_param(self): return None
[docs]class ConfigVersionCfg(HardcodedCfg): """ Version of the configuration storage. It does not present an environment variable nor a command line argument Example:: "1.2.3" """
[docs]class PasswordCfg(StringCfg): """Password value This can be used to handle value while limiting its exposition """ @property def password(self): return self.value @property def safe_value(self): """ Hide password in logs. """ return "*" * len(self.value)
[docs]class DirNameCfg(StringCfg): """Directory name Example:: "/path/to/existing/folder" """ default = None def set_value(self, value): self._value = os.path.abspath(value)
[docs]class ConfigFileCfg(StringCfg): """Configuration file to load rest of configuration Use to tell to your storage where the rest of the configuration should be used Example:: "/path/to/my/config.json" """ default = None ignore_in_cfg = True def __init__(self, *args, default_filename=None, **kwargs): self.default_filename = default_filename super(ConfigFileCfg, self).__init__(*args, **kwargs)
[docs]class BoolCfg(_CfgBase): """Boolean value Handle automatic integer convertion Example:: True """ default = False # type: Any def read_environ_var(self): e = os.environ.get(self.environ_var) return bool(e) @property def action(self): return 'store_true' @property def metavar(self): return None
[docs]class MultiChoiceCfg(ListOfStringCfg): """Let user choose one or mode value between several string value Example:: "a_value" """ def __init__(self, *args, choices=None, **kwargs): super(MultiChoiceCfg, self).__init__(*args, **kwargs) self.choices = choices def arg_type(self, string): items = string.split(",") for item in items: if item not in self.choices: raise argparse.ArgumentTypeError("{!r} not in available choise: {}".format( item, ", ".join(self.choices))) return items
[docs]class SingleChoiceCfg(StringCfg): """Let user choose one value between several string value Example:: "a_value" """ def __init__(self, *args, choices=None, **kwargs): super(SingleChoiceCfg, self).__init__(*args, **kwargs) self.choices = choices def arg_type(self, string): if string not in self.choices: raise argparse.ArgumentTypeError("{!r} not in available choise: {}".format( string, ", ".join(self.choices))) return string