Streaming the Response Body
CherryPy manages HTTP requests, packing and unpacking the low-level details before passing control to your application's page handler, which generates the response body. It provides us the mechanism to return and yield the body content.
CherryPy supports various return types, including string, list of strings, and file. Also, to stream the response body output, you have to use the yield method. By default, yield is set to off as it is not safe and easy to stream the output content.
First, we will discuss how the “normal” CherryPy response process works, and after that, we will discuss how “streaming output” works with CherryPy.
Normal CherryPy Response Process
CherryPy acts as a middleman between the HTTP server and your application. The conversation between the page handler and the HTTP server is managed by CherryPy, as shown in the following image:

As you can see, all the requests made by the client first reach CherryPy, and then to the application. A response is generated by the application and sent back to CherryPy, which thereby sends the response to the HTTP server. The HTTP server waits for the entire output to reach it, accumulates the output, and then sends it back to the client all at once. The output contains the status, headers, and the response body. This mechanism works well for static or simple pages.
Now we will discuss how streaming output works in CherryPy
How Streaming Output Works with CherryPy
The streaming of the output is set to false by default. So, to stream the response body, you must first set the “response.stream” to True. Once this is done, the internal working changes and looks something like this:

The main difference is that the HTTP server does not wait for the entire output to reach it before sending it back to the client. It first gets the status and headers, which it sends back to the client before the output is yielded. It is necessary for CherryPy to set the status and headers before producing any output.
After the status and headers are set, the generator comes into the picture. The generator yields the output individually and produces the response body in pieces. It uses the next method to move ahead and continue to yield the output. A piece of output is yielded and sent to the HTTP server by the application code.
The HTTP server writes the output to the client and requests for the generator.next() and the next piece is yielded by the application and sent to the HTTP server. This process continues until all the pieces of the output are not yielded and written to the client.
CherryPy steps out of the picture once the status and headers are set, and the output is started to be written down to the client. So, if any error occurs during this time, it is not observed by CherryPy. It directly reached the HTTP server.
Now HTTP server does not know how to deal with errors. This is when errors like NotFound, InternalRedirect, HTTPError, and HTTPRedirect occur. You must return a generator that is separate from your page handler if you want to use a streaming generator while modifying headers.
Example 4
class Root:
@cherrypy.expose
def demo(self):
cherrypy.response.headers['Content-Type'] = 'text/plain'
if not authorized():
raise cherrypy.NotFound()
def content():
yield "Hello, "
yield "Ninja"
return content()
demo._cp_config = {'response.stream': True}

You can also try this code with Online Python Compiler
Run Code
Since streaming output is difficult, it must be used only when necessary. CherryPy allows the use of streaming output in situations like:
- Your application takes a lot of time to gather the output before writing it to the client.
- When you want something to be displayed fast on a web page, then some other details.
It is advised to use buffer content in place of stream content.
Response Time
To record the time at which the response began, a response in CherryPy includes an attribute response.time.

response.time = a time.time(), which marks the time at which the response has begun.
Frequently Asked Questions
What is CherryPy?
CherryPy is a python-based, object-oriented web application framework developed in 2002. CherryPy helps in speeding up the process of web application development by wrapping the HTTP protocols.
What are unanticipated errors?
If your application throws an exception that is not caught by any other part of the application, then CherryPy will return the HTTP 500 error code by default by using “request.error_response”. This type of error is called an unanticipated error.
What is the default behavior in case an unanticipated error occurs?
When an unanticipated error occurs in CherryPy, it is treated as Error 500. It is similar to what is meant by “request.error_response”. We can also change the behavior by defining our functions and replacing “request.error_response” with them.
What is the response time in CherryPy?
Response time is an attribute in CherryPy that records the time at which the response began. It gives a time.time() marking the starting time of the response.
Why is streaming output difficult?
When we are streaming the output, the response is not gathered together and written to the client at once. During the yielding time, if any error occurs it cannot be detected by CherryPy, but goes straight to the HTTP server, which is difficult and unsafe.
Conclusion
This article discussed the way for handling errors in CherryPy. We also discussed the concept of streaming the response body and obtaining the response time in CherryPy.
I hope you would have gained a better understanding of these topics now!
Are you planning to ace the interviews of reputed product-based companies like Amazon, Google, Microsoft, and more?
Attempt our Online Mock Test Series on Coding Ninjas Studio now!
Happy Coding!