Configuration🔗
Loading the Environment🔗
The library supports configurable settings using "value descriptors".
These descriptors are used to define settings that can change their values
based on a .env
file or environment variables.
By default, Environment-classes will look for a .env
file from the current
working directory up to the root using the python-dotenv library.
from env_config import Environment, values
class Example(Environment):
DEBUG = values.BooleanValue()
In case you want to use environment variables instead:
from env_config import Environment, values
class Example(Environment, use_environ=True):
DEBUG = values.BooleanValue()
If a value matching the setting's name is found from the configured location, it will be used to set the value of the setting, given the specific descriptor is able to convert it to the type it expects.
You can also set the path for the .env
file directly if you wish.
from env_config import Environment, values
class Example(Environment, dotenv_path="/path/to/.env"):
DEBUG = values.BooleanValue()
Or you can disable the loading the .env
file altogether.
from env_config import Environment, values
class Example(Environment, dotenv_path=None):
DEBUG = values.BooleanValue()
However, doing this with the above configuration will raise an error,
since we cannot determine the value for DEBUG
. Similarly, an error would be raised
if the .env
if loaded, but it does not contain a matching value for the setting.
Therefore, we must set a default value in the descriptor for these cases.
from env_config import Environment, values
class Example(Environment):
DEBUG = values.BooleanValue(default=False)
The default value can also be None
, but note that doing this will also skip
the normal value conversion based on the descriptor type.
In case the name of the setting in the .env
file or environment is different from the
name of the setting in the Environment class, you can specify the name of the matching
setting in the descriptor using env_name
.
from env_config import Environment, values
class Example(Environment):
DEBUG = values.BooleanValue(env_name="DJANGO_DEBUG_MODE")
Setting env_name
to None
will make the descriptor always use the default value,
even if the loaded environment contains a value for the setting. This can be useful
if the value descriptor contains some useful validation or conversion logic that you
want to use when setting the value.
Value Descriptors🔗
Value🔗
The base class for all value descriptors. This is an abstract class that can't be
used directly. All subclasses must implement the convert
method, and can be initialized
with the following arguments:
default
: The default value for the setting. If not set, a value for the setting must be found from the.env
file or environment, or an exception will be raised.env_name
: The name of the setting in the.env
file or environment. If not set, the name of the setting in the Environment class is used. If set toNone
, the descriptor will always use thedefault
value.
StringValue🔗
A value descriptor for string values. The convert
method will return the value as is.
BooleanValue🔗
A value descriptor for boolean values. The convert
method will return True
if the
value is one of the following (case-insensitive): yes
, y
, true
, 1
or False
if it's one of the following (case-insensitive): no
, n
, false
, 0
or ""
.
Otherwise, an exception will be raised.
IntegerValue🔗
A value descriptor for integer values. The convert
method will return the value as an
integer if it can be converted. Otherwise, an exception will be raised.
PositiveIntegerValue🔗
A value descriptor for positive integer values. The convert
method will return the value
as an integer if it can be converted and is greater than zero. Otherwise, an exception will
be raised.
FloatValue🔗
A value descriptor for float values. The convert
method will return the value as a float
if it can be converted. Otherwise, an exception will be raised.
DecimalValue🔗
A value descriptor for decimal values. The convert
method will return the value as a
decimal if it can be converted. Otherwise, an exception will be raised.
ImportStringValue🔗
A value descriptor for string values that should be importable. The convert
method will
return the imported value if it can be imported. Otherwise, an exception will be raised.
SequenceValue🔗
An abstract value descriptor for sequences like lists, tuples, and sets. Cannot be used directly. Accepts the following additional arguments:
child
: A value descriptor to use for the list items. If not set, the items will be returned as strings.delimiter
: The delimiter to use when splitting the string into a list. Defaults to,
.
ListValue🔗
A SequenceValue descriptor for lists. The convert
method will return the value as a
list if it can be converted. Otherwise, an exception will be raised.
TupleValue🔗
A SequenceValue descriptor for tuples. The convert
method will return the value as a
tuple if it can be converted. Otherwise, an exception will be raised.
SetValue🔗
A SequenceValue descriptor for sets. The convert
method will return the value as a
sets if it can be converted. Otherwise, an exception will be raised.
MappingValue🔗
An abstract value descriptor for sequences like dicts. Cannot be used directly. Accepts the following additional arguments:
child
: A value descriptor to use for the dict values. If not set, the items will be returned as strings.kv_delimiter
: The delimiter to use when splitting items into keys and values. Defaults to=
.item_delimiter
: The delimiter to use when splitting the string list of key-value pairs. Defaults to;
.
DictValue🔗
A MappingValue descriptor for dicts. The convert
method will return the value as a
dict if it can be converted. Otherwise, an exception will be raised.
JsonValue🔗
A value descriptor for JSON values. The convert
method will return the value as a
valid JSON value if it can be converted. Otherwise, an exception will be raised.
EmailValue🔗
A value descriptor for email values. The convert
method will return the value as is
if it's a valid email address. Otherwise, an exception will be raised.
URLValue🔗
A value descriptor for URL values. The convert
method will return the value as is
if it's a valid URL. Otherwise, an exception will be raised.
IPValue🔗
A value descriptor for IP address values. The convert
method will return the value as is
if it's a valid IP address. Otherwise, an exception will be raised.
RegexValue🔗
A value descriptor for values that should match a regular expression. Accepts the following additional arguments:
regex
: The regular expression pattern to match.
The convert
method will return the value as is if it matches the regular expression.
Otherwise, an exception will be raised.
PathValue🔗
A value descriptor for directory path values. Accepts the following additional arguments:
check_exists
: Whether to check if the path exists or not. Defaults toTrue
.create_if_missing
: IfTrue
, create the path if it doesn't exist. Defaults toFalse
.mode
: The mode to use when creating the path if it doesn't exist. Defaults to0o777
.
The convert
method will return the value as is if it's a valid directory path.
Otherwise, an exception will be raised.
DatabaseURLValue🔗
Requires the
db
extra dependency to be installed.pip install django-environment-config[db]
A value descriptor for configuring the DATABASES
setting in Django. It uses the dj_database_url
library to parse the setting from a DATABASE_URL
environment variable. See the library for more details.
The convert
method will convert the value to a dictionary that can be used as the DATABASES
setting,
if it can be parsed. Otherwise, an exception will be raised.
CacheURLValue🔗
Requires the
cache
extra dependency to be installed.pip install django-environment-config[cache]
A value descriptor for configuring the CACHES
setting in Django. It uses the django_cache_url
library to parse the setting from a CACHE_URL
environment variable. See the library for more details.
The convert
method will convert the value to a dictionary that can be used as the CACHES
setting,
if it can be parsed. Otherwise, an exception will be raised.
Computed properties🔗
In addition to value descriptors and regular class attributes, you can also use classproperties to define computed settings. This can be useful if the setting requires values from other settings.
from env_config import Environment, values
from env_config.decorators import classproperty
class Example(Environment):
DEBUG = values.BooleanValue(default=False)
@classproperty
def LOG_LEVEL(cls):
return "DEBUG" if cls.DEBUG else "INFO"
Note that value descriptors are only bound to the environment values after the class is created, so if you try to use them in the class body before that, they will be plain classes, not descriptors.
```python from env_config import Environment, values
class Example(Environment): DEBUG = values.BooleanValue(default=False)
# Debug is still a BoolenValue instance, not a descriptor. # It will always be truthy, and so LOG_LEVEL will always be "DEBUG". LOG_LEVEL = "DEBUG" if DEBUG else "INFO"
```
Configuration mixins🔗
Mixin-classes can be a useful way to reuse setting for multiple environments. Remember to add the mixin first, and the Environment second.
from env_config import Environment
class Defaults:
ADMINS = []
...
class Local(Defaults, Environment):
pass
class Prod(Defaults, Environment):
pass
Note, however, that mixins will not override values defined on the inheriting class. For this, use the overrides feature.
Overrides🔗
For local development, one useful pattern for overriding settings is to provide
a local_settings.py
file that is ignored from versioning, and contains a mixin
for overriding settings locally. This mixin can then be imported to the settings.py
file, and added to the Environment using the overrides_from
argument. This way,
any settings defined in the mixin will be used, even if the same settings are
also defined in the created Environment itself.
# local_settings.py
class LocalOverrides:
DEBUG = True
# settings.py
from env_config import Environment
# Import mixin which is ignored from version control.
# Catch import errors, since the mixin is not there in production.
try:
from local_settings import LocalOverrides
except ImportError:
class LocalOverrides: ...
class Example(Environment, overrides_from=LocalOverrides):
pass