API¶
This part of the documentation briefly covers the interfaces of Concrete Settings.
Settings¶
-
class
concrete_settings.setting.Setting(value=<class 'concrete_settings.types.Undefined'>, *, doc='', validators=(), type_hint=<class 'concrete_settings.types.GuessSettingType'>, override=False)[source]¶ A setting is a named object for storing, documenting and validating a certain value.
- Parameters
value (
Any) – the initial value of a setting with the defaultUndefined.doc (str) – an end-user -friendly setting documentation.
validators (tuple) – setting validators, a tuple of
Validatorcallables.type_hint (
Any) – setting type, something one would use as type annotation. The default value (GuessSettingType) would invoke type guessing mechanism.override (bool) – a indicates that settings definiton is explicitly overriden.
The corresponding implicit definition of a setting in Settings class is written as following:
class MySettings(Settings): default_validators = (...) mandatory_validators = (...) #: Documentation is written #: in Sphinx-style comments above #: the setting definition SETTING_NAME: type_hint = value @behavior1 @behavior2 @...
-
name¶ Setting attribute name (read-only).
-
_behaviors¶ Internal attribute for storing behaviors attached to the setting
-
class
concrete_settings.settings.Settings(**kwargs)[source]¶ Settings is a container for one or more
Settingobjects. Settings classes can be mixed and nested.-
default_validators¶ Validators applied to each Setting that have no defined validators.
-
mandatory_validators¶ Validators applied to every Setting in the class.
- Type
- Value
-
is_valid(raise_exception=False) → bool[source]¶ Validate settings and return
Trueif settings are valid.If
raise_exceptionis False, validation errors are stored inself.errors. Otherwise aValidationErroris raised when the first invalid setting is encountered.
-
validate()[source]¶ Validate settings altogether.
This is a stub method intended to be overriden when needed. It is called after individual settings have been validated without any errors.
Raise
ValidationErrorto indicate errors.
-
property
errors¶ errorsproperty contains validation errors from the lastsettings.is_valid(raise_exception=False)call. The errors are packed in recursiveValidationErrorDetailstructure.
-
property
is_being_validated¶ Indicates that settings are being validated.
The property is intended to be used by behaviors to distinguish between Setting reads during validation and normal usage.
-
update(source[, strategies])[source]¶ Update settings from the given source.
The update process consist of two stages:
Intializing an access and/or reading a source object - Python, YAML or JSON file, environmental variables, a dict,
locals()etc.Update the settings by the values read from the sources.
-
-
class
concrete_settings.settings.setting¶
-
class
concrete_settings.settings.PropertySetting[source]¶ @setting(an alias toPropertySettingdecorator-class) is used to mark class methods as settings. The property-settings are read-only and used to compute a value, usually based on other settings. For example:class AppSettings(Settings): ADMIN_NAME: str = 'Alex' ADMIN_EMAIL: str = 'alex@example.com' @setting def ADMIN_FULL_EMAIL(self) -> str: """Full admin email in `name <email>` format""" return f'{self.ADMIN_NAME} <{self.ADMIN_EMAIL}>'
Note that methods written in UPPER_CASE are converted to
PropertySettingautomatically and do not require decoration by@setting.
Types¶
-
class
concrete_settings.types.Undefined(*args, **kwargs)[source]¶ A special Setting value which indicates that a value should be set by other means, e.g. by updating the settings object. Often used in conjuction with
RequiredValidatorandrequiredbehavior.class AppSettings(Settings): SPEED: int = Undefined
-
class
concrete_settings.types.GuessSettingType[source]¶ A special value for
Setting.type_hint, which indicates that a Setting type should be guessed from the default value.For an
Undefinedor an unknown type, the guessed type hint istyping.Any.-
KNOWN_TYPES= [<class 'bool'>, <class 'int'>, <class 'float'>, <class 'complex'>, <class 'list'>, <class 'tuple'>, <class 'range'>, <class 'bytes'>, <class 'str'>, <class 'frozenset'>, <class 'set'>, <class 'dict'>]¶ Recognized Setting value types
-
Validators¶
-
class
concrete_settings.validators.Validator(Protocol)[source]¶ A validator is a callable that raises an exception if a value is wrong.
A validator accepts a value as a mandatory argument, and keyword-only arguments referring to settings, setting and setting’s name.
-
class
concrete_settings.exceptions.ValidationError(details='')[source]¶ Raised by a setting validator when a setting value is invalid.
-
concrete_settings.exceptions.ValidationErrorDetails= typing.Union[str, typing.List[ForwardRef('ValidationErrorDetails')], typing.Dict[str, ForwardRef('ValidationErrorDetails')]]¶ A recursive union type which describes validation errors.
ValidationErrorDetailsis defined asSettingName = str ValidationErrorDetails = Union[ str, List[ValidationErrorDetails], Dict[SettingName, ValidationErrorDetails] ]
ValueTypeValidator¶
-
class
concrete_settings.validators.ValueTypeValidator(*args, **kwds)[source]¶ Matches setting value type and its type hint.
Setting value type should match
setting.type_hint.Undefinedvalue is considered valid for any type hint.ValueTypeValidatoris the default validator inSettings.mandatory_validators.- Parameters
type_hint – If
setting.type_hintisNone, then type match is performed against the giventype_hint.
RequiredValidator¶
-
class
concrete_settings.validators.RequiredValidator(message=None)[source]¶ Validates that setting value is not
UndefinedFor convenient usage, seerequiredbehavior.- Parameters
message – Custom validation error message template.
- Value message
“Setting {name} is required to have a value. Current value is `Undefined`”
DeprecatedValidator¶
-
class
concrete_settings.contrib.validators.DeprecatedValidator(msg, raise_exception=False)[source]¶ Emits a warning or raises ValidationError <concrete_settings.exceptions.ValidationError> indicating that setting is deprecated.
This is a helper validator added to a Setting attribute validators by
@deprecatedbehavior.
Behaviors¶
-
class
concrete_settings.behaviors.Behavior(*args, init_with_arguments=False, **kwargs)[source]¶ Base class for Setting attributes behaviors.
-
decorate(setting: concrete_settings.setting.Setting)[source]¶ Decorate setting attribute.
If your custom behavior adds a validator to the Setting, override this method as follows:
def decorate(self, setting): setting.validators = ( MyValidator() ) + setting.validators super().attach_to(setting)
- Parameters
setting – Setting to which the behavior is attached.
- Returns
Passed setting object.
-
-
class
concrete_settings.behaviors.GetterSetterBehavior(*args, init_with_arguments=False, **kwargs)[source]¶ A base class for behaviors which provide custom get / set behavior. The super class methods have to be invoked to invoke behaviors get / set chain down to the decorated original setting.
-
get_value(setting, owner)[source]¶ - Return type
- Parameters
Invoked when the decorated Setting is being read.
When overriding this method remember to call the base class method
super().get_value(setting, owner)to invoke the chained behaviors down to the setting’s original value getter. For example:def get_value(self, setting: 'Setting', owner: 'Settings') -> Any: val = super().get_value(setting, owner) print(f"Setting {setting.name} has been accessed, its value was {val}") return val
-
override¶
Sets Setting.override = True.
Usage:
from concrete_settings import Settings, override
class BaseSettings(Settings):
SECRET: int = 100200300400500
...
class DevSettings(BaseSettings):
SECRET: str = 'abcdef12345' @override
validate¶
Provides behavior-style way of attaching validators to a setting.
from concrete_settings import Settings, validate, ValidationError
def is_positive(value, **kwargs):
if value <= 0:
raise ValidationError(f'must be a positive integer')
class AppSettings(Settings):
SPEED: int = 20 @ validate(is_positive)
app_settings = AppSettings()
app_settings.SPEED = -10
print(app_settings.is_valid())
print(app_settings.errors)
False
{'SPEED': ['must be a positive integer']}
required¶
-
class
concrete_settings.contrib.behaviors.required(message=None)[source]¶ Attaches
RequiredValidatorto the setting which validates that setting value is notUndefined.Usage:
from concrete_settings import Settings, Undefined, required class AppSettings(Settings): SECRET_STRING: str = Undefined @required
deprecated¶
-
class
concrete_settings.contrib.behaviors.deprecated(deprecation_message='Setting `{name}` in class `{owner}` is deprecated.', *, warn_on_validation=True, error_on_validation=False, warn_on_get=False, warn_on_set=False)[source]¶ Emit warnings when Setting is read, written or being validated.
- Parameters
deprecation_message –
Warning message template. Placeholders:
{name}- setting name.{owner}- ownerSettingsobject.
warn_on_validation (bool) – Add warning-raising
DeprecatedValidatorto the setting’s validators list.error_on_validation (bool) – Add exception-raising
DeprecatedValidatorto the setting’s validators list. When this parameter is set toTrue,warn_on_validationis ignored.warn_on_get (bool) – Emit warning when reading the setting.
warn_on_set (bool) – Emit warning when writing the setting.
Sources¶
-
concrete_settings.sources.AnySource¶ AnySource = Union[Dict[str, Any], str, 'Source', Path]Valid settings sources types union. A valid source is either a
dict, an instance ofSourceor a path (str orPath)
-
class
concrete_settings.sources.Source[source]¶ The base class of all Concrete Settings sources.
-
static
get_source(src)[source]¶ -
A static method which returns a
Sourceinstance orNoneifsrcis not suitable. For example,DictSourceimplements it as follows:
@staticmethod def get_source(src: AnySource) -> Optional['DictSource']: if isinstance(src, dict): return DictSource(src) elif isinstance(src, DictSource): return src else: return None
-
read(setting, parents=())[source]¶ - Return type
- Parameters
setting (
Setting) – Setting attribute instance being processed. Usuallysetting.nameis of interest.parents (tuple[str]) – A chain of parent Settings classes names (i.e. in case of nested settings). This is used to map source setting keys like
DB_HOST_PORTtoAppSettings.DB.HOST.PORT. In this caseparents=('DB', 'HOST').
Called for each setting from settings beign read. A source should return the corresponding value.
read()should returnNotFoundif setting value was not provided by the source.
-
static
-
class
concrete_settings.sources.NotFound[source]¶ Returned by
Source.readwhen setting value is not provided by the source.
Update strategies¶
-
class
concrete_settings.sources.strategies.Strategy(Protocol)[source]¶ A strategy decides how a setting value will be
updated.-
abstract
__call__(current_value, new_value)[source]¶ Call self as a function.
The signature of Strategy callables
- Parameters
current_value – is the current value of a setting
new_value – is the new_value from a source.
Usually a strategy is a simple and small function. For example if a setting is a tuple, the following strategy would append values, instead of overwriting the tuple:
# the required strategy def append(new_val, old_val): return new_val + old_val class AppSettings(Settings): ADMIN_EMAILS: Tuple[str] = ('cto@example.com', ) app_settings = AppSettings() app_settings.update( source={ 'ADMIN_EMAILS': ('alex@example.com', ) }, strategies={ 'ADMIN_EMAILS': append } ) print(app_settings.ADMIN_EMAILS)
Output:
('cto@example.com', 'alex@example.com')-
abstract