Bokeh embedded server using Flask running on https://

Hi, I’m just getting into Bokeh and Flask and have a beginner problem:

In order to use Chrome’s getUserMedia to stream a user’s microphone, it is a requirement for the webpage to run in https://. I’ve done that with Flask but can’t get the bokeh plot rendering. I can get it running just fine with http:.

Is it a problem of passing on the certificate to the bokeh server that’s served using server_document and Server? If so, how do I do this? I’m not using nginx since this is development for now.

I’ve tried replacing the script = server_document("http://localhost:5006/bkapp") with https but it has the same effect.

Any help would be appreicated.

from flask import Flask, Response,render_template, jsonify, request
import pyaudio, time, queue
from deep_speaker_mic import mic_stream
from bokeh.embed import server_document, components
from bokeh.client import push_session
from bokeh.plotting import figure
from bokeh.models.sources import AjaxDataSource, ColumnDataSource
from bokeh.server.server import Server
from threading import Thread
from tornado.ioloop import IOLoop
from bokeh.themes import Theme
from OpenSSL import SSL

app = Flask(__name__)

@app.route('/embed', methods=['GET'])

def make_spectogram_plot():
    script = server_document("https://localhost:5006/bkapp")
    return render_template("embed.html", script=script, template="Flask")

def audio():
    mic = mic_stream()
    return mic.main()

def bkapp(doc):
    source = ColumnDataSource(dict(x=[],y=[])) 
    plot = figure(plot_height=400, plot_width=1800, title="Spectogram",
                x_range=[0,1500], y_range=[-1, 1])
    plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)
    def update():
        queue_spec = queue_1
        global y
        DOWNSAMPLE = 10
        while True:
                data = queue_spec.get_nowait()
                data = data[::DOWNSAMPLE]
            except queue.Empty:
        shift = len(data)
        y = np.roll(y, -shift, axis = 0)
        y[-shift:] = data
        x = np.linspace(1,1500,1500)

        new_data = dict(x = x, y = y), 1500)

    doc.add_periodic_callback(update, 33)
    doc.theme = Theme(filename="theme.yaml")

def bk_worker():
    # Can't pass num_procs > 1 in this configuration. If you need to run multiple
    # processes, see e.g.
    server = Server({'/bkapp': bkapp}, io_loop=IOLoop(), allow_websocket_origin=[""])

input_stream, (queue_1, queue_2) = audio()

if __name__ == "__main__": = 8000) = 8000, ssl_context=('cert.pem','key.pem'))


embed.html is
<!doctype html>

<html lang="en">
  <meta charset="utf-8">
  <title>Embedding a Bokeh Server With {{ framework }}</title>

  <script type="text/javascript" src="//"></script>
  <script type="text/javascript" src="//"></script>


This Bokeh app below served by a Bokeh server that has been embedded
in another web app framework. For more information see the section
<a  target="_blank" href="">Embedding Bokeh Server as a Library</a>
in the User's Guide.
  {{ script|safe }}

the input_stream is just a mic stream using the server’s (my laptop) for generating a test stream

So far my research has lead me to use:
server = Server({'/bkapp': bkapp}, io_loop=IOLoop(), allow_websocket_origin=[""], ssl_certfile='cert.pem', ssl_keyfile='key.pem')

I can visit the page but still the plot does not show up.
However to check, I can see the plot on:


I originally had problems running a bokeh server securely using Gunicorn+Flask and an HTTPS address. In my case, the issue came down to needing to generate a Subject Alternative Name (SAN) certificate when I made a self-signed certificate via openssl for testing.

If you’re using a self-signed certificate, that might be what you’re running into as well. See this topic on bokeh discourse towards the end of the discussion for a link to more info.