Skip to content

Commit

Permalink
Add separate init_app function for providing the flask app
Browse files Browse the repository at this point in the history
  • Loading branch information
multimeric committed May 23, 2019
1 parent f958d9e commit 4ad5c06
Showing 1 changed file with 74 additions and 57 deletions.
131 changes: 74 additions & 57 deletions dash/dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,13 @@ def __init__(
components_cache_max_age=None,
show_undo_redo=False,
plugins=None,
defer_app=False,
**kwargs):

# Store some flask-related parameters for use in init_app()
self.compress = compress
self.name = name

# pylint-disable: too-many-instance-attributes
if 'csrf_protect' in kwargs:
warnings.warn('''
Expand Down Expand Up @@ -154,22 +159,6 @@ def __init__(
'show_undo_redo': show_undo_redo
})

assets_blueprint_name = '{}{}'.format(
self.config.routes_pathname_prefix.replace('/', '_'),
'dash_assets'
)

self.server.register_blueprint(
flask.Blueprint(
assets_blueprint_name, name,
static_folder=self._assets_folder,
static_url_path='{}{}'.format(
self.config.routes_pathname_prefix,
assets_url_path.lstrip('/')
)
)
)

# list of dependencies
self.callback_map = {}

Expand All @@ -181,15 +170,6 @@ def __init__(
# default renderer string
self.renderer = 'var renderer = new DashRenderer();'

if compress:
# gzip
Compress(self.server)

@self.server.errorhandler(exceptions.PreventUpdate)
def _handle_error(_):
"""Handle a halted callback and return an empty 204 response"""
return '', 204

# static files from the packages
self.css = Css()
self.scripts = Scripts()
Expand Down Expand Up @@ -236,8 +216,6 @@ def _handle_error(_):
'{}_favicon.ico'.format(prefix),
self._serve_default_favicon)

self.server.before_first_request(self._setup_server)

self._layout = None
self._cached_layout = None
self._dev_tools = _AttributeDict({
Expand All @@ -250,10 +228,6 @@ def _handle_error(_):
'props_check': False,
})

# add a handler for components suites errors to return 404
self.server.errorhandler(exceptions.InvalidResourceError)(
self._invalid_resources_handler)

self._assets_files = []

# hot reload
Expand All @@ -270,6 +244,49 @@ def _handle_error(_):
for plugin in plugins:
plugin.plug(self)

if not defer_app:
self.init_app()

def init_app(self, app=None):
"""
Initialize the parts of Dash that require a flask app
"""

if app is not None:
self.server = app

assets_blueprint_name = '{}{}'.format(
self.config.routes_pathname_prefix.replace('/', '_'),
'dash_assets'
)

self.server.register_blueprint(
flask.Blueprint(
assets_blueprint_name,
self.name,
static_folder=self._assets_folder,
static_url_path='{}{}'.format(
self.config.routes_pathname_prefix,
self._assets_url_path.lstrip('/')
)
)
)

if self.compress:
# gzip
Compress(self.server)

@self.server.errorhandler(exceptions.PreventUpdate)
def _handle_error(_):
"""Handle a halted callback and return an empty 204 response"""
return '', 204

self.server.before_first_request(self._setup_server)

# add a handler for components suites errors to return 404
self.server.errorhandler(exceptions.InvalidResourceError)(
self._invalid_resources_handler)

def _add_url(self, name, view_func, methods=('GET',)):
self.server.add_url_rule(
name,
Expand Down Expand Up @@ -404,7 +421,7 @@ def _relative_url_path(relative_package_path='', namespace=''):
paths = [paths] if isinstance(paths, str) else paths

for rel_path in paths:
self.registered_paths[resource['namespace']]\
self.registered_paths[resource['namespace']] \
.add(rel_path)

if not is_dynamic_resource:
Expand Down Expand Up @@ -432,7 +449,7 @@ def _relative_url_path(relative_package_path='', namespace=''):

def _generate_css_dist_html(self):
links = self._external_stylesheets + \
self._collect_and_register_resources(self.css.get_all_css())
self._collect_and_register_resources(self.css.get_all_css())

return '\n'.join([
_format_tag('link', link, opened=True)
Expand All @@ -454,12 +471,12 @@ def _generate_scripts_html(self):
dash_renderer._js_dist_dependencies,
dev_bundles=self._dev_tools.serve_dev_bundles
)) + self._external_scripts + self._collect_and_register_resources(
self.scripts.get_all_scripts(
dev_bundles=self._dev_tools.serve_dev_bundles) +
self.scripts._resources._filter_resources(
dash_renderer._js_dist,
dev_bundles=self._dev_tools.serve_dev_bundles
))
self.scripts.get_all_scripts(
dev_bundles=self._dev_tools.serve_dev_bundles) +
self.scripts._resources._filter_resources(
dash_renderer._js_dist,
dev_bundles=self._dev_tools.serve_dev_bundles
))

return '\n'.join([
_format_tag('script', src)
Expand Down Expand Up @@ -509,14 +526,14 @@ def serve_component_suites(self, package_name, path_in_package_dist):
'Error loading dependency.\n'
'"{}" is not a registered library.\n'
'Registered libraries are: {}'
.format(package_name, list(self.registered_paths.keys())))
.format(package_name, list(self.registered_paths.keys())))

if path_in_package_dist not in self.registered_paths[package_name]:
raise exceptions.DependencyException(
'"{}" is registered but the path requested is not valid.\n'
'The path requested: "{}"\n'
'List of registered paths: {}'
.format(
.format(
package_name,
path_in_package_dist,
self.registered_paths
Expand Down Expand Up @@ -775,7 +792,7 @@ def _validate_callback(self, output, inputs, state):
arg.component_property,
arg.component_id,
component.available_properties).replace(
' ', ''))
' ', ''))

if hasattr(arg, 'component_event'):
raise exceptions.NonExistentEventException('''
Expand Down Expand Up @@ -871,19 +888,19 @@ def _raise_invalid(bad_val, outer_val, bad_type, path, index=None,
or is in the top level of the returned list,'''
),
location=(
"\n" +
("[{:d}] {:s} {:s}".format(index, outer_type, outer_id)
if index is not None
else ('[*] ' + outer_type + ' ' + outer_id))
+ "\n" + path + "\n"
"\n" +
("[{:d}] {:s} {:s}".format(index, outer_type, outer_id)
if index is not None
else ('[*] ' + outer_type + ' ' + outer_id))
+ "\n" + path + "\n"
) if not toplevel else '',
bad_val=bad_val).replace(' ', ''))

def _value_is_valid(val):
return (
# pylint: disable=unused-variable
any([isinstance(val, x) for x in valid]) or
type(val).__name__ == 'unicode'
any([isinstance(val, x) for x in valid]) or
type(val).__name__ == 'unicode'
)

def _validate_value(val, index=None):
Expand Down Expand Up @@ -1140,17 +1157,17 @@ def dispatch(self):

for component_registration in self.callback_map[output]['inputs']:
args.append([
c.get('value', None) for c in inputs if
c['property'] == component_registration['property'] and
c['id'] == component_registration['id']
][0])
c.get('value', None) for c in inputs if
c['property'] == component_registration['property'] and
c['id'] == component_registration['id']
][0])

for component_registration in self.callback_map[output]['state']:
args.append([
c.get('value', None) for c in state if
c['property'] == component_registration['property'] and
c['id'] == component_registration['id']
][0])
c.get('value', None) for c in state if
c['property'] == component_registration['property'] and
c['id'] == component_registration['id']
][0])

response.set_data(self.callback_map[output]['callback'](*args))
return response
Expand Down

0 comments on commit 4ad5c06

Please sign in to comment.