How can I evaluate if a env variable is a boolean True, in Python? Is it correct to use:
if os.environ['ENV_VAR'] is True:
.......
How can I evaluate if a env variable is a boolean True, in Python? Is it correct to use:
if os.environ['ENV_VAR'] is True:
.......
I think this works well:
my_env = os.getenv("ENV_VAR", 'False').lower() in ('true', '1', 't')
It allows: things like true, True, TRUE, 1, "1", TrUe, t, T, ...
Update: After I read the commentary of Klaas, I updated the original code my_env = bool(os.getenv(... to my_env = os.getenv(... because in will result in a bool type
UPDATE:
After the @MattG commentary, I added a new solution that raises an error for entries like ttrue instead of returning False:
# ...
import os
# ...
def get_variable(name: str, default_value: bool | None = None) -> bool:
true_ = ('true', '1', 't') # Add more entries if you want, like: `y`, `yes`, ...
false_ = ('false', '0', 'f')
value: str | None = os.getenv(name, None)
if value is None:
if default_value is None:
raise ValueError(f'Variable `{name}` not set!')
else:
value = str(default_value)
if value.lower() not in true_ + false_:
raise ValueError(f'Invalid value `{value}` for variable `{name}`')
return value in true_
# ...
my_env1 = get_variable("ENV_VAR1")
my_env2 = get_variable(name="ENV_VAR2") # Raise error if variable was not set
my_env3 = get_variable(name="ENV_VAR3", default_value=False) # return False if variable was not set
All the same, but thats the most readable version for me:
DEBUG = (os.getenv('DEBUG', 'False') == 'True')
Here anything but True will evaluate to False. DEBUG is False unless explicitly set to True in ENV
I recommend using strtobool function
example:
DEBUG = strtobool(os.getenv("DEBUG", "false"))
You can check them in python documentation https://docs.python.org/3/distutils/apiref.html#distutils.util.strtobool
Only one problem, they raise an error if you pass the wrong value
Code
from distutils.util import strtobool
print("Value: ", strtobool("false"))
print("Value: ", strtobool("Wrong value"))
Output
Value: 0
Traceback (most recent call last):
File "<string>", line 9, in <module>
File "/usr/lib/python3.8/distutils/util.py", line 319, in strtobool
raise ValueError("invalid truth value %r" % (val,))
ValueError: invalid truth value 'wrong value'
Neither of the ways you have will work. os.environ['ENV_VAR'] alone will cause a KeyError if the key doesn't exist, and will return the value associated with the 'ENV_VAR' if it does. In either case, you'll error out, or compare to True or "true" which will always result in False (unless the value associated with the environment variable happens to be "true"; but that isn't what you're after).
To check if a mapping contains a particular key, you would use in:
if 'ENV_VAR' in os.environ:
# It contains the key
else:
# It doesn't contain the key
Highly recommend environs:
from environs import Env
env = Env()
MY_BOOL_VALUE = env.bool("MY_BOOL_VALUE", False)
if MY_BOOL_VALUE:
print("MY_BOOL_VALUE was set to True.")
else:
print("MY_BOOL_VALUE was either set to False or was not defined.")
Another alternative that accepts either "false", "False", "true" or "True":
import os
import ast
def getenv_bool(name: str, default: str = "False"):
raw = os.getenv(name, default).title()
return ast.literal_eval(raw)
I use the following to have more strict typing and support wider boolean variations in inputs
import os
def getenv_bool(name: str, default: bool = False) -> bool:
return os.getenv(name, str(default)).lower() in ("yes", "y", "true", "1", "t")
Usage :
feature_1=getenv_bool('FEATURE_1', False)
Another possible solution is parse values as JSON values:
import json
import os
def getenv(name, default="null"):
try:
return json.loads(os.getenv(name, default))
except json.JSONDecodeError:
return name
The try is for cases when is not possible a direct conversion.
assert getenv("0") == 0
assert getenv("1.1") = 1.1
assert getenv("true") == True
assert getenv("Hello") = "Hello"
assert getenv('["list", "of", "strings"]') == ["list", "of", "strings"]
If you don't want to use the environs library mentioned above then strtobool is perfect for this. The only problem is it is deprecated, there does not seem to be a replacement library anywhere, but luckily it is only a few lines of simple code with no dependencies. Just implement the code:
# Copied from distutils.util.strtobool, which is deprecated
def strtobool (val):
"""Convert a string representation of truth to true (1) or false (0).
True values are case insensitive 'y', 'yes', 't', 'true', 'on', and '1'.
false values are case insensitive 'n', 'no', 'f', 'false', 'off', and '0'.
Raises ValueError if 'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))
Use it like this:
my_env_var_value = strtobool(os.getenv("ENV_VAR", "False"))
And YES, this will throw an error if the environment variable has some value that is neither true nor false. In the great majority of cases that is probably the best course of action.