Automatically loading environment variables in a Flask app?

Viewed 3842

I have a small Flask application which uses the python-dotenv lib to load environment variables that I store in a file named .env. Everything works just fine, but I recently realized that I actually never call the load_dotenv() method, so I'm not sure how it can work. Just out of curiosity I tried to play around it a little bit:

  • I removed even the import (from dotenv import load_dotenv) - Still works
  • I renamed .env to something_else.env - Doesn't work
  • I uninstalled python-dotenv with pip - Doesn't work

I'm using version 0.10.3 and I have read the docs but didn't find anything about automatic loading of environment variables.

Any idea on how it can be possible? I could take a look at the code of python-dotenv but I'm quite new to python and I wish to spend my time on something more useful, but this thing just bugs me.

3 Answers

Flask uses load_dotenv by default. See the source

I uninstalled python-dotenv with pip - Doesn't work

Flask uses python-dotenv as an external dependency to dynamically load Environment Variables from dotenv using a separate .env file usually located under the project root near to .flaskenv file. Refer to:

I removed even the import (from dotenv import load_dotenv) - Still works

since you have installed python-dotenv package you don't need to explicitly call load_dotenv(), Flask expect by default to locate / find .env and .flaskenv files under the root of your project. But when you decide for some reason to put .env file in some where in your project structure for e.g use an instance folder which usually used to store a sensitive data of your application like .env, configs, logs, sqlite3 database file .. then you have to explicitly indicate the path to the .env file to be loaded by the app like so:

[..]

def create_app(config_object):
    """Create a Flask application using the app factory pattern."""

    app = Flask(__name__)

    load_config(app, config_object)  # here

    [..]

    return app

def load_config(app, config_object):
    """Load configuration."""

    import os

    from dotenv import load_dotenv

    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    dotenv_path = os.path.join(BASE_DIR, 'var/instance/.env')  # just an e.g

    if os.path.exists(dotenv_path):
        load_dotenv(dotenv_path)
    else:
        import sys
        print('".env" is missing.')
        sys.exit(1)

    app.config.from_object(config_object)

[..]

I renamed .env to something_else.env - Doesn't work

.env is THE name for the file to store Environment variables, you have not to rename it.

which will load environment variables from a file named .env in the current directory or any of its parents or from the path specificied

Refer to python-dotenv doc

python-dotenv is one of the best to use for loading .env files in your flask application.

I used it for my flask application as:

from dotenv import load_dotenv
env_file_name = "local.env"
env_path = Path.cwd().joinpath(f"env/{env_file_name}")
load_dotenv(dotenv_path=env_path)

After running load_dotenv() your application now has all the environment variable loaded from the .env file. So you can access them through conventional os.getenv("variable name")


    MAIL_USERNAME = os.getenv('EMAIL_USER')
    MAIL_PASSWORD = os.getenv('EMAIL_PASSWORD')

That is all you need to do. Cheers!

Related