- Organization
Utah Python
- Author
Seth House <seth@eseth.com>
- Date
2013-05-09
Outline
- History
- 2 v 3 v 3.2
- Basics
- Good
- Docs
- Bad
- Docs
- Community size
French dude.
- Remi Delon
- 2002: CherryPy
- CherryPy class processed to be self-contained module (app & server)
- 2004: CherryPy 2
- Object publishing
- Filters
- 2005: CherryPy 2.1
- Shipped with Turbogears
- Scrutiny; performance; WSGI support
- 2006: CherryPy 3
- Book
- Turbogears 2.x chose Pylons
- 2011: CherryPy 3.2
- Simplicity
- No deps
- Lightly opinionated
- Community driven
- Small (~600k)
- Featureful
- Plain functions or objects
- Extremely extendible
- Application framework
- Webserver
- Configuration via dictionaries
- Seven hook functions
- Called during request/response cycle
- Caching
- Encoding
- Sessions & cookies
- Authorization
- Uploads
- Static content
- No ORM / no templating / no forms
- Pure Python (Python 2.3+)
- HTTP/1.1 compliant
- Thread pooled
- Fast (1-2 ms per request)
- SSL (!)
- Cheroot: Stand-alone version
Application and server:
hello.py
import cherrypy
class HelloWorld:
def index(self):
return "Hello world!"
index.exposed = True
cherrypy.quickstart(HelloWorld())
help(cherrypy)
- Determine handler (via app config and URI)
- Set
cherrypy.request.handler
- Wraps handler
- Collect config in
cherrypy.request.config
- Extremely open-ended
- Use a custom by setting
request.dispatch
- http://docs.cherrypy.org/stable/refman/_cpdispatch.html
For example:
- http://localhost/ ->
root.index
- http://localhost/onepage ->
root.onepage
- http://localhost/some/page ->
root.some.page
Or possibly:
- http://localhost/blog/2005/01/17 ->
root.blog(self, year, month, day)
Resources:
When you wish to serve a resource on the Web, you never actually serve the resource, because “resources” are concepts. What you serve are representations of a resource, and page handlers are what you use in CherryPy to do that. Page handlers are functions that you write; CherryPy calls one for each request and uses its response (a string of HTML, for example) as the representation. […] CherryPy takes the output of the appropriate page handler function, binds it to cherrypy.response.body, and sends it as the HTTP response entity body. Your page handler function (and almost any other part of CherryPy) can directly set cherrypy.response.status and cherrypy.response.headers as desired.
- Any callable
- Current handler is
cherrypy.request.handler
- Replace on the fly
- Must have
exposed=True
attribute .index
attribute will take precedencedefault
callable as fallbackPOST
data available as kwargs:class MyHandler(object): def search(self, q, lang, page): # do something with ``q``
- Dictionaries (!)
- Python code (run-time)
- ConfigParser ini files
- Python code (execution-time)
- Configure
- Dispatcher (per URL)
request
/response
object attributes- Hooks
- Tools
- Logging
- Server options
- Global config
- Application config
Handler config:
class MyHandler(object): _cp_config = {}
- Behavior outside handlers
- Many builtin
Register / enable in the config:
[/images] tools.staticdir.on: True
- Some usable as handler
- Directly callable
Usable as decorators:
@tools.staticdir(dir='static') def images(): …
def mytool():
# something!
cherrypy.tools.mytool = Tool('on_some_hook', mytool)
- on_start_resource
The earliest hook; the Request-Line and request headers have been processed and a dispatcher has set request.handler and request.config.
- before_request_body
Tools that are hooked up here run right before the request body would be processed.
- before_handler
Right before the request.handler (the “exposed” callable that was found by the dispatcher) is called.
- before_finalize
This hook is called right after the page handler has been processed and before CherryPy formats the final response object. It helps you for example to check for what could have been returned by your page handler and change some headers if needed.
- on_end_resource
Processing is complete - the response is ready to be returned. This doesn’t always mean that the request.handler (the exposed page handler) has executed! It may be a generator. If your tool absolutely needs to run after the page handler has produced the response body, you need to either use on_end_request instead, or wrap the response.body in a generator which applies your tool as the response body is being generated (what a mouthful–see caching tee.output for an example).
- before_error_response
Called right before an error response (status code, body) is set.
- after_error_response
Called right after the error response (status code, body) is set and just before the error response is finalized.
- on_end_request
The request/response conversation is over, all data has been written to the client, nothing more to see here, move along.
on_start_resource
before_request_body
before_handler
before_finalize
on_end_resource
before_error_response
after_error_response
on_end_request
- Crazy flexible
- Lots of documentation
- Small
- Fast
- No deps
- Documentation is scattered / some holes
- CherryPy 2 vs. 3 vs. 3.2
- Small community
- Flexibility style can be tough to organize
- Demo of REST interface to Salt
- Request
- Response
- Reading headers
- Writing headers
- Redirects
- Exceptions
- WSGI Server
- Writing tests