具有交互作用的散景开发工作流程

时间:2016-06-12 16:54:24

标签: bokeh

我正在使用

开发可视化
% bokeh serve --show myapp.py 

问题在于,当我更改myapp.py时,我必须终止上述命令并重新启动它。这种开发有更好的工作流程吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

还没有。截至Bokeh 0.11.1(很快也将成为0.12),这是一个有计划但仍然开放的feature request只有少数人为Bokeh工作了大量工作。新贡献者可以帮助加速新功能和修复。如果您能够提供帮助,请通过project gitter channel与我们联系。

答案 1 :(得分:0)

我无法理解散景的内部结构,以使这项工作变得更好,但这是一个hacky脚本,无论如何都能做到我想要的。

# bokeh_watcher.py
#
# Watches specific files in directory and restarts bokeh server upon change.
#
#   % python bokeh_watcher filename.py
#
# Note that you stil have to navigate your browser to localhost:5006/filename
# to see your Bokeh visualization and you might have to refresh the browser. 

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import RegexMatchingEventHandler
from bokeh.command.bootstrap import main
import multiprocessing
import os
JOBS = []
FILE = []

def spawn_bokeh(args):
    main(args)

class BokehHandler(RegexMatchingEventHandler):
    '''
    kills and restarts bokeh server upon filechange.
    '''
    def on_modified(self, event):
        super(BokehHandler, self).on_modified(event)
        what = 'directory' if event.is_directory else 'file'
        logging.info("Modified %s: %s"% (what, event.src_path))
        p=JOBS.pop()
        p.terminate()
        time.sleep(1) # time to die
        logging.info('terminated')
        logging.info('initiating restart')
        p = multiprocessing.Process(target=spawn_bokeh,
                                    args=(self.args,))
        p.start()
        JOBS.append(p)

if __name__ == "__main__":
    here = os.path.realpath(__file__)
    fullpathname=os.path.dirname(here)+os.sep+sys.argv[1]
    # local logger
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    filemod_handler = BokehHandler(['.*%s'%(sys.argv[1])])
    filemod_handler.args = ['','serve',fullpathname, '--log-level','info'] 
    # fire up bokeh server
    p = multiprocessing.Process(target=spawn_bokeh,args=(filemod_handler.args,))
    p.start()
    # store object in global for later
    JOBS.append(p)
    observer = Observer()
    observer.schedule(filemod_handler, '.', recursive=False)
    observer.start()
    try:
        while True:
            time.sleep(3)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()