Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entry point for a bokeh server

I provide a tool as part of my python package that visualizes a parameter space using bokeh. The normal way to launch it would be:

$ bokeh serve --show my_package/tools/my_tool.py

Which opens a browser and shows an interactive plot. However, when I install this package using pip/ PyPI users can not easily access this folder, so I would like to provide an entry point for this in my setup.py.

Package Layout:
folder
|
|--- my_package
|     |
|     |- __init__.py
|     |- __main__.py
|     |- some_code.py
|     |
|     +--- tools
|           |
|           +--- my_tool.py
|
+--setup.py

In my setup.py I already specify an entry point to my main method:

setup.py
from setuptools import setup, find_packages

setup(
    name = "my_package",
    packages = find_packages(),
    entry_points = {
        'console_scripts': [
            'my_package = my_package.__main__:main'
          ]
    },
    [...],
)

However, the only way I found to launch the bokeh server and show the interface was to create another python script like this

import os
from subprocess import call

def main():
    p = os.path.realpath(__file__)
    prefix, _ = os.path.split(p)
    bokeh_server_file = os.path.join(prefix, "my_tool.py")
    call(["bokeh", "serve", "--show", bokeh_server_file])

if __name__ == "__main__":
    main()

place it in the tools folder and create an entry point for this scripts main method. *shudder* There has to be a better way to do this.

Is it possible to provide this kind of entry point using setuptools or is there another way to achieve this behavior?

like image 512
m00am Avatar asked Mar 22 '17 17:03

m00am


People also ask

When should I use Bokeh server?

You might want to use the Bokeh server for exploratory data analysis, possibly in a Jupyter notebook, or for a small app that you and your colleagues can run locally.

What is a Bokeh server?

The Bokeh server is an optional component that can be used to provide additional capabilities, such as: hosting and publishing Bokeh plots for wider audiences. streaming data to plots so that they automatically update. interactively visualizing very large datasets by employing downsampling and abstract rendering.

How do you install Bokeh?

The easiest way to install Bokeh is to use conda . Conda is part of the Anaconda Python Distribution, which is designed with scientific and data analysis applications like Bokeh in mind. If you use Anaconda on your system, installing with conda is the recommended method. Otherwise, use pip .


1 Answers

To expand on the answer of @jxramos, I modified the standalone embed example given on the page. By managing the tornado IO loop yourself in the main function you can make your bokeh script behave like a normal python script that automatically starts a browser when executed.

from tornado.ioloop import IOLoop
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
from bokeh.server.server import Server

def modify_doc(doc):
    """Function that modifies a document."""
    # [...] create a plot
    doc.add_root(plot)
    doc.title = "Test Plot"

def main():
    """Launch the server and connect to it."""
    io_loop = IOLoop.current()
    bokeh_app = Application(FunctionHandler(modify_doc)) # pass the function that assembles your document here.
    server = Server({"/": bokeh_app}, io_loop=io_loop)
    server.start()
    print("Opening Bokeh application on http://localhost:5006/")

    io_loop.add_callback(server.show, "/")
    io_loop.start()

main()

This script can then be called from the command line

$ python my_tool.py

and hence be used for an entry point as expected:

[...]
entry_points = {
    'console_scripts': [
        'my_package = my_package.tools.my_tool:main'
      ]
},
[...]

General Version

The following is a more complete example that I ported over from a Documentation example I wrote. Since Documentation is being phased out, I think it is better suited as part of this answer.

Local bokeh server with console entry point

To allow a bokeh application to be executed like a normal .py file, you need to handle the tornado IOloop in your application, as described here. A standalone bokeh application like this can be used to implement a console script entry point in setup.py. However, this requires bokeh version >= 0.12.4.

The bokeh application

Consider the file local_server.py:

from tornado.ioloop import IOLoop

from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.server.server import Server


def modify_doc(doc):
    """Add a plotted function to the document.

    Arguments:
        doc: A bokeh document to which elements can be added.
    """
    x_values = range(10)
    y_values = [x ** 2 for x in x_values]
    data_source = ColumnDataSource(data=dict(x=x_values, y=y_values))
    plot = figure(title="f(x) = x^2",
                  tools="crosshair,pan,reset,save,wheel_zoom",)
    plot.line('x', 'y', source=data_source, line_width=3, line_alpha=0.6)
    doc.add_root(plot)
    doc.title = "Test Plot"


def main():
    """Launch the server and connect to it.
    """
    print("Preparing a bokeh application.")
    io_loop = IOLoop.current()
    bokeh_app = Application(FunctionHandler(modify_doc))

    server = Server({"/": bokeh_app}, io_loop=io_loop)
    server.start()
    print("Opening Bokeh application on http://localhost:5006/")

    io_loop.add_callback(server.show, "/")
    io_loop.start()


main()

This file can be executed

$ python local_server.py

which run the server and automatically launch a browser to show the document.

Entry points and the setup.py

In order to provide a script that can be easily installed and called using the setup.py. Consider the following folder structure:

project
├── setup.py
└── my_package
    ├── __init__.py
    └── local_server.py

Content of setup.py:

from setuptools import setup

setup(
    name = "my_package",
    entry_points={
        "console_scripts": ["my_script = my_package.local_server:main"],
    },
)

When installing the package using

$ python setup.py install

you can then use the call

$ my_script

to launch the bokeh application and automatically start a browser displaying the document.

like image 71
m00am Avatar answered Sep 27 '22 21:09

m00am