
Question:
I've just discovered CherryPy. I am going through the tutorial, so far so good. While doing it I wanted to create a "BUSY DOING WORK" splash screen, essentially I have a python function that for example updates an sqlite table with 10000 records. What I want to do is get CherryPy to display a <strong>busy.html</strong> page while the database is being updated, when the database operation completes I want to redirect the user back to the <strong>main.html</strong> page. So far I have only come across
dev update_db(self):
#Code to update the database goes here
return "busy.html"<----show user that work is being done
#database has completed
CherryPy.redirect "main.html"
But <em>return</em> simply exits the function. Is there anyway of doing presenting the user with a temporary splashscreen, while the database is being updated then returning the user back to another page once its complete. I suppose an alternative is to have a message flash across the top of the existing page, But I don't know if CherryPy has a flash message feature much like Flask.
Answer1:IMHO, you can achieve this with generators and here is a link from latest (v3.8) cherrypy <a href="http://docs.cherrypy.org/en/latest/advanced.html#how-streaming-output-works-with-cherrypy" rel="nofollow">documentation</a>. However, you should take into account the following issue in the docs
<blockquote>Streaming generators are sexy, but they play havoc with HTTP. CherryPy allows you to stream output for specific situations: pages which take many minutes to produce, or pages which need a portion of their content immediately output to the client. Because of the issues outlined above, it is usually better to flatten (buffer) content rather than stream content. Do otherwise only when the benefits of streaming outweigh the risks.
</blockquote>Generators have some limitations as written in the documentation
<blockquote>you cannot manually modify the status or headers within your page handler if that handler method is a streaming generator, because the method will not be iterated over until after the headers have been written to the client. <strong>This includes raising exceptions like HTTPError, NotFound, InternalRedirect and HTTPRedirect</strong>. To use a streaming generator while modifying headers, you would have to return a generator that is separate from (or embedded in) your page handler.
</blockquote>Because the headers have already been written to the client when streaming, raising redirection exception cannot help to redirect to different page after your long running task. If I were you, I would yield
this
<meta http-equiv="refresh" content="0;URL='/anotherpage'" />
or this at the final yield
<script>window.location.href="/anotherpage";</script>
I coded and example for you. I hope this gives you an idea.
# encoding: utf-8
import time
import cherrypy
class Root(object):
@cherrypy.expose
def index(self):
content = '''<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("body").append("jQuery Ready
");
setTimeout(function(){
$("body").html("Redirecting Please Wait...")
}, 2500);
});
</script>
</head>
<body>
Page Content1
Page Content2
Page Content3
Page Content4
Page Content5
Page Content Final
</body>
</html>
'''
for line in content.split("\n"):
yield line
time.sleep(1)
else:
yield '''<meta http-equiv="refresh" content="5;URL='/anotherpage'" />'''
index._cp_config = {'response.stream': True}
@cherrypy.expose
def anotherpage(self):
return "Another Page"
cherrypy.quickstart(Root(), "/")