BACKGROUND: I have an application that embeds a bokeh server (actually a panel server in case this detail becomes important) in a Flask app run via gunicorn.
Everything works as expected when serving the application on a self-managed Linux or OSX system. Recent steps have demonstrated the feasibility of deploying this to Heroku by reorganizing the implementation to run on two dynos that respectively run the Flask app and the bokeh/panel server that Flask embeds. See Bokeh Discourse Topic 6199.
ISSUE: My actual application implements a custom Div model using TypeScript, the purpose of which is to isolate the HTML div from triggering a re-layout when a user interacts with the app via sliders and other widgets. See Bokeh Discourse Topic 5119.
This custom model generates a model-not-found error in the Flask app when the code is reorganized into two separate applications. The Flask app is now getting the server document via Bokeh client pull_session()
.
A stack trace of the error follows. NB: I tried two additional things to remedy the problem without success (1) including the custom div model code in the Flask app directory and importing it; and (2) attempting to create a dummy IsoDiv()
model in the Flask app in the hopes this would make the model able to be found/recognized.
The second modification resulted in a different error related to panel.markup.HTML, which I assume is part of the scaffolding for div.
Versions: Bokeh 2.2.0, Panel 0.9.7, Python 3.8.3
ERROR:main:Exception on /demo [GET]
Traceback (most recent call last):
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/flask_login/utils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "/Users/x/Desktop/my_flask/main.py", line 246, in demo
with pull_session(url=MY_PANEL_SERVER_URL, arguments=arguments) as session:
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/client/session.py", line 120, in pull_session
session.pull()
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/client/session.py", line 387, in pull
self._connection.pull_doc(doc)
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/client/connection.py", line 199, in pull_doc
reply.push_to_document(document)
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/protocol/messages/pull_doc_reply.py", line 83, in push_to_document
doc.replace_with_json(self.content['doc'])
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/document/document.py", line 832, in replace_with_json
replacement = self.from_json(json)
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/document/document.py", line 555, in from_json
references = instantiate_references_json(references_json, {})
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/document/util.py", line 112, in instantiate_references_json
cls = get_class(obj_type)
File "/Users/x/opt/anaconda3/envs/heroku/lib/python3.8/site-packages/bokeh/model.py", line 147, in get_class
raise KeyError("View model name '%s' not found" % view_model_name)
KeyError: "View model name 'IsoDiv' not found"