How to check the availability of environment variables correctly?
Question:
I did a token check, if at least one token is missing, ‘True’ will not be. Now I need to deduce which variable is missing, how to do it?
PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN')
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')
def check_tokens():
"""Checks the availability of environment variables."""
ENV_VARS = [PRACTICUM_TOKEN, TELEGRAM_TOKEN, TELEGRAM_CHAT_ID]
if not all(ENV_VARS):
print('Required environment variables are missing:', ...)
else:
return True
Answers:
I might suggest putting these values inside a class. The check tokens method can be part of the class, and you can use __dict__
to dynamically get reference to all of the tokens you defined without having to duplicate code.
class Environment:
def __init__(self):
self.PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN')
self.TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
self.TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')
def check_tokens(self):
"""Checks the availability of environment variables."""
missing_vars = [var for var, value in self.__dict__.items() if not value]
if missing_vars:
print('Required environment variables are missing:', *missing_vars)
return False
else:
return True
print(Environment().check_tokens())
A minimal adaptation of your code:
PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN')
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')
ENV_VARS = ['PRACTICUM_TOKEN', 'TELEGRAM_TOKEN', 'TELEGRAM_CHAT_ID']
def check_tokens():
"""Checks the availability of environment variables."""
undefined_vars = set(filter(lambda v: globals().get(v) is not None,
ENV_VARS))
if not undefined_vars:
return True
print(f"Required environment variables are missing: {undefined_vars}")
return False
But I hate writing lines like FOO = bar('FOO')
, so here’s a more complicated approach, partly inspired by flakes answer:
class Environment:
env_vars = ['PRACTICUM_TOKEN', 'TELEGRAM_TOKEN', 'TELEGRAM_CHAT_ID']
def __init__(self):
for var in self.env_vars:
setattr(self, var, os.getenv(var))
def check_tokens(e):
"""checks the availability of environment variables."""
undefined_vars = set(filter(lambda v: not getattr(e, v), e.env_vars))
if not undefined_vars:
return True
print(f"Required environment variables are missing: {undefined_vars}")
return False
env = Environment()
check_tokens(env)
$ TELEGRAM_TOKEN=1 python3 envvars.py
Required environment variables are missing: {'TELEGRAM_CHAT_ID', 'PRACTICUM_TOKEN'}
I did a token check, if at least one token is missing, ‘True’ will not be. Now I need to deduce which variable is missing, how to do it?
PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN')
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')
def check_tokens():
"""Checks the availability of environment variables."""
ENV_VARS = [PRACTICUM_TOKEN, TELEGRAM_TOKEN, TELEGRAM_CHAT_ID]
if not all(ENV_VARS):
print('Required environment variables are missing:', ...)
else:
return True
I might suggest putting these values inside a class. The check tokens method can be part of the class, and you can use __dict__
to dynamically get reference to all of the tokens you defined without having to duplicate code.
class Environment:
def __init__(self):
self.PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN')
self.TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
self.TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')
def check_tokens(self):
"""Checks the availability of environment variables."""
missing_vars = [var for var, value in self.__dict__.items() if not value]
if missing_vars:
print('Required environment variables are missing:', *missing_vars)
return False
else:
return True
print(Environment().check_tokens())
A minimal adaptation of your code:
PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN')
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')
ENV_VARS = ['PRACTICUM_TOKEN', 'TELEGRAM_TOKEN', 'TELEGRAM_CHAT_ID']
def check_tokens():
"""Checks the availability of environment variables."""
undefined_vars = set(filter(lambda v: globals().get(v) is not None,
ENV_VARS))
if not undefined_vars:
return True
print(f"Required environment variables are missing: {undefined_vars}")
return False
But I hate writing lines like FOO = bar('FOO')
, so here’s a more complicated approach, partly inspired by flakes answer:
class Environment:
env_vars = ['PRACTICUM_TOKEN', 'TELEGRAM_TOKEN', 'TELEGRAM_CHAT_ID']
def __init__(self):
for var in self.env_vars:
setattr(self, var, os.getenv(var))
def check_tokens(e):
"""checks the availability of environment variables."""
undefined_vars = set(filter(lambda v: not getattr(e, v), e.env_vars))
if not undefined_vars:
return True
print(f"Required environment variables are missing: {undefined_vars}")
return False
env = Environment()
check_tokens(env)
$ TELEGRAM_TOKEN=1 python3 envvars.py
Required environment variables are missing: {'TELEGRAM_CHAT_ID', 'PRACTICUM_TOKEN'}