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.
Code:
app.py
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",
tools="crosshair,pan,reset,save,wheel_zoom",
x_range=[0,1500], y_range=[-1, 1])
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)
input_stream.start()
def update():
queue_spec = queue_1
global y
DOWNSAMPLE = 10
while True:
try:
data = queue_spec.get_nowait()
data = data[::DOWNSAMPLE]
break
except queue.Empty:
continue
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)
source.stream(new_data, 1500)
doc.add_root(plot)
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. flask_gunicorn_embed.py
server = Server({'/bkapp': bkapp}, io_loop=IOLoop(), allow_websocket_origin=["127.0.0.1:8000"])
server.start()
server.io_loop.start()
Thread(target=bk_worker).start()
input_stream, (queue_1, queue_2) = audio()
y=np.zeros((1500,))
if __name__ == "__main__":
#app.run(port = 8000)
app.run(port = 8000, ssl_context=('cert.pem','key.pem'))
and
embed.html is
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Embedding a Bokeh Server With {{ framework }}</title>
<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
</head>
<body>
<div>
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="https://docs.bokeh.org/en/latest/docs/user_guide/server.html#embedding-bokeh-server-as-a-library">Embedding Bokeh Server as a Library</a>
in the User's Guide.
</div>
{{ script|safe }}
</body>
</html>
the input_stream is just a mic stream using the server’s (my laptop) for generating a test stream