88
99from plotly .utils import PlotlyJSONEncoder
1010
11- from .app_name import app_name
11+ from .app_name import app_name , main_view_label
1212
1313uid_counter = 0
1414
1515usable_apps = {}
16- app_instances = {}
1716nd_apps = {}
1817
18+ def add_usable_app (name , app ):
19+ global usable_apps
20+ usable_apps [name ] = app
21+
22+ def add_instance (id , instance ):
23+ global nd_apps
24+ nd_apps [id ] = instance
25+
1926def get_app_by_name (name ):
2027 '''
2128 Locate a registered dash app by name, and return a DelayedDash instance encapsulating the app.
@@ -28,6 +35,9 @@ def get_app_instance_by_id(id):
2835 '''
2936 return nd_apps .get (id ,None )
3037
38+ def clear_app_instance (id ):
39+ del nd_apps [id ]
40+
3141def get_or_form_app (id , name , ** kwargs ):
3242 '''
3343 Locate an instance of a dash app by identifier, loading or creating a new instance if needed
@@ -60,15 +70,17 @@ def __init__(self, name=None, **kwargs):
6070 self .css = Holder ()
6171 self .scripts = Holder ()
6272
63- global usable_apps
64- usable_apps [ self . _uid ] = self
73+ add_usable_app ( self . _uid ,
74+ self )
6575
6676 self ._expanded_callbacks = False
6777
68- def form_dash_instance (self ):
78+ def form_dash_instance (self , replacements = None , specific_identifier = None ):
6979 rd = NotDash (name_root = self ._uid ,
70- app_pathname = "%s:main" % app_name ,
71- expanded_callbacks = self ._expanded_callbacks )
80+ app_pathname = "%s:%s" % (app_name , main_view_label ),
81+ expanded_callbacks = self ._expanded_callbacks ,
82+ replacements = replacements ,
83+ specific_identifier = specific_identifier )
7284 rd .layout = self .layout
7385
7486 for cb , func in self ._callback_sets :
@@ -112,17 +124,14 @@ def run(self,*args,**kwargs):
112124 pass
113125
114126class NotDash (Dash ):
115- def __init__ (self , name_root , app_pathname = None , replacements = None , ** kwargs ):
127+ def __init__ (self , name_root , app_pathname = None , replacements = None , specific_identifier = None , expanded_callbacks = False , ** kwargs ):
116128
117- global app_instances
118- current_instances = app_instances .get (name_root ,None )
119-
120- if current_instances is not None :
121- self ._uid = "%s-%i" % (name_root ,len (current_instances )+ 1 )
122- current_instances .append (self )
129+ if specific_identifier is not None :
130+ self ._uid = specific_identifier
123131 else :
124132 self ._uid = name_root
125- app_instances [name_root ] = [self ,]
133+
134+ add_instance (self ._uid , self )
126135
127136 self ._flask_app = Flask (self ._uid )
128137 self ._notflask = NotFlask ()
@@ -132,11 +141,9 @@ def __init__(self, name_root, app_pathname=None, replacements = None, **kwargs):
132141 kwargs ['server' ] = self ._notflask
133142
134143 super (NotDash , self ).__init__ (** kwargs )
135- global nd_apps
136- nd_apps [self ._uid ] = self
137144
138145 self ._adjust_id = False
139- self ._dash_dispatch = not kwargs . get ( ' expanded_callbacks' , False )
146+ self ._dash_dispatch = not expanded_callbacks
140147 if replacements :
141148 self ._replacements = replacements
142149 else :
@@ -164,6 +171,8 @@ def augment_initial_layout(self, base_response):
164171 content_type = base_response .mimetype )
165172
166173 def walk_tree_and_replace (self , data ):
174+ # Walk the tree. Rely on json decoding to insert instances of dict and list
175+ # ie we use a dna test for anatine, rather than our eyes and ears...
167176 if isinstance (data ,dict ):
168177 response = {}
169178 replacements = {}
0 commit comments