My application is launched from Python. The user is presented with a browser interface which they can interact with, update the display with images fetched from Python, and finally, return results to Python and continue with Python scripting.
With Bokeh 2.4.3, I had custom models which I precompiled into a minified JS file using bokeh build. I then loaded this minified file after the Bokeh <script> lines in the HTML file <head> section. An example of one of these is found here. With Bokeh 3.1.1, it seems as though the JavaScript implementation details are expected in a namespace modeled on the Python package hierarchy because with 3.1.1 I get an error in the console:
Uncaught (in promise) Error: could not resolve type 'casagui.bokeh.sources._image_data_source.ImageDataSource', which could be due to a widget or a custom model not being registered before first usage
at p.error (bokeh-3.1.1.min.js:211:4951)
at p._resolve_type (bokeh-3.1.1.min.js:211:5059)
at p._decode_object_ref (bokeh-3.1.1.min.js:211:4782)
at p._decode (bokeh-3.1.1.min.js:211:1779)
at bokeh-3.1.1.min.js:211:2711
at f (bokeh-3.1.1.min.js:178:450)
at p._decode_map (bokeh-3.1.1.min.js:211:2640)
at p._decode (bokeh-3.1.1.min.js:211:1379)
at p._decode_plain_object (bokeh-3.1.1.min.js:211:2340)
at p._decode (bokeh-3.1.1.min.js:211:1066)
I export these custom models in the index.ts for the bokeh build. How can I force bokeh build to export the implementation for the custom models in a way that is compatible with the namespace expected when the generated HTML file is loaded into a browser.
I assume this is something I’ve done wrong in my initial approach, but everything I’ve tried has not worked. I need to update to Bokeh to get access to newer features.
Hi, There were enormous behind-the-scenes changes on the BokehJS side for version 3.0 so I want to be up front that it’s likely any custom extension code for 2.x will require a substantial re-write for any 3.x version. It’s possible the issue is somehow just with bokeh build and page setup, but more likely it’s with the extension code itself (or both). However, it’s not really possible to speculate about any actual details with so little information. Here are some resources that may help, or at least help to focus the question on specifics:
But first things first: does the extension code work without being pre-compiled? If not, I’d recommend backing up and going through some of the simple examples above successfully in order to be able to compare and contrast to your current code. It’s definitely important to get the code working not-precompiled as a first step, to tease different concerns apart.
Once the code itself is working uncompiled, then it can be possible to address any issues with (or with using) bokeh build. Pre-compiled models is a very arcane corner of Bokeh, I am only aware of a handful of users. So I would actually suggest that any questions about that (or about porting the old code if there are issues there) to a GitHub development discussion, since the folks who can offer the most help are more likely to see a discussion there, than here.
As always, the #1 thing you can do to help other help you efficiently is to pare your problem down to a complete Minimal Reproducible Example so that they can test things out directly.
Lastly, incidentally, the latest version is 3.2.2 and 3.3 will be out in the next few months. If you have to make a big leap, I’d advise you make the biggest leap possible at one time.
I just wanted to follow up before replies were blocked. Thanks @Bryan for the pointers. The main issues I ran into in converting from Bokeh 2 to Bokeh 3 ended up being:
Previously some properties of derived models were initialized before the derived class constructor was called, now all (most?) initialization involving properties must be done in the initialize member function
All typescript files found in the Python source tree of the package are compiled into the loaded display. Previously it was only the files that were referenced from Python.
The typescript which goes along with a derived model is expected to be in a model specific namespace. When the model’s typescript is compiled separately, this must be indicated by setting the __module__ member (as seen here)