How do I integrate a Bokeh Server into a Pyramids Application?

倾然丶 夕夏残阳落幕 提交于 2019-12-03 21:29:48

As bigreddot said, the workflow is quite similar with minute changes in the code. I actually built my answer based on his anwer. Thanks bigreddot!

Following is my solution for integrating bokeh-sever with Pyramid.

  1. Create a function to generate Bokeh document (plot)
def bokeh_doc(doc):
    # create data source
    # define all elements that are necessary
    # ex: 
    p = line(x, y, source)

    # now add 'p' to the doc object
    doc.add_root(p)

    # define a callback if necessary
    # and register that callback
    doc.add_periodic_callback(_cb, delay)
  1. Add a route location of the app to Pyramid server config object. Mostly in the __init__.py or any other file where you configure the routes.
    conf.add_route('bokeh_app', '/bokeh-app')
  1. Add a view where the bokeh_app has to be rendered. This function could be written in views.py or where ever you deem appropriate.
from pyramid.view import view_config
from bokeh.embed import server_document

@view_config(route_name='bokeh_app', renderer='static/plot.jinja2')
def bokeh_view(request):
    # this '/app' route to the plot is configured in step. 4
    # using default host and port of bokeh server. 
    # But, the host and port can be configured (step. 4)
    script = server_document('localhost:5006/app') 

    # assuming your jinja2 file has 
    # {{ script|safe }}
    # embedded somewhere in the <body> tag
    return {'script': script}
  1. Now, fire-up a bokeh server.
from bokeh.application import Application 
from bokeh.application.handlers import FunctionHandler 
from bokeh.server.server import Server

# bokeh_doc is the function which defines the plot layout (step. 1)
chart_app = Application(FunctionHandler(bokeh_doc))

# the '/app' path is configured to display the 'chart_app' application
# here, a different host and port for Bokeh-server could be defined
# ex: {"<host2:9898>/app_bokeh": chart_app}
bokeh_server = Server({"/app": chart_app}, allow_websocket_origin=["localhost:6543"]) 

# start the bokeh server and put it in a loop
server.start()
server.io_loop.start()

allow_websocket_origin takes in a list of strings that must be upgraded to support web-socket connection required by bokeh. In this case, we need give the url of the pyramid server

  1. Finally, start the Pyramid server
from wsgiref.simple_server import make_server

pyramid_app = conf.make_wsgi_app()
pyramid_server = make_server('localhost', 6543, pyramid_app)

pyramid_server.serve_forever()

The formula for running embedded in another (flask, django, tornado, etc.) process is basically the same in all cases. He bare essentials are presented in this "standalone" example which shows just the steps needed to start a Bokeh server on a Tornado IOloop that you manage yourself:

https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py

The basic steps are:

  • Make a function to generate Bokeh documents:

    def modify_doc(doc):
    
        # setup up plots and widgets in a layout, then
        doc.add_root(some_layout)
    
  • Create a Bokeh Application with this function, and start a Bokeh server with it:

    from bokeh.application.handlers import FunctionHandler
    from bokeh.application import Application
    from bokeh.server.server import Server
    
    bokeh_app = Application(FunctionHandler(modify_doc))
    
    server = Server({'/': bokeh_app}, io_loop=io_loop)
    server.start()
    
  • Finally, add the Bokeh Server to a tornado IOloop that you create and manage:

    from tornado.ioloop import IOLoop
    
    io_loop = IOLoop.current()
    io_loop.add_callback(server.show, "/")
    io_loop.start()
    

Then your (Flask, Django, Pyramid, whatever) views can embed Bokeh apps from this server using either <iframes> or bokeh.embed.autoload_server in the standard ways (see e.g. the Flask embed script for an example)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!