Issue: jinja2.exceptions.UndefinedError: 'embed' is undefined

I have a functioning Bokeh simulation working on a Bokeh server.

I am trying to embed it into a webpage. I have my files set up how the Bokeh tutorial recommends (currently nothing in the app_hooks.py or request_handler.py files). I am following the advice on this page about Bokeh templating: Embedding Bokeh content — Bokeh 2.4.2 Documentation

If I try to embed my script into anything (ie extend from an HTML file other than base), then insert blocks with the right reference into the corresponding webpage, I get the server error

jinja2.exceptions.UndefinedError: ‘embed’ is undefined

I assume I am missing something critical about how Bokeh interacts with webpages. Do I need to include Bokeh function definitions for embed somewhere in my files? Does anyone have advice?

embed() is a macro defined in bokeh/core/_templates/macros.html, and should be made available automatically. Most likely you are using outdated version of bokeh or jinja, or maybe you are doing something non-standard that prevents this macro from being loaded.

1 Like

I made sure (using pip) that jinja2 and bokeh are up to date.

Do I need to do something actively to include (or remove) the bokeh macros? I am starting my server with the command “bokeh serve --show [projectname]”

Also, in my template file, index.html, I am replacing {% extends base %} with {% extends “webpage.html” %}, where webpage.html is in the templates folder alongside index.html

Essentially, when I remove {% extends base%} from the top of my index.html, the embed function stops working.

The “extends base” is what adds the macro.

1 Like

Ok, so how can I embed an app into an existing webpage without changing the extends parameter? My understanding on Jinja2 is that the aforementioned is necessary to insert block content, like an embedded plot, into a webpage.

That template is for use when the Boker server itself is serving all the content. If you want to embed and entire Bokeh application in some other web page (this was not evident from your question) then that is described in the Embedding Bokeh Content—Bokeh Applications section of the documentation. If you are wanting to embed individual components of a Bokeh app separately into an external web page, than I am not actually sure if that is possible. (cc @mateusz @Philipp_Rudiger) If it is possible then AFAIK it would be by pulling a session explicitly in your external web app and then by passing a specific model parameter to server_session but this is not a thoroughly developed usage scenario (you are walking on fresh ground).

1 Like

Cool, so I have to essentially pass data between BokehJS on a webpage and the Python script running on the Bokeh server.

I definitely saw tutorials for this, but I think the tutorials that showed updating Bokeh content directly to html via the base made me think there was a simpler, more direct method. Thank you for clearing that up.

I am not sure what you mean in the latter part (I’m new to web dev), but my ultimate goal is to link several Bokeh simulations (auto-updating plots with sliders that change parameters) to a single website, which I would assume require running a Bokeh server separately for each hosted app.

@JordanK10 Let’s say you have a Bokeh app that has a column of sliders next to two plots. If you want to embed this entire set of objects (in their one overall Bokeh layout) all at once into some external page, you can most-simply use server_document to do that. If you multiple apps, you can embed them each individually using multiple calls to server_document (one for each app URL). The entire apps can go wherever you want in the embedding page. If that’s what you want then I think things are fine for your use case.

Going back to the example: a column of sliders next to two plots. I f what you want is to embed the sliders from one app in one place on an external page, and embed the plots in different places on that same page from the same app session, (i.e. you want to “throw away” the top-level Bokeh layout to embed sub-components of the app individually) then that is the use-case that is not certain.

It’s not really clear which scenario you are after.

1 Like

To be clear: I am building a website that will host several python simulation visualization. Each individual simulation has an arbitrary number of plots and interactive tools, the placement of which I am not trying to customize until potentially later. So as of right now, I am not concerned with embedding each plot component separately.

Each simulation will be on separate pages, and each simulation has a separate main.py that will be operating individually. For example, on one page there will be a simulation of projectile motion, being fed from one python script, and on another page a simulation of fluid motion being fed from another python script. I would naively assume that since each of these simulations would require different interactions from the user and ruin different calculations under the hood, it would make sense to separate the Bokeh servers entirely.

Thank you for your help by the way!

OK great, that sounds like you should be covered by using server_document for each separate app URL. (Or server_session if you want to do any pre-render customizations, but still embed the entire document at once.)

1 Like

Is running the webpage on a Flask server necessary to serve the Bokeh JSON instructions? Your json_item.py example suggests it is, but I just wanna be certain.

In this case, I would run a standalone server that is just the website, then a Bokeh server for each simulation.

1 Like

Flask is only mentioned as a common example. Embedding JSON works on any static HTML page independent of however it is served.

But to be completely clear, json_item is not embedding a Bokeh server application. It is embedding static Bokeh content, that is has no connection to a Bokeh server. If you are trying to ended Bokeh server applications then there are only the two APIs I mentioned above (which also do not depend on our care about Flask specifically).

2 Likes