diff --git a/docs/cli.rst b/docs/cli.rst index b857fe9b..7ce63fd2 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -201,6 +201,30 @@ These can be added to the ``.flaskenv`` file just like ``FLASK_APP`` to control default command options. +Disable dotenv +~~~~~~~~~~~~~~ + +The ``flask`` command will show a message if it detects dotenv files but +python-dotenv is not installed. + +.. code-block:: none + + flask run + * Tip: There are .env files present. Do "pip install python-dotenv" to use them. + +You can tell Flask not to load dotenv files even when python-dotenv is +installed by setting the ``FLASK_SKIP_DOTENV`` environment variable. +This can be useful if you want to load them manually, or if you're using +a project runner that loads them already. Keep in mind that the +environment variables must be set before the app loads or it won't +configure as expected. + +.. code-block:: none + + export FLASK_SKIP_DOTENV=1 + flask run + + Environment Variables From virtualenv ------------------------------------- diff --git a/flask/cli.py b/flask/cli.py index b3a89968..635abb13 100644 --- a/flask/cli.py +++ b/flask/cli.py @@ -28,7 +28,7 @@ from werkzeug.utils import import_string from . import __version__ from ._compat import getargspec, iteritems, reraise, text_type from .globals import current_app -from .helpers import get_debug_flag, get_env +from .helpers import get_debug_flag, get_env, get_load_dotenv try: import dotenv @@ -544,7 +544,7 @@ class FlaskGroup(AppGroup): # script that is loaded here also attempts to start a server. os.environ['FLASK_RUN_FROM_CLI'] = 'true' - if self.load_dotenv: + if get_load_dotenv(self.load_dotenv): load_dotenv() obj = kwargs.get('obj') @@ -583,12 +583,11 @@ def load_dotenv(path=None): .. versionadded:: 1.0 """ - if dotenv is None: if path or os.path.exists('.env') or os.path.exists('.flaskenv'): click.secho( ' * Tip: There are .env files present.' - ' Do "pip install python-dotenv" to use them', + ' Do "pip install python-dotenv" to use them.', fg='yellow') return diff --git a/flask/helpers.py b/flask/helpers.py index 88f2302a..df0b91fc 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -68,6 +68,21 @@ def get_debug_flag(): return val.lower() not in ('0', 'false', 'no') +def get_load_dotenv(default=True): + """Get whether the user has disabled loading dotenv files by setting + :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load the + files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get('FLASK_SKIP_DOTENV') + + if not val: + return default + + return val.lower() in ('0', 'false', 'no') + + def _endpoint_from_view_func(view_func): """Internal helper that returns the default endpoint for a given function. This always is the function name. diff --git a/tests/test_cli.py b/tests/test_cli.py index f7755258..387eeeba 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -474,6 +474,14 @@ def test_dotenv_optional(monkeypatch): assert 'FOO' not in os.environ +@need_dotenv +def test_disable_dotenv_from_env(monkeypatch, runner): + monkeypatch.chdir(test_path) + monkeypatch.setitem(os.environ, 'FLASK_SKIP_DOTENV', '1') + runner.invoke(FlaskGroup()) + assert 'FOO' not in os.environ + + def test_run_cert_path(): # no key with pytest.raises(click.BadParameter):