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
Validator
callables.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
Setting
objects. 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
True
if settings are valid.If
raise_exception
is False, validation errors are stored inself.errors
. Otherwise aValidationError
is 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
ValidationError
to indicate errors.
-
property
errors
¶ errors
property contains validation errors from the lastsettings.is_valid(raise_exception=False)
call. The errors are packed in recursiveValidationErrorDetail
structure.
-
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 toPropertySetting
decorator-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
PropertySetting
automatically 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
RequiredValidator
andrequired
behavior.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
Undefined
or 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.
ValidationErrorDetails
is 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
.Undefined
value is considered valid for any type hint.ValueTypeValidator
is the default validator inSettings.mandatory_validators
.- Parameters
type_hint – If
setting.type_hint
isNone
, then type match is performed against the giventype_hint
.
RequiredValidator¶
-
class
concrete_settings.validators.
RequiredValidator
(message=None)[source]¶ Validates that setting value is not
Undefined
For convenient usage, seerequired
behavior.- 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
@deprecated
behavior.
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
RequiredValidator
to 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}
- ownerSettings
object.
warn_on_validation (bool) – Add warning-raising
DeprecatedValidator
to the setting’s validators list.error_on_validation (bool) – Add exception-raising
DeprecatedValidator
to the setting’s validators list. When this parameter is set toTrue
,warn_on_validation
is 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 ofSource
or 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
Source
instance orNone
ifsrc
is not suitable. For example,DictSource
implements 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.name
is 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_PORT
toAppSettings.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 returnNotFound
if setting value was not provided by the source.
-
static
-
class
concrete_settings.sources.
NotFound
[source]¶ Returned by
Source.read
when 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