Source code for spade_bokeh.spade_bokeh

# -*- coding: utf-8 -*-

import asyncio
from threading import Thread

from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop

from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.server.server import BaseServer
from bokeh.server.tornado import BokehTornado
from bokeh.server.util import bind_sockets
from bokeh.embed import server_document


[docs]class BokekServer(object): def __init__(self, agent): self.hostname = None self.port = None self.agent = agent self.thread = Thread(target=self.bokeh_worker) self.server = None self.is_running = False self.apps = {}
[docs] def start(self, hostname="localhost", port=5006): """ Starts the bokeh server. Args: hostname (str): hostname of the server. Must be the same where the agent is running. Defaults to "localhost" port (int): port of the server. Defaults to 5006. """ self.hostname = hostname self.port = port self.thread.start() self.is_running = True
[docs] def stop(self): """ Stops the Bokeh server. """ if self.server: self.server.stop() self.is_running = False
[docs] def bokeh_worker(self): asyncio.set_event_loop(asyncio.new_event_loop()) sockets, port = bind_sockets(self.hostname, self.port) extra_websocket_origins = ["{}:{}".format(self.hostname, self.port), "{}:{}".format(self.hostname, self.agent.web.port)] bokeh_tornado = BokehTornado(self.apps, extra_websocket_origins=extra_websocket_origins) bokeh_http = HTTPServer(bokeh_tornado) bokeh_http.add_sockets(sockets) self.server = BaseServer(IOLoop.current(), bokeh_tornado, bokeh_http) self.server.start() self.server.io_loop.start()
[docs] def get_plot_script(self, path): """ Returns the necessary javascript to render a plot Args: path (str): the path with which the plot was registered in the server. Returns: A string with the javascript code to render the plot. """ return server_document("http://{hostname}:{port}{path}".format(hostname=self.hostname, port=self.port, path=path))
[docs] def add_plot(self, path, func): """ Registers a new plot in the bokeh server. Args: path: path where the plot will respond to queries func: the function that renders the plot. """ self.apps[path] = Application(FunctionHandler(func))
[docs]class BokehServerMixin(object): """ This is the Mixin to inherit from when you create your agent. """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.bokeh_server = BokekServer(agent=self)