Reputation: 99
I am trying to develop a web site where one can upload a file, which is then analyzed in the back to generate interactive figures (a scatter plot and a histogram), which is then return to the browser for the user to manipulate. (Imagine putting Excel online so that one can upload a file, get a figure and manipulate the figure.) I considered various options and decided to go with Bokeh for plotting. I wrote a python script and an html page to upload a file. Using Bokeh, I was able to create an output file (e.g. "plot.html"). This works well.
Separately, I have installed Tornado so that I can upload and dynamically read a simple file (e.g. "test.txt"), and simply return the content of the file in output.html. So this works well.
However, when I modify the script written for use with Tornado so that it displays the earlier, Bokeh generated plot.html, this doesn't work. Is there anything about a Bokeh generated html (containing plot objects) that cannot be properly rendered by Tornado? For example, I read that an entry from a database search can contain elements that cannot be serialized, and non-serializable elements need to be removed before the search result can be displayed. I am wondering if something like this may be going on.
Here're some relevant scripts:
display.py: for reading and returning the content of a file using Tornado. This works and returns the content of test.txt, as expected.
import os.path
import random
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
define("port", default=80, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
class OutputHandler(tornado.web.RequestHandler):
def post(self):
fname = self.get_argument('upfile')
f = open(fname, 'r')
lines = f.readlines()
self.render('plot.html', content=lines)
if __name__ == '__main__':
tornado.options.parse_command_line()
app = tornado.web.Application(
handlers=[(r'/', IndexHandler), (r'/content', OutputHandler)],
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
debug=True
)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
plot.py: for reading and generating a plot using Bokeh. This works and creates plot.html containing the generated plots.
from bokeh.plotting import *
output_file("plot.html")
filename = 'test.dat'
f=open(filename,'r')
#####
# deleted lines for manipulating data
#####
scatter(ndarray[:1000,0], ndarray[:1000,1], color='red', alpha=0.7)
quad(top=hist, bottom=np.zeros(len(hist)), left=edges[:-1], right=edges[1:],
fill_color="#036564", line_color="#033649")
display_plot.py: for displaying a Bokeh generated plot.html through Tornado. This does not work.
import os.path
import random
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
define("port", default=80, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('plot.html')
# the rest the same as in display.py for now.
This last script is what led me to think that displaying a Bokeh generated html containing plot objects is not the same as displaying other html files containing text and figures only, which can be rendered correctly. Is this true and what can I do to display plot.html using Tornado (or any web service for that matter)?
Thanks for your help.
Upvotes: 1
Views: 1484
Reputation: 22134
RequestHandler.render
interprets a file as a Tornado template. This means that some character sequences (especially double curly braces {{ }}
) have a special meaning. If you just want to serve a file as-is, use write
instead of render
:
with open('plot.html') as f:
self.write(f.read())
Upvotes: 2