2010-05-27 23:42:01 +08:00
|
|
|
Configuration Handling
|
|
|
|
======================
|
|
|
|
|
2011-08-17 13:38:34 +08:00
|
|
|
Applications need some kind of configuration. There are different settings
|
|
|
|
you might want to change depending on the application environment like
|
|
|
|
toggling the debug mode, setting the secret key, and other such
|
|
|
|
environment-specific things.
|
2010-05-27 23:42:01 +08:00
|
|
|
|
|
|
|
The way Flask is designed usually requires the configuration to be
|
2019-05-15 04:08:00 +08:00
|
|
|
available when the application starts up. You can hard code the
|
2010-06-28 11:49:50 +08:00
|
|
|
configuration in the code, which for many small applications is not
|
2010-05-27 23:42:01 +08:00
|
|
|
actually that bad, but there are better ways.
|
|
|
|
|
|
|
|
Independent of how you load your config, there is a config object
|
|
|
|
available which holds the loaded configuration values:
|
|
|
|
The :attr:`~flask.Flask.config` attribute of the :class:`~flask.Flask`
|
|
|
|
object. This is the place where Flask itself puts certain configuration
|
|
|
|
values and also where extensions can put their configuration values. But
|
|
|
|
this is also where you can have your own configuration.
|
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
|
2010-05-27 23:42:01 +08:00
|
|
|
Configuration Basics
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
The :attr:`~flask.Flask.config` is actually a subclass of a dictionary and
|
|
|
|
can be modified just like any dictionary::
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
2018-01-07 00:07:56 +08:00
|
|
|
app.config['TESTING'] = True
|
2010-05-27 23:42:01 +08:00
|
|
|
|
|
|
|
Certain configuration values are also forwarded to the
|
2011-08-17 13:38:34 +08:00
|
|
|
:attr:`~flask.Flask` object so you can read and write them from there::
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2018-01-07 00:07:56 +08:00
|
|
|
app.testing = True
|
2010-05-27 23:42:01 +08:00
|
|
|
|
|
|
|
To update multiple keys at once you can use the :meth:`dict.update`
|
|
|
|
method::
|
|
|
|
|
|
|
|
app.config.update(
|
2018-01-07 00:07:56 +08:00
|
|
|
TESTING=True,
|
2021-10-12 21:00:50 +08:00
|
|
|
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
|
2010-05-27 23:42:01 +08:00
|
|
|
)
|
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
|
2018-01-07 00:07:56 +08:00
|
|
|
Environment and Debug Features
|
|
|
|
------------------------------
|
2017-03-04 18:29:04 +08:00
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
The :data:`ENV` and :data:`DEBUG` config values are special because they
|
|
|
|
may behave inconsistently if changed after the app has begun setting up.
|
2022-06-18 00:26:26 +08:00
|
|
|
In order to set the environment and debug mode reliably, pass options to
|
|
|
|
the ``flask`` command or use environment variables.
|
2017-03-04 18:29:04 +08:00
|
|
|
|
2022-06-18 00:26:26 +08:00
|
|
|
The execution environment is used to indicate to Flask, extensions, and
|
|
|
|
other programs, like Sentry, what context Flask is running in. It is
|
|
|
|
controlled with the ``FLASK_ENV`` environment variable, or the
|
|
|
|
``--env`` option when using the ``flask`` command, and defaults to
|
|
|
|
``production``.
|
2017-03-04 18:29:04 +08:00
|
|
|
|
2022-06-18 00:26:26 +08:00
|
|
|
Setting ``--env development`` will enable debug mode. ``flask run`` will
|
|
|
|
use the interactive debugger and reloader by default in debug mode. To
|
|
|
|
control this separately from the environment, use the
|
|
|
|
``--debug/--no-debug`` option or the ``FLASK_DEBUG`` environment
|
|
|
|
variable.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
To switch Flask to the development environment and enable debug mode,
|
2022-06-18 00:26:26 +08:00
|
|
|
set ``--env``:
|
2020-10-16 05:08:37 +08:00
|
|
|
|
2022-06-18 00:26:26 +08:00
|
|
|
.. code-block:: text
|
2020-10-16 05:08:37 +08:00
|
|
|
|
2022-06-18 00:26:26 +08:00
|
|
|
$ flask --app hello --env development run
|
2018-01-11 07:38:52 +08:00
|
|
|
|
2022-06-18 00:26:26 +08:00
|
|
|
Using the options or environment variables as described above is
|
|
|
|
recommended. While it is possible to set :data:`ENV` and :data:`DEBUG`
|
|
|
|
in your config or code, this is strongly discouraged. They can't be read
|
|
|
|
early by the ``flask`` command, and some systems or extensions may have
|
|
|
|
already configured themselves based on a previous value.
|
2018-01-07 00:07:56 +08:00
|
|
|
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2010-05-27 23:42:01 +08:00
|
|
|
Builtin Configuration Values
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
The following configuration values are used internally by Flask:
|
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
.. py:data:: ENV
|
|
|
|
|
|
|
|
What environment the app is running in. Flask and extensions may
|
|
|
|
enable behaviors based on the environment, such as enabling debug
|
|
|
|
mode. The :attr:`~flask.Flask.env` attribute maps to this config
|
|
|
|
key. This is set by the :envvar:`FLASK_ENV` environment variable and
|
|
|
|
may not behave as expected if set in code.
|
|
|
|
|
|
|
|
**Do not enable development when deploying in production.**
|
|
|
|
|
|
|
|
Default: ``'production'``
|
|
|
|
|
|
|
|
.. versionadded:: 1.0
|
|
|
|
|
2017-05-29 05:04:18 +08:00
|
|
|
.. py:data:: DEBUG
|
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
Whether debug mode is enabled. When using ``flask run`` to start the
|
|
|
|
development server, an interactive debugger will be shown for
|
|
|
|
unhandled exceptions, and the server will be reloaded when code
|
|
|
|
changes. The :attr:`~flask.Flask.debug` attribute maps to this
|
|
|
|
config key. This is enabled when :data:`ENV` is ``'development'``
|
|
|
|
and is overridden by the ``FLASK_DEBUG`` environment variable. It
|
|
|
|
may not behave as expected if set in code.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
**Do not enable debug mode when deploying in production.**
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2018-04-27 22:37:13 +08:00
|
|
|
Default: ``True`` if :data:`ENV` is ``'development'``, or ``False``
|
2018-01-11 07:38:52 +08:00
|
|
|
otherwise.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
.. py:data:: TESTING
|
|
|
|
|
|
|
|
Enable testing mode. Exceptions are propagated rather than handled by the
|
|
|
|
the app's error handlers. Extensions may also change their behavior to
|
|
|
|
facilitate easier testing. You should enable this in your own tests.
|
|
|
|
|
|
|
|
Default: ``False``
|
|
|
|
|
|
|
|
.. py:data:: PROPAGATE_EXCEPTIONS
|
|
|
|
|
|
|
|
Exceptions are re-raised rather than being handled by the app's error
|
|
|
|
handlers. If not set, this is implicitly true if ``TESTING`` or ``DEBUG``
|
|
|
|
is enabled.
|
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
|
|
|
.. py:data:: TRAP_HTTP_EXCEPTIONS
|
|
|
|
|
|
|
|
If there is no handler for an ``HTTPException``-type exception, re-raise it
|
|
|
|
to be handled by the interactive debugger instead of returning it as a
|
|
|
|
simple error response.
|
|
|
|
|
|
|
|
Default: ``False``
|
|
|
|
|
2017-12-14 11:08:33 +08:00
|
|
|
.. py:data:: TRAP_BAD_REQUEST_ERRORS
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
Trying to access a key that doesn't exist from request dicts like ``args``
|
|
|
|
and ``form`` will return a 400 Bad Request error page. Enable this to treat
|
|
|
|
the error as an unhandled exception instead so that you get the interactive
|
2017-05-30 10:08:25 +08:00
|
|
|
debugger. This is a more specific version of ``TRAP_HTTP_EXCEPTIONS``. If
|
|
|
|
unset, it is enabled in debug mode.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2017-05-30 10:08:25 +08:00
|
|
|
Default: ``None``
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
.. py:data:: SECRET_KEY
|
|
|
|
|
|
|
|
A secret key that will be used for securely signing the session cookie
|
|
|
|
and can be used for any other security related needs by extensions or your
|
2020-04-04 02:58:16 +08:00
|
|
|
application. It should be a long random ``bytes`` or ``str``. For
|
|
|
|
example, copy the output of this to your config::
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2021-10-18 16:37:39 +08:00
|
|
|
$ python -c 'import secrets; print(secrets.token_hex())'
|
2021-10-12 21:00:50 +08:00
|
|
|
'192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
**Do not reveal the secret key when posting questions or committing code.**
|
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
|
|
|
.. py:data:: SESSION_COOKIE_NAME
|
|
|
|
|
|
|
|
The name of the session cookie. Can be changed in case you already have a
|
|
|
|
cookie with the same name.
|
|
|
|
|
|
|
|
Default: ``'session'``
|
|
|
|
|
|
|
|
.. py:data:: SESSION_COOKIE_DOMAIN
|
|
|
|
|
|
|
|
The domain match rule that the session cookie will be valid for. If not
|
2018-02-23 23:51:34 +08:00
|
|
|
set, the cookie will be valid for all subdomains of :data:`SERVER_NAME`.
|
|
|
|
If ``False``, the cookie's domain will not be set.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
|
|
|
.. py:data:: SESSION_COOKIE_PATH
|
|
|
|
|
|
|
|
The path that the session cookie will be valid for. If not set, the cookie
|
|
|
|
will be valid underneath ``APPLICATION_ROOT`` or ``/`` if that is not set.
|
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
|
|
|
.. py:data:: SESSION_COOKIE_HTTPONLY
|
|
|
|
|
|
|
|
Browsers will not allow JavaScript access to cookies marked as "HTTP only"
|
|
|
|
for security.
|
|
|
|
|
|
|
|
Default: ``True``
|
|
|
|
|
|
|
|
.. py:data:: SESSION_COOKIE_SECURE
|
|
|
|
|
|
|
|
Browsers will only send cookies with requests over HTTPS if the cookie is
|
|
|
|
marked "secure". The application must be served over HTTPS for this to make
|
|
|
|
sense.
|
|
|
|
|
|
|
|
Default: ``False``
|
|
|
|
|
2018-01-23 21:57:50 +08:00
|
|
|
.. py:data:: SESSION_COOKIE_SAMESITE
|
|
|
|
|
2018-01-24 07:11:50 +08:00
|
|
|
Restrict how cookies are sent with requests from external sites. Can
|
|
|
|
be set to ``'Lax'`` (recommended) or ``'Strict'``.
|
|
|
|
See :ref:`security-cookie`.
|
2018-01-23 21:57:50 +08:00
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
2018-01-24 07:11:50 +08:00
|
|
|
.. versionadded:: 1.0
|
|
|
|
|
2017-05-30 01:29:06 +08:00
|
|
|
.. py:data:: PERMANENT_SESSION_LIFETIME
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2017-08-01 23:28:32 +08:00
|
|
|
If ``session.permanent`` is true, the cookie's expiration will be set this
|
|
|
|
number of seconds in the future. Can either be a
|
|
|
|
:class:`datetime.timedelta` or an ``int``.
|
|
|
|
|
|
|
|
Flask's default cookie implementation validates that the cryptographic
|
|
|
|
signature is not older than this value.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
Default: ``timedelta(days=31)`` (``2678400`` seconds)
|
|
|
|
|
|
|
|
.. py:data:: SESSION_REFRESH_EACH_REQUEST
|
|
|
|
|
|
|
|
Control whether the cookie is sent with every response when
|
|
|
|
``session.permanent`` is true. Sending the cookie every time (the default)
|
|
|
|
can more reliably keep the session from expiring, but uses more bandwidth.
|
|
|
|
Non-permanent sessions are not affected.
|
|
|
|
|
|
|
|
Default: ``True``
|
|
|
|
|
|
|
|
.. py:data:: USE_X_SENDFILE
|
|
|
|
|
|
|
|
When serving files, set the ``X-Sendfile`` header instead of serving the
|
|
|
|
data with Flask. Some web servers, such as Apache, recognize this and serve
|
|
|
|
the data more efficiently. This only makes sense when using such a server.
|
|
|
|
|
|
|
|
Default: ``False``
|
|
|
|
|
2017-05-30 01:29:06 +08:00
|
|
|
.. py:data:: SEND_FILE_MAX_AGE_DEFAULT
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
When serving files, set the cache control max age to this number of
|
2020-11-06 01:00:57 +08:00
|
|
|
seconds. Can be a :class:`datetime.timedelta` or an ``int``.
|
2017-05-29 05:04:18 +08:00
|
|
|
Override this value on a per-file basis using
|
2020-11-06 01:00:57 +08:00
|
|
|
:meth:`~flask.Flask.get_send_file_max_age` on the application or
|
|
|
|
blueprint.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
2020-11-06 01:00:57 +08:00
|
|
|
If ``None``, ``send_file`` tells the browser to use conditional
|
|
|
|
requests will be used instead of a timed cache, which is usually
|
|
|
|
preferable.
|
|
|
|
|
|
|
|
Default: ``None``
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
.. py:data:: SERVER_NAME
|
|
|
|
|
2018-02-23 23:51:34 +08:00
|
|
|
Inform the application what host and port it is bound to. Required
|
|
|
|
for subdomain route matching support.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
If set, will be used for the session cookie domain if
|
2018-02-23 23:51:34 +08:00
|
|
|
:data:`SESSION_COOKIE_DOMAIN` is not set. Modern web browsers will
|
|
|
|
not allow setting cookies for domains without a dot. To use a domain
|
|
|
|
locally, add any names that should route to the app to your
|
|
|
|
``hosts`` file. ::
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
127.0.0.1 localhost.dev
|
|
|
|
|
|
|
|
If set, ``url_for`` can generate external URLs with only an application
|
|
|
|
context instead of a request context.
|
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
|
|
|
.. py:data:: APPLICATION_ROOT
|
|
|
|
|
|
|
|
Inform the application what path it is mounted under by the application /
|
2019-06-01 03:33:06 +08:00
|
|
|
web server. This is used for generating URLs outside the context of a
|
|
|
|
request (inside a request, the dispatcher is responsible for setting
|
2020-04-05 03:57:14 +08:00
|
|
|
``SCRIPT_NAME`` instead; see :doc:`/patterns/appdispatch`
|
2019-06-01 03:33:06 +08:00
|
|
|
for examples of dispatch configuration).
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
Will be used for the session cookie path if ``SESSION_COOKIE_PATH`` is not
|
|
|
|
set.
|
|
|
|
|
|
|
|
Default: ``'/'``
|
|
|
|
|
|
|
|
.. py:data:: PREFERRED_URL_SCHEME
|
|
|
|
|
|
|
|
Use this scheme for generating external URLs when not in a request context.
|
|
|
|
|
|
|
|
Default: ``'http'``
|
|
|
|
|
|
|
|
.. py:data:: MAX_CONTENT_LENGTH
|
|
|
|
|
|
|
|
Don't read more than this many bytes from the incoming request data. If not
|
|
|
|
set and the request does not specify a ``CONTENT_LENGTH``, no data will be
|
|
|
|
read for security.
|
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
|
|
|
.. py:data:: JSON_AS_ASCII
|
|
|
|
|
2020-04-04 02:58:16 +08:00
|
|
|
Serialize objects to ASCII-encoded JSON. If this is disabled, the
|
|
|
|
JSON returned from ``jsonify`` will contain Unicode characters. This
|
|
|
|
has security implications when rendering the JSON into JavaScript in
|
|
|
|
templates, and should typically remain enabled.
|
2017-05-29 05:04:18 +08:00
|
|
|
|
|
|
|
Default: ``True``
|
|
|
|
|
|
|
|
.. py:data:: JSON_SORT_KEYS
|
|
|
|
|
|
|
|
Sort the keys of JSON objects alphabetically. This is useful for caching
|
|
|
|
because it ensures the data is serialized the same way no matter what
|
|
|
|
Python's hash seed is. While not recommended, you can disable this for a
|
|
|
|
possible performance improvement at the cost of caching.
|
|
|
|
|
|
|
|
Default: ``True``
|
|
|
|
|
|
|
|
.. py:data:: JSONIFY_PRETTYPRINT_REGULAR
|
|
|
|
|
|
|
|
``jsonify`` responses will be output with newlines, spaces, and indentation
|
|
|
|
for easier reading by humans. Always enabled in debug mode.
|
|
|
|
|
|
|
|
Default: ``False``
|
|
|
|
|
|
|
|
.. py:data:: JSONIFY_MIMETYPE
|
|
|
|
|
|
|
|
The mimetype of ``jsonify`` responses.
|
|
|
|
|
|
|
|
Default: ``'application/json'``
|
|
|
|
|
|
|
|
.. py:data:: TEMPLATES_AUTO_RELOAD
|
|
|
|
|
|
|
|
Reload templates when they are changed. If not set, it will be enabled in
|
|
|
|
debug mode.
|
|
|
|
|
|
|
|
Default: ``None``
|
|
|
|
|
|
|
|
.. py:data:: EXPLAIN_TEMPLATE_LOADING
|
|
|
|
|
|
|
|
Log debugging information tracing how a template file was loaded. This can
|
|
|
|
be useful to figure out why a template was not loaded or the wrong file
|
|
|
|
appears to be loaded.
|
|
|
|
|
|
|
|
Default: ``False``
|
2010-07-14 08:50:41 +08:00
|
|
|
|
2017-04-19 20:08:53 +08:00
|
|
|
.. py:data:: MAX_COOKIE_SIZE
|
|
|
|
|
|
|
|
Warn if cookie headers are larger than this many bytes. Defaults to
|
|
|
|
``4093``. Larger cookies may be silently ignored by browsers. Set to
|
|
|
|
``0`` to disable the warning.
|
|
|
|
|
2010-06-29 07:13:40 +08:00
|
|
|
.. versionadded:: 0.4
|
|
|
|
``LOGGER_NAME``
|
|
|
|
|
|
|
|
.. versionadded:: 0.5
|
|
|
|
``SERVER_NAME``
|
|
|
|
|
2010-07-16 03:22:11 +08:00
|
|
|
.. versionadded:: 0.6
|
|
|
|
``MAX_CONTENT_LENGTH``
|
2010-07-14 16:47:57 +08:00
|
|
|
|
2010-11-29 15:57:38 +08:00
|
|
|
.. versionadded:: 0.7
|
2011-05-28 02:10:53 +08:00
|
|
|
``PROPAGATE_EXCEPTIONS``, ``PRESERVE_CONTEXT_ON_EXCEPTION``
|
2010-11-29 15:57:38 +08:00
|
|
|
|
2011-08-05 18:35:41 +08:00
|
|
|
.. versionadded:: 0.8
|
2011-08-25 19:13:55 +08:00
|
|
|
``TRAP_BAD_REQUEST_ERRORS``, ``TRAP_HTTP_EXCEPTIONS``,
|
2011-08-30 20:36:50 +08:00
|
|
|
``APPLICATION_ROOT``, ``SESSION_COOKIE_DOMAIN``,
|
|
|
|
``SESSION_COOKIE_PATH``, ``SESSION_COOKIE_HTTPONLY``,
|
|
|
|
``SESSION_COOKIE_SECURE``
|
2011-08-05 18:35:41 +08:00
|
|
|
|
2012-04-09 22:24:43 +08:00
|
|
|
.. versionadded:: 0.9
|
|
|
|
``PREFERRED_URL_SCHEME``
|
|
|
|
|
2012-10-18 07:48:15 +08:00
|
|
|
.. versionadded:: 0.10
|
2013-06-02 02:24:03 +08:00
|
|
|
``JSON_AS_ASCII``, ``JSON_SORT_KEYS``, ``JSONIFY_PRETTYPRINT_REGULAR``
|
2012-10-18 07:48:15 +08:00
|
|
|
|
2016-05-23 20:42:42 +08:00
|
|
|
.. versionadded:: 0.11
|
2014-09-03 23:57:44 +08:00
|
|
|
``SESSION_REFRESH_EACH_REQUEST``, ``TEMPLATES_AUTO_RELOAD``,
|
|
|
|
``LOGGER_HANDLER_POLICY``, ``EXPLAIN_TEMPLATE_LOADING``
|
2013-09-30 23:40:35 +08:00
|
|
|
|
2017-07-29 05:55:52 +08:00
|
|
|
.. versionchanged:: 1.0
|
|
|
|
``LOGGER_NAME`` and ``LOGGER_HANDLER_POLICY`` were removed. See
|
2019-07-02 05:56:18 +08:00
|
|
|
:doc:`/logging` for information about configuration.
|
2017-07-29 05:55:52 +08:00
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
Added :data:`ENV` to reflect the :envvar:`FLASK_ENV` environment
|
|
|
|
variable.
|
|
|
|
|
2018-01-24 07:11:50 +08:00
|
|
|
Added :data:`SESSION_COOKIE_SAMESITE` to control the session
|
|
|
|
cookie's ``SameSite`` option.
|
|
|
|
|
2017-04-19 20:08:53 +08:00
|
|
|
Added :data:`MAX_COOKIE_SIZE` to control a warning from Werkzeug.
|
|
|
|
|
2022-06-30 12:02:44 +08:00
|
|
|
.. versionchanged:: 2.2
|
|
|
|
Removed ``PRESERVE_CONTEXT_ON_EXCEPTION``.
|
|
|
|
|
2018-01-11 07:38:52 +08:00
|
|
|
|
2019-10-11 18:52:29 +08:00
|
|
|
Configuring from Python Files
|
|
|
|
-----------------------------
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2011-08-17 13:38:34 +08:00
|
|
|
Configuration becomes more useful if you can store it in a separate file,
|
|
|
|
ideally located outside the actual application package. This makes
|
|
|
|
packaging and distributing your application possible via various package
|
2020-04-05 03:57:14 +08:00
|
|
|
handling tools (:doc:`/patterns/distribute`) and finally modifying the
|
2011-08-17 13:38:34 +08:00
|
|
|
configuration file afterwards.
|
2010-05-27 23:42:01 +08:00
|
|
|
|
|
|
|
So a common pattern is this::
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
app.config.from_object('yourapplication.default_settings')
|
|
|
|
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
|
|
|
|
|
2010-06-28 11:49:50 +08:00
|
|
|
This first loads the configuration from the
|
2010-05-27 23:42:01 +08:00
|
|
|
`yourapplication.default_settings` module and then overrides the values
|
2016-11-15 18:57:09 +08:00
|
|
|
with the contents of the file the :envvar:`YOURAPPLICATION_SETTINGS`
|
2020-10-16 05:08:37 +08:00
|
|
|
environment variable points to. This environment variable can be set
|
|
|
|
in the shell before starting the server:
|
|
|
|
|
|
|
|
.. tabs::
|
|
|
|
|
|
|
|
.. group-tab:: Bash
|
|
|
|
|
|
|
|
.. code-block:: text
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2020-10-16 05:08:37 +08:00
|
|
|
$ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
|
|
|
|
$ flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2022-01-11 20:59:08 +08:00
|
|
|
.. group-tab:: Fish
|
|
|
|
|
|
|
|
.. code-block:: text
|
|
|
|
|
|
|
|
$ set -x YOURAPPLICATION_SETTINGS /path/to/settings.cfg
|
|
|
|
$ flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
|
|
|
|
2020-10-16 05:08:37 +08:00
|
|
|
.. group-tab:: CMD
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2020-10-16 05:08:37 +08:00
|
|
|
.. code-block:: text
|
|
|
|
|
|
|
|
> set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg
|
|
|
|
> flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
|
|
|
|
|
|
|
.. group-tab:: Powershell
|
|
|
|
|
|
|
|
.. code-block:: text
|
|
|
|
|
|
|
|
> $env:YOURAPPLICATION_SETTINGS = "\path\to\settings.cfg"
|
|
|
|
> flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
2010-05-27 23:42:01 +08:00
|
|
|
|
|
|
|
The configuration files themselves are actual Python files. Only values
|
|
|
|
in uppercase are actually stored in the config object later on. So make
|
|
|
|
sure to use uppercase letters for your config keys.
|
|
|
|
|
2011-08-17 13:38:34 +08:00
|
|
|
Here is an example of a configuration file::
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2011-08-17 13:38:34 +08:00
|
|
|
# Example configuration
|
2021-10-12 21:00:50 +08:00
|
|
|
SECRET_KEY = '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2011-08-17 13:38:34 +08:00
|
|
|
Make sure to load the configuration very early on, so that extensions have
|
2010-05-27 23:42:01 +08:00
|
|
|
the ability to access the configuration when starting up. There are other
|
|
|
|
methods on the config object as well to load from individual files. For a
|
|
|
|
complete reference, read the :class:`~flask.Config` object's
|
|
|
|
documentation.
|
|
|
|
|
2019-10-11 18:52:29 +08:00
|
|
|
|
2019-10-19 00:15:00 +08:00
|
|
|
Configuring from Data Files
|
|
|
|
---------------------------
|
2019-10-11 18:52:29 +08:00
|
|
|
|
2019-10-19 00:15:00 +08:00
|
|
|
It is also possible to load configuration from a file in a format of
|
|
|
|
your choice using :meth:`~flask.Config.from_file`. For example to load
|
|
|
|
from a TOML file:
|
2019-10-11 18:52:29 +08:00
|
|
|
|
2019-10-19 00:15:00 +08:00
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
import toml
|
|
|
|
app.config.from_file("config.toml", load=toml.load)
|
|
|
|
|
|
|
|
Or from a JSON file:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
import json
|
|
|
|
app.config.from_file("config.json", load=json.load)
|
2019-10-11 18:52:29 +08:00
|
|
|
|
2019-03-09 08:41:57 +08:00
|
|
|
|
2017-06-10 01:28:54 +08:00
|
|
|
Configuring from Environment Variables
|
|
|
|
--------------------------------------
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-09 05:40:48 +08:00
|
|
|
In addition to pointing to configuration files using environment
|
|
|
|
variables, you may find it useful (or necessary) to control your
|
|
|
|
configuration values directly from the environment. Flask can be
|
|
|
|
instructed to load all environment variables starting with a specific
|
|
|
|
prefix into the config using :meth:`~flask.Config.from_prefixed_env`.
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-26 02:00:32 +08:00
|
|
|
Environment variables can be set in the shell before starting the
|
|
|
|
server:
|
2020-10-16 05:08:37 +08:00
|
|
|
|
|
|
|
.. tabs::
|
|
|
|
|
|
|
|
.. group-tab:: Bash
|
|
|
|
|
|
|
|
.. code-block:: text
|
|
|
|
|
2022-03-09 05:40:48 +08:00
|
|
|
$ export FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
|
|
|
|
$ export FLASK_MAIL_ENABLED=false
|
2020-10-16 05:08:37 +08:00
|
|
|
$ flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
|
|
|
|
2022-01-11 20:59:08 +08:00
|
|
|
.. group-tab:: Fish
|
|
|
|
|
|
|
|
.. code-block:: text
|
|
|
|
|
2022-03-09 05:40:48 +08:00
|
|
|
$ set -x FLASK_SECRET_KEY "5f352379324c22463451387a0aec5d2f"
|
|
|
|
$ set -x FLASK_MAIL_ENABLED false
|
2022-01-11 20:59:08 +08:00
|
|
|
$ flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
|
|
|
|
2020-10-16 05:08:37 +08:00
|
|
|
.. group-tab:: CMD
|
|
|
|
|
|
|
|
.. code-block:: text
|
|
|
|
|
2022-03-09 05:40:48 +08:00
|
|
|
> set FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
|
|
|
|
> set FLASK_MAIL_ENABLED=false
|
2020-10-16 05:08:37 +08:00
|
|
|
> flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2020-10-16 05:08:37 +08:00
|
|
|
.. group-tab:: Powershell
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2020-10-16 05:08:37 +08:00
|
|
|
.. code-block:: text
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-09 05:40:48 +08:00
|
|
|
> $env:FLASK_SECRET_KEY = "5f352379324c22463451387a0aec5d2f"
|
|
|
|
> $env:FLASK_MAIL_ENABLED = "false"
|
2020-10-16 05:08:37 +08:00
|
|
|
> flask run
|
|
|
|
* Running on http://127.0.0.1:5000/
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-26 02:00:32 +08:00
|
|
|
The variables can then be loaded and accessed via the config with a key
|
|
|
|
equal to the environment variable name without the prefix i.e.
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-09 05:40:48 +08:00
|
|
|
.. code-block:: python
|
2019-03-09 08:41:57 +08:00
|
|
|
|
2022-03-09 05:40:48 +08:00
|
|
|
app.config.from_prefixed_env()
|
|
|
|
app.config["SECRET_KEY"] # Is "5f352379324c22463451387a0aec5d2f"
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-26 02:00:32 +08:00
|
|
|
The prefix is ``FLASK_`` by default. This is configurable via the
|
|
|
|
``prefix`` argument of :meth:`~flask.Config.from_prefixed_env`.
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-26 02:00:32 +08:00
|
|
|
Values will be parsed to attempt to convert them to a more specific type
|
|
|
|
than strings. By default :func:`json.loads` is used, so any valid JSON
|
|
|
|
value is possible, including lists and dicts. This is configurable via
|
|
|
|
the ``loads`` argument of :meth:`~flask.Config.from_prefixed_env`.
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-26 02:00:32 +08:00
|
|
|
When adding a boolean value with the default JSON parsing, only "true"
|
|
|
|
and "false", lowercase, are valid values. Keep in mind that any
|
|
|
|
non-empty string is considered ``True`` by Python.
|
2017-06-09 22:19:08 +08:00
|
|
|
|
2022-03-26 02:00:32 +08:00
|
|
|
It is possible to set keys in nested dictionaries by separating the
|
|
|
|
keys with double underscore (``__``). Any intermediate keys that don't
|
|
|
|
exist on the parent dict will be initialized to an empty dict.
|
|
|
|
|
|
|
|
.. code-block:: text
|
|
|
|
|
|
|
|
$ export FLASK_MYAPI__credentials__username=user123
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
app.config["MYAPI"]["credentials"]["username"] # Is "user123"
|
|
|
|
|
2022-03-26 03:05:07 +08:00
|
|
|
On Windows, environment variable keys are always uppercase, therefore
|
|
|
|
the above example would end up as ``MYAPI__CREDENTIALS__USERNAME``.
|
|
|
|
|
|
|
|
For even more config loading features, including merging and
|
|
|
|
case-insensitive Windows support, try a dedicated library such as
|
|
|
|
Dynaconf_, which includes integration with Flask.
|
2022-03-26 02:00:32 +08:00
|
|
|
|
|
|
|
.. _Dynaconf: https://www.dynaconf.com/
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2019-03-09 08:41:57 +08:00
|
|
|
|
2010-05-27 23:42:01 +08:00
|
|
|
Configuration Best Practices
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
The downside with the approach mentioned earlier is that it makes testing
|
2011-08-17 13:38:34 +08:00
|
|
|
a little harder. There is no single 100% solution for this problem in
|
|
|
|
general, but there are a couple of things you can keep in mind to improve
|
|
|
|
that experience:
|
2010-05-27 23:42:01 +08:00
|
|
|
|
2014-07-11 23:23:01 +08:00
|
|
|
1. Create your application in a function and register blueprints on it.
|
2010-05-27 23:42:01 +08:00
|
|
|
That way you can create multiple instances of your application with
|
2019-05-15 04:08:00 +08:00
|
|
|
different configurations attached which makes unit testing a lot
|
2010-05-27 23:42:01 +08:00
|
|
|
easier. You can use this to pass in configuration as needed.
|
|
|
|
|
|
|
|
2. Do not write code that needs the configuration at import time. If you
|
|
|
|
limit yourself to request-only accesses to the configuration you can
|
|
|
|
reconfigure the object later on as needed.
|
2010-07-06 20:42:43 +08:00
|
|
|
|
2022-03-26 02:00:32 +08:00
|
|
|
3. Make sure to load the configuration very early on, so that
|
|
|
|
extensions can access the configuration when calling ``init_app``.
|
|
|
|
|
|
|
|
|
2016-06-03 06:40:59 +08:00
|
|
|
.. _config-dev-prod:
|
2010-07-06 20:42:43 +08:00
|
|
|
|
|
|
|
Development / Production
|
|
|
|
------------------------
|
|
|
|
|
2011-08-17 13:38:34 +08:00
|
|
|
Most applications need more than one configuration. There should be at
|
|
|
|
least separate configurations for the production server and the one used
|
|
|
|
during development. The easiest way to handle this is to use a default
|
|
|
|
configuration that is always loaded and part of the version control, and a
|
2010-07-06 20:42:43 +08:00
|
|
|
separate configuration that overrides the values as necessary as mentioned
|
|
|
|
in the example above::
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
app.config.from_object('yourapplication.default_settings')
|
|
|
|
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
|
|
|
|
|
2014-11-05 11:45:22 +08:00
|
|
|
Then you just have to add a separate :file:`config.py` file and export
|
2010-07-06 20:42:43 +08:00
|
|
|
``YOURAPPLICATION_SETTINGS=/path/to/config.py`` and you are done. However
|
|
|
|
there are alternative ways as well. For example you could use imports or
|
|
|
|
subclassing.
|
|
|
|
|
|
|
|
What is very popular in the Django world is to make the import explicit in
|
2016-04-02 05:12:25 +08:00
|
|
|
the config file by adding ``from yourapplication.default_settings
|
2010-07-06 20:42:43 +08:00
|
|
|
import *`` to the top of the file and then overriding the changes by hand.
|
|
|
|
You could also inspect an environment variable like
|
|
|
|
``YOURAPPLICATION_MODE`` and set that to `production`, `development` etc
|
2019-05-15 04:08:00 +08:00
|
|
|
and import different hard-coded files based on that.
|
2010-07-06 20:42:43 +08:00
|
|
|
|
|
|
|
An interesting pattern is also to use classes and inheritance for
|
|
|
|
configuration::
|
|
|
|
|
|
|
|
class Config(object):
|
|
|
|
TESTING = False
|
|
|
|
|
|
|
|
class ProductionConfig(Config):
|
|
|
|
DATABASE_URI = 'mysql://user@localhost/foo'
|
2012-03-14 07:34:16 +08:00
|
|
|
|
2010-07-06 20:42:43 +08:00
|
|
|
class DevelopmentConfig(Config):
|
2020-06-23 22:14:03 +08:00
|
|
|
DATABASE_URI = "sqlite:////tmp/foo.db"
|
2010-07-06 20:42:43 +08:00
|
|
|
|
2011-03-14 07:26:40 +08:00
|
|
|
class TestingConfig(Config):
|
2020-06-23 21:56:51 +08:00
|
|
|
DATABASE_URI = 'sqlite:///:memory:'
|
2010-07-06 20:42:43 +08:00
|
|
|
TESTING = True
|
|
|
|
|
|
|
|
To enable such a config you just have to call into
|
|
|
|
:meth:`~flask.Config.from_object`::
|
|
|
|
|
|
|
|
app.config.from_object('configmodule.ProductionConfig')
|
|
|
|
|
2018-07-07 04:16:05 +08:00
|
|
|
Note that :meth:`~flask.Config.from_object` does not instantiate the class
|
|
|
|
object. If you need to instantiate the class, such as to access a property,
|
|
|
|
then you must do so before calling :meth:`~flask.Config.from_object`::
|
|
|
|
|
|
|
|
from configmodule import ProductionConfig
|
|
|
|
app.config.from_object(ProductionConfig())
|
|
|
|
|
|
|
|
# Alternatively, import via string:
|
|
|
|
from werkzeug.utils import import_string
|
|
|
|
cfg = import_string('configmodule.ProductionConfig')()
|
|
|
|
app.config.from_object(cfg)
|
|
|
|
|
2019-02-24 18:40:23 +08:00
|
|
|
Instantiating the configuration object allows you to use ``@property`` in
|
2018-07-07 04:16:05 +08:00
|
|
|
your configuration classes::
|
|
|
|
|
|
|
|
class Config(object):
|
|
|
|
"""Base config, uses staging database server."""
|
|
|
|
TESTING = False
|
|
|
|
DB_SERVER = '192.168.1.56'
|
|
|
|
|
|
|
|
@property
|
2020-04-05 02:39:03 +08:00
|
|
|
def DATABASE_URI(self): # Note: all caps
|
|
|
|
return f"mysql://user@{self.DB_SERVER}/foo"
|
2018-07-07 04:16:05 +08:00
|
|
|
|
|
|
|
class ProductionConfig(Config):
|
|
|
|
"""Uses production database server."""
|
|
|
|
DB_SERVER = '192.168.19.32'
|
|
|
|
|
|
|
|
class DevelopmentConfig(Config):
|
|
|
|
DB_SERVER = 'localhost'
|
|
|
|
|
|
|
|
class TestingConfig(Config):
|
|
|
|
DB_SERVER = 'localhost'
|
|
|
|
DATABASE_URI = 'sqlite:///:memory:'
|
|
|
|
|
2010-07-06 20:42:43 +08:00
|
|
|
There are many different ways and it's up to you how you want to manage
|
2010-07-06 22:07:13 +08:00
|
|
|
your configuration files. However here a list of good recommendations:
|
2010-07-06 20:42:43 +08:00
|
|
|
|
2014-07-11 23:23:01 +08:00
|
|
|
- Keep a default configuration in version control. Either populate the
|
2010-07-06 20:42:43 +08:00
|
|
|
config with this default configuration or import it in your own
|
|
|
|
configuration files before overriding values.
|
2014-07-11 23:23:01 +08:00
|
|
|
- Use an environment variable to switch between the configurations.
|
2010-07-06 20:42:43 +08:00
|
|
|
This can be done from outside the Python interpreter and makes
|
|
|
|
development and deployment much easier because you can quickly and
|
|
|
|
easily switch between different configs without having to touch the
|
|
|
|
code at all. If you are working often on different projects you can
|
|
|
|
even create your own script for sourcing that activates a virtualenv
|
|
|
|
and exports the development configuration for you.
|
|
|
|
- Use a tool like `fabric`_ in production to push code and
|
2010-10-06 14:05:35 +08:00
|
|
|
configurations separately to the production server(s). For some
|
2011-05-28 21:11:48 +08:00
|
|
|
details about how to do that, head over to the
|
2020-04-05 03:57:14 +08:00
|
|
|
:doc:`/patterns/fabric` pattern.
|
2010-07-06 20:42:43 +08:00
|
|
|
|
2018-10-27 20:28:45 +08:00
|
|
|
.. _fabric: https://www.fabfile.org/
|
2011-08-10 19:55:57 +08:00
|
|
|
|
|
|
|
|
|
|
|
.. _instance-folders:
|
|
|
|
|
|
|
|
Instance Folders
|
|
|
|
----------------
|
|
|
|
|
|
|
|
.. versionadded:: 0.8
|
|
|
|
|
|
|
|
Flask 0.8 introduces instance folders. Flask for a long time made it
|
|
|
|
possible to refer to paths relative to the application's folder directly
|
|
|
|
(via :attr:`Flask.root_path`). This was also how many developers loaded
|
|
|
|
configurations stored next to the application. Unfortunately however this
|
|
|
|
only works well if applications are not packages in which case the root
|
|
|
|
path refers to the contents of the package.
|
|
|
|
|
|
|
|
With Flask 0.8 a new attribute was introduced:
|
|
|
|
:attr:`Flask.instance_path`. It refers to a new concept called the
|
|
|
|
“instance folder”. The instance folder is designed to not be under
|
|
|
|
version control and be deployment specific. It's the perfect place to
|
|
|
|
drop things that either change at runtime or configuration files.
|
|
|
|
|
2011-08-26 04:16:06 +08:00
|
|
|
You can either explicitly provide the path of the instance folder when
|
|
|
|
creating the Flask application or you can let Flask autodetect the
|
|
|
|
instance folder. For explicit configuration use the `instance_path`
|
|
|
|
parameter::
|
2011-08-10 19:55:57 +08:00
|
|
|
|
2011-08-10 19:57:30 +08:00
|
|
|
app = Flask(__name__, instance_path='/path/to/instance/folder')
|
|
|
|
|
2011-08-26 04:16:06 +08:00
|
|
|
Please keep in mind that this path *must* be absolute when provided.
|
|
|
|
|
|
|
|
If the `instance_path` parameter is not provided the following default
|
|
|
|
locations are used:
|
|
|
|
|
|
|
|
- Uninstalled module::
|
2011-08-10 19:57:30 +08:00
|
|
|
|
|
|
|
/myapp.py
|
|
|
|
/instance
|
|
|
|
|
2011-08-26 04:16:06 +08:00
|
|
|
- Uninstalled package::
|
|
|
|
|
2011-08-10 19:57:30 +08:00
|
|
|
/myapp
|
|
|
|
/__init__.py
|
|
|
|
/instance
|
2011-08-10 19:55:57 +08:00
|
|
|
|
2011-08-26 04:16:06 +08:00
|
|
|
- Installed module or package::
|
|
|
|
|
2020-04-04 02:58:16 +08:00
|
|
|
$PREFIX/lib/pythonX.Y/site-packages/myapp
|
2011-08-26 04:16:06 +08:00
|
|
|
$PREFIX/var/myapp-instance
|
|
|
|
|
|
|
|
``$PREFIX`` is the prefix of your Python installation. This can be
|
|
|
|
``/usr`` or the path to your virtualenv. You can print the value of
|
|
|
|
``sys.prefix`` to see what the prefix is set to.
|
2011-08-10 19:55:57 +08:00
|
|
|
|
|
|
|
Since the config object provided loading of configuration files from
|
|
|
|
relative filenames we made it possible to change the loading via filenames
|
|
|
|
to be relative to the instance path if wanted. The behavior of relative
|
|
|
|
paths in config files can be flipped between “relative to the application
|
|
|
|
root” (the default) to “relative to instance folder” via the
|
|
|
|
`instance_relative_config` switch to the application constructor::
|
|
|
|
|
|
|
|
app = Flask(__name__, instance_relative_config=True)
|
|
|
|
|
|
|
|
Here is a full example of how to configure Flask to preload the config
|
2018-09-21 21:43:23 +08:00
|
|
|
from a module and then override the config from a file in the instance
|
2011-08-10 19:55:57 +08:00
|
|
|
folder if it exists::
|
|
|
|
|
|
|
|
app = Flask(__name__, instance_relative_config=True)
|
|
|
|
app.config.from_object('yourapplication.default_settings')
|
|
|
|
app.config.from_pyfile('application.cfg', silent=True)
|
|
|
|
|
|
|
|
The path to the instance folder can be found via the
|
|
|
|
:attr:`Flask.instance_path`. Flask also provides a shortcut to open a
|
2011-08-10 20:00:57 +08:00
|
|
|
file from the instance folder with :meth:`Flask.open_instance_resource`.
|
2011-08-10 19:55:57 +08:00
|
|
|
|
|
|
|
Example usage for both::
|
|
|
|
|
2011-11-02 12:45:39 +08:00
|
|
|
filename = os.path.join(app.instance_path, 'application.cfg')
|
2011-08-10 19:55:57 +08:00
|
|
|
with open(filename) as f:
|
|
|
|
config = f.read()
|
|
|
|
|
|
|
|
# or via open_instance_resource:
|
|
|
|
with app.open_instance_resource('application.cfg') as f:
|
|
|
|
config = f.read()
|