123

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:
      .......
4
  • 22
    Environment variables can never be a boolean, they are always a string (or not present). Commented Jul 27, 2020 at 13:31
  • So, I should write: if os.environ['ENV_VAR'] == 'true': ..... right? Commented Jul 27, 2020 at 13:37
  • 3
    That depends on the semantics of that specific environment variable. They are only strings, but programs can of course endow specific strings with some special meaning, like "truth". Whether that's "true". "True", "TRUE", "yes", or "1" depends on the application. Commented Jul 27, 2020 at 14:03
  • os.environ.get('ADT_email_send',str(False))=='True' Commented Feb 24, 2024 at 23:32

14 Answers 14

185

Option 1

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


Option 2

UPDATE: After the @MattG commentary, I added a new solution that raises an error for entries like ttrue instead of returning False:

# ...
import os
# ...

TRUTHY_VALUES = ('true', '1', 't')  # Add more entries if you want, like: `y`, `yes`, `on`, ...
FALSY_VALUES = ('false', '0', 'f')  # Add more entries if you want, like: `n`, `no`, `off`, ...
VALID_VALUES = TRUTHY_VALUES + FALSY_VALUES

def get_bool_env_variable(name: str, default_value: bool | None = None) -> bool:
    value = os.getenv(name) or default_value
    if value is None:
        raise ValueError(f'Environment variable "{name}" is not set!')
    value = str(value).lower()
    if value not in VALID_VALUES:
        raise ValueError(f'Invalid value "{value}" for environment variable "{name}"!')
    return value in TRUTHY_VALUES

# ...

my_env1 = get_bool_env_variable('ENV_VAR1') # Raise error if variable was not set
my_env2 = get_bool_env_variable('ENV_VAR2', default_value=False) # return False if variable was not set
Sign up to request clarification or add additional context in comments.

5 Comments

You can add to the list ['true', '1'] other options, like: ['true', '1', 'yes', 'y', 't']
the use of bool in the above example is superfluous... a in b is always a boolean anyway
@KlaasvanSchelven, True, you are right, I will update. Thanks
The problem with this, is that if a typo is made setting the environment variable to say "ttrue" , this will not raise an exception. I think it is rare that for environment variable parsing, where you control the behavior of your code you don't want strong validation and are happy to accept values like "ttrue" being silently accepted as False.
Important bug I think: value in true_ must be changed to value.lower() in true_.
83

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

1 Comment

I would make it os.getenv('DEBUG', 'False').lower() == 'true' but awesome, thanks.
36

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'

2 Comments

From the package documentation: Note: The entire distutils package has been deprecated and will be removed in Python 3.12
PEP 0632: "setuptools is a better documented and well maintained enhancement based on distutils". But it marks distutils.util.strtobool as deprecated.
16

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.")

Comments

8

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

Comments

6

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)

Comments

5

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)

1 Comment

This is not as good of an idea as it may appear at first, because ast.literal_eval will give surprising and confusing (for the user) error messages such as SyntaxError and IndentationError with deep stack traces for bad inputs.
4

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.

1 Comment

confirmed works
2

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"]

Comments

2

Here's my 2 cents: Why not use YAML?

Code:

import os, yaml

bool(yaml.load(os.getenv("MY_VAR") or "", yaml.Loader))

Test:

for val, expected in {
    "yes": True,
    "no": False,
    "on": True,
    "off": False,
    "true": True,
    "false": False,
    "1": True,
    "0": False,
    "": False,
    None: False,
}.items():
    actual = bool(yaml.load(val or "", yaml.Loader))
    assert actual == expected

Comments

2

I prefer to require strictly that the environment variable is set to either True or False, and to not allow so many other squishy possibilities. Also, if the variable isn't defined, I want an exception to be raised.

assert os.environ["MY_KEY"] in ("True", "False")

my_key = os.environ["MY_KEY"] == "True"

This will raise a KeyError if MY_KEY is not defined, or raise an AssertionError if it's not set to either 'True' or 'False'.

If you are doing this frequently and therefore want a function, use this:

def get_env_bool(key):
    """ Handles the case of a boolean environment variable
    """
    if not key in os.environ:
        raise KeyError(f"No environment variable {key}")

    if not os.environ[key] in ("True", "False"):
        raise AssertionError(f"Key {key} is not proper boolean: {os.environ[key]}")

    return os.environ[key] == "True"

Usage:

if get_env_bool("MY_KEY"):
   ...

Comments

1

Python Version: 3.9.13 (main, May 27 2022, 17:01:00)

I used solution below and it works perfect;

In your env file;

SOMEHING_ENABLED=True

and use case in your python file;

from distutils.util import strtobool

if bool(strtobool(os.getenv('SOMEHING_ENABLED'))):
   # good to go.

Not: distutils will no longer work from version 3.12

3 Comments

distutils is deprecated: peps.python.org/pep-0632
I determined my python version and tested code.
It will no longer work from version 3.12. I will edit my answer.
1

In Django, if you are using python-dotenv also make sure you don't use DEBUG in the .env file as it will always default to True when we do os.getenv("DEBUG"). Use another variable e.g DEBUG_MODE. For example:

#.env 

DEBUG_MODE = False

#settings.py 

import os
from dotenv import load_dotenv

load_dotenv()
DEBUG = os.getenv("DEBUG_MODE", False) == "True"

1 Comment

If you use .env, you need to load it. Get path: dotenv_path = os.path.join(BASE_DIR, ".env"). Load: load_dotenv(dotenv_path). Then, you can use DEBUG in the .env file.
-5

The way I see it - why not use the builtin bool() which is similar to for instance str()

import os

my_boolean_env_var = bool(os.getenv("MY_ENV_VAR"))

2 Comments

This will return True for any value of MY_ENV_VAR because the boolean value of any string is True in Python. Hence, also values like False, false, 0, etc. will end up as True. Likely not what you want.
Any non-empty value of MY_ENV_VAR, that is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.