-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A way to specify required environment variables #3
Comments
@okke-formsma thanks for the suggestion! Do you have an idea on how this will work? Is there a special way you define certain values that are required? I think this is a good idea, I am trying to think about how it plays with #2, since that says "if you didn't predefine a setting, then it won't get loaded". |
@brettlangdon, I was thinking along the lines of setting the required fields to a specific value, something like
|
Alright, I just had a idea... feel free to tell me I am crazy or complicating things. I was trying to think about other use cases, like mapping env variables to different names, or explicitly casting values to a specific type, or making certain ones required, etc etc. So I came up with the following idea/solution. from flask_env import MetaFlaskEnv, Loader
class Settings(metaclass=MetaFlaskEnv):
# This value is required, raise exception if it is not provided
SECRET_KEY = Loader.required()
# Load this value from the `DB_URI` env variable, and it is required to be set
SQLALCHEMY_DATABASE_URI = Loader.name('DB_URI').required()
# Load this value from `PORT`, default to `8000`, and explicitly cast the value to an `int`
PORT = Loader.default(8000).cast(int)
# Can still assign defaults like normal
DEBUG = True
Elasticsearch_HOST = 'localhost' |
That's nice. I'm not a very big fan of the chained commands. Maybe just use optional parameters instead? Also, I think variables should be implicitly required, unless a default value is provided. from flask_env import MetaFlaskEnv, EnvLoader
class Settings(metaclass=MetaFlaskEnv):
# This value is required, raise exception if it is not provided
SECRET_KEY = EnvLoader()
# Load this value from the `DB_URI` env variable, and it is required to be set
SQLALCHEMY_DATABASE_URI = EnvLoader(name='DB_URI')
# Load this value from `PORT`, default to `8000`, and explicitly cast the value to an `int`
PORT = EnvLoader(default=8000, cast=int)
# Can still assign defaults like normal
DEBUG = True
Elasticsearch_HOST = 'localhost' |
I gave this a stab for myself, feel free to use it in any way. This is based on the descriptor pattern (https://docs.python.org/2/howto/descriptor.html) class EnvVar():
def __init__(self, name=None, default=None, cast=None):
""" Load environment name `name`. Use default value `default`. Raises an ValueError if no environment variable
is found and no default is set. Will cast automatically to the type `cast` or to the type of `default` if not
set.
Example:
DevelopmentConfig():
DEBUG = EnvVar('FLASK_DEBUG', default=False)
PROFILE_RATE = EnvVar(cast=float)
SQLALCHEMY_DATABASE_URI = EnvVar('DB')
"""
self.name = name
self.default = default
if cast is None:
self.cast = type(default)
else:
self.cast = cast
self.value = None
def __get__(self, obj, objtype=None):
value = os.getenv(self.name)
if value is None:
if self.default is None:
raise ValueError("Environment variable `{}` was expected to be set.".format(self.name))
else:
return self.default
if self.cast is None:
return value
return self.cast(value)
def __set__(self, obj, value):
raise ValueError("This variable can not be set but will be initiated from environment values.") |
It would be nice to have a way to specify which environment variables are required to be set, so the flask app will quit early when there are environment variables missing.
The text was updated successfully, but these errors were encountered: