diff --git a/dash/CHANGELOG.md b/dash/CHANGELOG.md
index ef8b9027a4..3e6f17d745 100644
--- a/dash/CHANGELOG.md
+++ b/dash/CHANGELOG.md
@@ -1,5 +1,13 @@
## Unreleased
### Changed
+- 💥 [#761](https://github.com/plotly/dash/pull/761) Several breaking changes to the `dash.Dash` API:
+ - Removed two obsolete constructor kwargs: `static_folder` and `components_cache_max_age`
+ - Removed the misspelled `supress_callback_exceptions` fallback
+ - Removed the unused `resources.config.infer_from_layout`
+ - Revamped `app.config`: ALL constructor args are now stored in `config`, with three exceptions: `server`, `index_string`, and `plugins`. None of these are stored in any other instance attributes anymore.
+ - Changed `hot_reload_interval` from msec to seconds, for consistency with `hot_reload_watch_interval`
+ - When called from `enable_dev_tools`, `debug=True` by default. It's still `False` by default from `run_server`.
+
- [#753](https://github.com/plotly/dash/pull/753) `Component` no longer inherits `MutableMapping`, so `values`, `keys`, and more are no longer methods. This fixed an issue reported in [dcc](https://github.com/plotly/dash-core-components/issues/440) where components with certain prop names defined but not provided would cause a failure to render. During component generation we now disallow all props with leading underscores or matching a few remaining reserved words: `UNDEFINED`, `REQUIRED`, `to_plotly_json`, `available_properties`, and `available_wildcard_properties`.
- [#739](https://github.com/plotly/dash/pull/739) Allow the Flask app to be provided to Dash after object initialization. This allows users to define Dash layouts etc when using the app factory pattern, or any other pattern that inhibits access to the app object. This broadly complies with the flask extension API, allowing Dash to be considered as a Flask extension where it needs to be.
diff --git a/dash/_utils.py b/dash/_utils.py
index 740f946d2a..dcd83b1c26 100644
--- a/dash/_utils.py
+++ b/dash/_utils.py
@@ -75,8 +75,28 @@ def __getattr__(self, key):
try:
return self[key]
except KeyError:
- # to conform with __getattr__ spec
- raise AttributeError(key)
+ pass
+ # to conform with __getattr__ spec
+ # but get out of the except block so it doesn't look like a nested err
+ raise AttributeError(key)
+
+ def set_read_only(self, names, msg='Attribute is read-only'):
+ object.__setattr__(self, '_read_only', names)
+ object.__setattr__(self, '_read_only_msg', msg)
+
+ def finalize(self, msg='Object is final: No new keys may be added.'):
+ """Prevent any new keys being set"""
+ object.__setattr__(self, '_final', msg)
+
+ def __setitem__(self, key, val):
+ if key in self.__dict__.get('_read_only', []):
+ raise AttributeError(self._read_only_msg, key)
+
+ final_msg = self.__dict__.get('_final')
+ if final_msg and key not in self:
+ raise AttributeError(final_msg, key)
+
+ return super(AttributeDict, self).__setitem__(key, val)
# pylint: disable=inconsistent-return-statements
def first(self, *names):
diff --git a/dash/dash.py b/dash/dash.py
index 292d8f207b..e48dbe9c39 100644
--- a/dash/dash.py
+++ b/dash/dash.py
@@ -9,7 +9,6 @@
import json
import pkgutil
import threading
-import warnings
import re
import logging
import pprint
@@ -36,6 +35,7 @@
from ._utils import get_asset_path as _get_asset_path
from ._utils import create_callback_id as _create_callback_id
from ._configs import (get_combined_config, pathname_configs)
+from .version import __version__
_default_index = '''
@@ -86,106 +86,223 @@ class _NoUpdate(object):
# pylint: disable=too-many-instance-attributes
# pylint: disable=too-many-arguments, too-many-locals
class Dash(object):
+ """
+ Dash is a framework for building analytical web applications.
+ No JavaScript required.
+
+ If a parameter can be set by an environment variable, that is listed as:
+ env: ``DASH_****``
+ Values provided here take precedence over environment variables.
+
+ :param name: The name Flask should use for your app. Even if you provide
+ your own ``server``, ``name`` will be used to help find assets.
+ Typically ``__name__`` (the magic global var, not a string) is the
+ best value to use. Default ``'__main__'``, env: ``DASH_APP_NAME``
+ :type name: string
+
+ :param server: Sets the Flask server for your app. There are three options:
+ ``True`` (default): Dash will create a new server
+ ``False``: The server will be added later via ``app.init_app(server)``
+ where ``server`` is a ``flask.Flask`` instance.
+ ``flask.Flask``: use this pre-existing Flask server.
+ :type server: boolean or flask.Flask
+
+ :param assets_folder: a path, relative to the current working directory,
+ for extra files to be used in the browser. Default ``'assets'``.
+ All .js and .css files will be loaded immediately unless excluded by
+ ``assets_ignore``, and other files such as images will be served if
+ requested.
+ :type assets_folder: string
+
+ :param assets_url_path: The local urls for assets will be:
+ ``requests_pathname_prefix + assets_url_path + '/' + asset_path``
+ where ``asset_path`` is the path to a file inside ``assets_folder``.
+ Default ``'assets'``.
+ :type asset_url_path: string
+
+ :param assets_ignore: A regex, as a string to pass to ``re.compile``, for
+ assets to omit from immediate loading. Ignored files will still be
+ served if specifically requested. You cannot use this to prevent access
+ to sensitive files.
+ :type assets_ignore: string
+
+ :param assets_external_path: an absolute URL from which to load assets.
+ Use with ``serve_locally=False``. Dash can still find js and css to
+ automatically load if you also keep local copies in your assets
+ folder that Dash can index, but external serving can improve
+ performance and reduce load on the Dash server.
+ env: ``DASH_ASSETS_EXTERNAL_PATH``
+ :type assets_external_path: string
+
+ :param include_assets_files: Default ``True``, set to ``False`` to prevent
+ immediate loading of any assets. Assets will still be served if
+ specifically requested. You cannot use this to prevent access
+ to sensitive files. env: ``DASH_INCLUDE_ASSETS_FILES``
+ :type include_assets_files: boolean
+
+ :param url_base_pathname: A local URL prefix to use app-wide.
+ Default ``'/'``. Both `requests_pathname_prefix` and
+ `routes_pathname_prefix` default to `url_base_pathname`.
+ env: ``DASH_URL_BASE_PATHNAME``
+ :type url_base_pathname: string
+
+ :param requests_pathname_prefix: A local URL prefix for file requests.
+ Defaults to `url_base_pathname`, and must end with
+ `routes_pathname_prefix`. env: ``DASH_REQUESTS_PATHNAME_PREFIX``
+ :type requests_pathname_prefix: string
+
+ :param routes_pathname_prefix: A local URL prefix for JSON requests.
+ Defaults to ``url_base_pathname``, and must start and end
+ with ``'/'``. env: ``DASH_ROUTES_PATHNAME_PREFIX``
+ :type routes_pathname_prefix: string
+
+ :param serve_locally: If ``True`` (default), assets and dependencies
+ (Dash and Component js and css) will be served from local URLs.
+ If ``False`` we will use CDN links where available.
+ :type serve_locally: boolean
+
+ :param compress: Use gzip to compress files and data served by Flask.
+ Default ``True``
+ :type compress: boolean
+
+ :param meta_tags: html tags to be added to the index page.
+ Each dict should have the attributes and values for one tag, eg:
+ ``{'name': 'description', 'content': 'My App'}``
+ :type meta_tags: list of dicts
+
+ :param index_string: Override the standard Dash index page.
+ Must contain the correct insertion markers to interpolate various
+ content into it depending on the app config and components used.
+ See https://dash.plot.ly/external-resources for details.
+ :type index_string: string
+
+ :param external_scripts: Additional JS files to load with the page.
+ Each entry can be a string (the URL) or a dict with ``src`` (the URL)
+ and optionally other ``
+
+