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

久未见 提交于 2019-12-05 06:49:00

问题


In order of complexity, with Pyramids, I can create static bokeh graphs and then incorperate them with div tags like outlined here.

The Bokeh documentations explain clearly how one can setup a bokeh server for interactive data exploration, and I have successfully created such an application.

What I would like to do though is to have an interactive graph within a Pyramids view page. The requirements of this page would be as followed:

  • Upon loading of the view, a bokeh server is somehow started, and the data is loaded into the server's object model.
  • Somehow the Pyramid view will also receive the data in the server object model and render the data.

There are things I am not clear about:

  • I am not sure as to where the "widgets" used for selecting and filtering data should be rendered. It appears that for easy interaction with the rest of the graph, they should be part of the bokeh server.
  • I am not sure how to integrate a bokeh server page into a Pyramids view.
  • I am also not sure how one would approach starting of the bokeh server from within a Pyramids web app.

There is one paragraph that mentions how bokeh server can be embedded into either a Flask or Tornado app. But the paragraph is too brief for me to make sense right now. So I am asking how would I do this in Pyramids?


回答1:


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()



回答2:


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)



来源:https://stackoverflow.com/questions/44400581/how-do-i-integrate-a-bokeh-server-into-a-pyramids-application

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