Yesterday night I experimented with getting Zope 3/Grok to work CherryPy, through WSGI. This led to all kinds of interesting adventures and opportunities. Follow the path I took: This started as I had been doing some work with CherryPy recently. I like what I see of CherryPy so far; a nice, Pythonic and powerful web server. Currently Zope 3 uses Twisted as the default web server implementation. Using Twisted has lots of advantages. It's a high-quality framework with a lot of features. It's also maintained by people other than the Zope developers, which is good. Since Zope was one of the first in the Python web space, the Zope developers still maintain a version of Medusa for Zope 2 called ZServer. It made sense to do that at the time, but it doesn't now. So if Twisted is so nice, why look at CherryPy at all? Because it's nice and because it's fun to try would be reasons that are good enough, but there are some other reasons that make CherryPy interesting for Zope too: Then I got slightly side-tracked. I figured that the easiest way to
integrate Zope 3 with CherryPy was to use CherryPy's WSGI server and use Zope 3 as a WSGI app, which Zope 3 has support for. This gave me a nice opportunity to play with WSGI for a bit. Now CherryPy's WSGI server is not actually CherryPy's server, so there goes my goal of integrating the whole of CherryPy... I heard a few good things about CherryPy's WSGI server too though, and it was easier to do, so I tried that. This became a nice opportunity to play with some other things. One of the reasons I wanted to try running Zope 3 and Grok with CherryPy is that it would allow me to experiment with what the minimal Zope 3 configuration of Zope 3 would need to be. Grok comes in nicely here: aiming for Grok support made that minimal configuration quite well-defined. I didn't need to aim to get Zope 3's own management UI up, just to get the basic Grok functionality to work. One of my aims is to make Zope 3's startup procedure a lot faster when you're doing Grok development. Another aim is to be prepared for the time when Zope 3 comes as a whole bunch of eggs: we can just use the eggs that Grok needs and not anything else. Combined with buildout this makes for an easy and powerful development and deployment system. So those are my aims and motivations - how far did I get? Quite far: I got a basic Grok view working with CherryPy's WSGI server when I stopped. Not needing the whole of Zope 3 to load up, the server also starts a bit faster, though not as fast as I'd like yet. Here it is: http://svn.zope.org/megrok.cherry There are some interesting parts. This is the site.zcml that includes the smallest minimum of ZCML I've managed to get to yet: http://svn.zope.org/megrok.cherry/trunk/site.zcml?view=markup This is the WSGI-based server that hooks Zope 3 as a WSGI app into CherryPy's WSGI server: http://svn.zope.org/megrok.cherry/trunk/src/megrok/cherry/server.py?view=markup Not a lot of code, thanks to WSGI! This shows that Grok works at least minimally; we're registering a view for Zope 3 containers (such as the root folder): http://svn.zope.org/megrok.cherry/trunk/src/megrok/cherry/demo.py?view=markup A lot more work needs to be done if this wants to become anywhere near production ready. This code right now is just an experiment. I just thought I'd get my thoughts out there, and see who's interested. Since it's all a buildout, you can install it safely and if you're on a sufficiently Unixy machine, make it work: This starts a server running on port 8080. It doesn't do much yet, but what it does is allowing you to access: This is rendered by the demo.py referenced before. Let me know what you think!
(7) Wed Nov 29 2006 23:15 Grok, CherryPy, WSGI and Zope 3:
$ svn co svn://svn.zope.org/repos/main/megrok.cherry megrok.cherry
$ cd megrok.cherry
$ python2.4 bootstrap.py
$ bin/buildout
$ bin/startserver
http://localhost:8080/test
- Comments:
Posted by Robert Brewer at Thu Nov 30 2006 01:35
Looks like fun. :) I'd only recommend that, if you're not using CherryPy's engine+server architecture, you should probably subclass _cpwsgiserver.CherryPyWSGIServer instead of wsgi.WSGIServer. One less import and a lot fewer headaches.
Posted by nastypastry at Thu Nov 30 2006 05:25
stay away from cherrypy, its a nice "toy project" but nowhere near at the level where one would trust a mission critical application on itjust take a look at the kinds of bugs that are fixed 6 months after release, boggles the mind just how amateurish it is
Posted by Martijn Faassen at Thu Nov 30 2006 14:08
Robert, I saw _cpwsigserver.CherryPyWSGIServer and realized I could subclass it myself. I didn't as I didn't know what to pass in yet, so that's why I reused CherryPy's server. Now that I know what goes I can probably dump that.Note that I'm also a bit baffled by why CherryPyWSGIServer is in a module starting with an underscore. That indicates private to me, but there doesn't seem to be a way to get to it without importing _cpwsgiserver. Should CherryPy be importing this into its __init__.py?
Posted by Kevin Smith at Thu Nov 30 2006 18:39
I've also played around recently with _cpwsgiserver with a full zope3 instance and casual benchmarking showed about a 20% performance increase over zserver and twisted. The casual test didn't account for media files or complex pages, but it's very nice to be able to switch out the webserver with just a few lines of code. Although very immature FAPWS looks promising as a very fast server (uses bindings to libevent) more wsgi servers can be found at http://www.wsgi.org/wsgi/Servers
Posted by Ian Bicking at Thu Nov 30 2006 19:12
Paste Script / Paste Deploy has some techniques for gluing together apps and servers. You might find it handy. The trunk of Paste Script has the glue code for CP's server as well (hopefully the author submitted that upstream too, but I dunno). The work required on your end would be to make some simple entry points for Grok apps -- basically a factory that given some configuration information, will return a WSGI app. It's described in more detail here: http://pythonpaste.org/deploy/#paste-app-factoryAnyway, given that you can put together a simple config file to plug together the Grok app and any of the supported servers (which is most of the WSGI servers). You can also start configuring WSGI stacks using different kinds of middleware, like prefix mappers, some transforming middleware like Deliverance, a bunch of debugging tools, and other stuff.
Posted by Robert Brewer at Thu Nov 30 2006 19:27
> Note that I'm also a bit baffled by why
> CherryPyWSGIServer is in a module starting
> with an underscore. That indicates private
> to me, but there doesn't seem to be a way
> to get to it without importing _cpwsgiserver.Good point! That should probably be changed in order to make it more clear that the module can be used standalone, in exactly the way you're doing.> Should CherryPy be importing this into its
> __init__.py?Perhaps, but probably not. The top-level cherrypy namespace aims at devs using the whole of CP, and since _cpwsgi.WSGIServer is the default WSGI server when you use the whole stack, we're leaving references to it (and its base class) out of the top level.Posted by Christian Wyglendowski at Thu Nov 30 2006 23:35
Not sure if you knew about/tried this, but in CP 3.0 you can "graft" arbitrary WSGI applications onto the CherryPy tree.Something like:cherrypy.tree.graft(yourWSGIapp, '/apps/yours')You /might/ not need to subclass the server at all.
