-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Streamline README.txt, add documentation for the new feature (Zope …
…3 on top of Paste), and move some cumbersome "documentation" out to a separate file. * Bump version number to 0.2 * Improve packaging metadata, use README.txt as CheeseShop frontpage
- Loading branch information
Showing
4 changed files
with
216 additions
and
218 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,252 +1,173 @@ | ||
zope.paste - wsgi applications in zope 3 using paste.deploy | ||
=========================================================== | ||
zope.paste - Zope 3 and PasteDeploy | ||
=================================== | ||
|
||
What is it? | ||
----------- | ||
zope.paste allows you to | ||
|
||
A simple package that enables one to configure WSGI applications to | ||
run inside Zope 3 using `paste.deploy`_. | ||
* employ WSGI middlewares inside a Zope 3 application | ||
|
||
Why? | ||
---- | ||
* deploy the Zope 3 application server on any WSGI-capable webserver | ||
|
||
Because Zope 3 already supported WSGI applications, but didn't provide | ||
a simple way to create and configure them. | ||
using PasteDeploy_. These are two completely different modi operandi | ||
which only have in common that they are facilitate PasteDeploy_. Each | ||
is explained in detail below. | ||
|
||
How to use it? | ||
-------------- | ||
.. _PasteDeploy: http://pythonpaste.org/deploy/ | ||
|
||
Short version | ||
+++++++++++++ | ||
|
||
Configuration is very simple. There are three steps that need to be | ||
performed: | ||
WSGI middlewares inside Zope 3 | ||
------------------------------ | ||
|
||
1. Configure a named IServerType utility (by default, we already | ||
define a utility named `Paste.Main`). | ||
zope.paste allows you to stack WSGI middlewares on top of Zope 3's | ||
publisher application without changing the way you configure Zope | ||
(``zope.conf``) or run it (``runzope``, ``zopectl``). | ||
|
||
2. Change the <server> directive on <INSTANCE_HOME>/etc/zope.conf to | ||
use the newly-created `IServerType` utility (out of the box, you | ||
can just swap out `HTTP` or `WSGI-HTTP` by `Paste.Main`). | ||
Configuration is very simple. Assuming that you've already created a | ||
Zope 3 instance using the ``mkzopeinstance`` script, there are three | ||
steps that need to be performed: | ||
|
||
3. Configure a WSGI application using `paste.deploy`_ syntax in | ||
<INSTANCE_HOME>/etc/paste.ini | ||
Installing and configuring zope.paste | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Here's an example of how to configure the `Paste.Main` application | ||
using paste.deploy to use the Zope 3 publisher as a WSGI app: | ||
zope.paste can be installed as an egg anywhere onto your | ||
``PYTHONPATH`` or simply dropped into your | ||
``<INSTANCE_HOME>/lib/python`` directory. Then you need to enable | ||
zope.paste's ZCML configuration by creating the file | ||
``<INSTANCE_HOME>/etc/package-includes/zope.paste-configure.zcml`` | ||
with the following contents:: | ||
|
||
[app:Paste.Main] | ||
paste.app_factory = zope.paste.application:zope_publisher_app_factory | ||
<include package="zope.paste" /> | ||
|
||
.. _paste.deploy: http://pythonpaste.org/deploy/ | ||
Configuring the server | ||
~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Long version | ||
++++++++++++ | ||
|
||
The narrative below applies to Zope 3.2. | ||
|
||
When you create a Zope 3 instance, you have a choice of creating a | ||
`zope.app.server` (a.k.a. zserver) instance or a `zope.app.twisted` | ||
instance. | ||
|
||
This package works with both, but applications that you develop using | ||
WSGI might choose to use only one of them. | ||
|
||
After creating an instance, you should have a directory with some | ||
subdirectories like `etc`, `lib`, `var`, `log`, etc. Inside the `etc` | ||
directory you can find a file named `zope.conf` inside it. | ||
|
||
This is the file that contains the bootstrap configuration for | ||
starting up a Zope 3 server. | ||
|
||
Regardless of the flavor you choose (zserver or twisted) you will end | ||
up with a file that contains something just like this:: | ||
|
||
<server> | ||
type HTTP | ||
address 8080 | ||
</server> | ||
|
||
The part that's most interesting to us here is the `type HTTP` | ||
line. This is what controls what kind of server will be | ||
created. | ||
|
||
When starting up, upon finding this directive, Zope 3 will lookup a | ||
`named utility` providing `IServerType`. If you don't know what a | ||
named utility is, you should go read some documentation before | ||
proceeding. | ||
|
||
Zope 3.2 has some support to WSGI applications. In fact, it does | ||
define a `IServerType` utility named `WSGI-HTTP`, which is also | ||
aliased to `HTTP`. So when you start up Zope 3 for the first time, | ||
you're actually using WSGI already! | ||
|
||
This package, `zope.paste` does define a new `IServerType` utility | ||
named `Paste.Main`. So, effectively, once you have this package | ||
installed you can change your `zope.conf` file to read:: | ||
We create a ``<server>`` directive in | ||
``<INSTANCE_HOME>/etc/zope.conf`` to use zope.paste's server | ||
definition, ``Paste.Main``. That way the WSGI middlewares will be | ||
invoked when responses are served through this server:: | ||
|
||
<server> | ||
type Paste.Main | ||
address 8080 | ||
address 8081 | ||
</server> | ||
|
||
The `Paste.Main` utility defined in this package though doesn't know | ||
how to create a WSGI application by itself. Instead, it relies on | ||
`paste.deploy` to create a WSGI application. By default, it will load | ||
a file named `paste.ini` in the `etc` directory of your Zope 3 | ||
instance. | ||
Configuring the WSGI stack | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
When loading this file it will look for an application with the *same | ||
name* as the utility defined. So the simplest thing you can do is to | ||
create the `paste.ini` file with some content as follows:: | ||
Now we configure a WSGI application using PasteDeploy_ syntax in | ||
``<INSTANCE_HOME>/etc/paste.ini``. Here's an example of how to | ||
configure the `Paste.Main` application to use the Zope 3 publisher as | ||
a WSGI application, therefore doing the exact same thing that the | ||
regular ``HTTP`` server definition would do:: | ||
|
||
[app:Paste.Main] | ||
paste.app_factory = zope.paste.application:zope_publisher_app_factory | ||
|
||
What this does is to create a WSGIPublisherApplication, which happens | ||
to be the same WSGI application that is created when you use the | ||
`HTTP` or `WSGI-HTTP` server type utilities. | ||
|
||
Now, this is a lot of contortion just to do something that Zope 3 does | ||
out of the box no? Yes, I agree. But this is where stuff starts | ||
getting fun. | ||
|
||
`paste.deploy` allows you to chain various WSGI entities | ||
together. There seems to be a distinction between 'apps' and 'filters' | ||
(also referred to as 'middleware'). An example that might interest is | ||
applying a `XSLT` transformation to the output of the Zope 3 WSGI | ||
application. | ||
That's not really interesting, though. PasteDeploy_ allows you to | ||
chain various WSGI entities together, which is where it gets | ||
interesting. There seems to be a distinction between 'apps' and | ||
'filters' (also referred to as 'middleware'). An example that might | ||
be of interest is applying a `XSLT` transformation to the output of | ||
the Zope 3 WSGI application. | ||
|
||
Happily enough, someone seems to have already created a WSGI filter | ||
for applying a `XSLT` stylesheet. You can find it at:: | ||
|
||
http://www.decafbad.com/2005/07/xmlwiki/lib/xmlwiki/xslfilter.py | ||
|
||
If you wanted to apply this WSGI filter to Zope 3, you would need three | ||
things: | ||
for applying a `XSLT` stylesheet. You can find it at | ||
http://www.decafbad.com/2005/07/xmlwiki/lib/xmlwiki/xslfilter.py | ||
|
||
1. Put the `xslfilter.py` file somewhere in | ||
PYTHONPATH. <INSTANCE>/lib/python is a good place. | ||
If you wanted to apply this WSGI filter to Zope 3, you would need | ||
three things: | ||
|
||
2. Add this snippet to the bottom of `xslfilter.py` | ||
1. Put the ``xslfilter.py`` file somewhere in ``PYTHONPATH``. | ||
``<INSTANCE>/lib/python`` is a good place. | ||
|
||
:: | ||
2. Add this snippet to the bottom of ``xslfilter.py``:: | ||
|
||
def filter_factory(global_conf, **local_conf): | ||
def filter(app): | ||
return XSLFilter(app) | ||
return filter | ||
def filter_factory(global_conf, **local_conf): | ||
def filter(app): | ||
return XSLFilter(app) | ||
return filter | ||
|
||
3. Change the `paste.ini` file as follows | ||
3. Change ``paste.ini`` file as follows:: | ||
|
||
:: | ||
[pipeline:Paste.Main] | ||
pipeline = xslt main | ||
|
||
[pipeline:Paste.Main] | ||
pipeline = xslt main | ||
[app:main] | ||
paste.app_factory = zope.paste.application:zope_publisher_app_factory | ||
|
||
[app:main] | ||
paste.app_factory = zope.paste.application:zope_publisher_app_factory | ||
[filter:xslt] | ||
paste.filter_factory = xslfilter:filter_factory | ||
|
||
[filter:xslt] | ||
paste.filter_factory = xslfilter:filter_factory | ||
What this does is to define a *pipeline*. Learn more about this on | ||
the PasteDeploy_ website. Refer to the source of ``xslfilter.py`` | ||
for information about how to pass a stylesheet to the filter. | ||
|
||
What this does is to define a `pipeline`. Learn more about this on the | ||
`paste.deploy`_ website. Refer to the source of `xslfilter.py` for | ||
information about how to pass a stylesheet to the filter. | ||
|
||
Now, this far we only worked with a single WSGI application. If you | ||
wanted to host *more* than one WSGI application there are a couple | ||
ways of doing it: | ||
Deploying Zope 3 on an WSGI-capable webserver | ||
--------------------------------------------- | ||
|
||
1. Using a `composite application` as described in `paste.deploy`_. | ||
zope.paste allows you to run Zope 3 on any WSGI-capable webserver | ||
software using PasteDeploy_. For this you will no longer need a Zope | ||
3 instance (though you can still have one), you won't configure Zope 3 | ||
through ``zope.conf`` and won't start it using ``runzope`` or | ||
``zopectl``. | ||
|
||
2. Setting up extra `IServerType` utilities. | ||
Configuring the application | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
I'm going to show you how to do the latter now. | ||
zope.paste provides a PasteDeploy_-compatible factory for Zope 3's | ||
WSGI publisher application and registers it in an entry point. We can | ||
therefore create a very simple Zope 3 application in a PasteDeploy_ | ||
configuration file (e.g. ``paste.ini``):: | ||
|
||
The trick here is that as mentioned earlier here, you have the option | ||
to use both the `zserver` and the `twisted` WSGI servers. `zope.paste` | ||
is just glue code, so we defined a `IServerType` utility for each, and | ||
the only thing special is that the utility name is passed on to the | ||
WSGI application factory. | ||
|
||
Here's an excerpt from the `configure.zcml` as found on this package:: | ||
|
||
<configure zcml:condition="have zserver"> | ||
<utility | ||
name="Paste.Main" | ||
component="._server.http" | ||
provides="zope.app.server.servertype.IServerType" | ||
/> | ||
</configure> | ||
|
||
<configure zcml:condition="have twisted"> | ||
<utility | ||
name="Paste.Main" | ||
component="._twisted.http" | ||
provides="zope.app.twisted.interfaces.IServerType" | ||
/> | ||
</configure> | ||
|
||
Depending on which server is available, the right `IServerType` | ||
utility is registered. You are encouraged to use the same pattern when | ||
defining yours. | ||
|
||
So suppose you want to have a second WSGI application. Here's how you | ||
could do it. | ||
|
||
1. Create a new `IServerType` utility. This excerpt could be added to | ||
a `configure.zcml` in your own package, or to a standalone file in | ||
`etc/package_includes` | ||
|
||
:: | ||
[app:main] | ||
use = egg:zope.paste | ||
site_definition = /path/to/site.zcml | ||
file_storage = /path/to/Data.fs | ||
devmode = on | ||
|
||
<configure zcml:condition="have zserver"> | ||
<utility | ||
name="Paste.Another" | ||
component="zope.paste._server.http" | ||
provides="zope.app.server.servertype.IServerType" | ||
/> | ||
</configure> | ||
In this case, ``/path/to/site.zcml`` refers to a ``site.zcml`` as | ||
known from a Zope 3 instance. You can, for example, put ``paste.ini`` | ||
into an existing Zope 3 instance, next to ``site.zcml``. | ||
|
||
<configure zcml:condition="have twisted"> | ||
<utility | ||
name="Paste.Another" | ||
component="zope.paste._twisted.http" | ||
provides="zope.app.twisted.interfaces.IServerType" | ||
/> | ||
</configure> | ||
Configuring the ZODB database | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
2. Change your `zope.conf` file to define a new server, using the | ||
newly-created `Paste.Another` utility | ||
Instead of referring to a ZODB FileStorage using the ``file_storage`` | ||
setting, you can also configure multiple or other ZODB database | ||
backends in a ZConfig-style configuration file (much like | ||
``zope.conf``), e.g. the following configures a ZEO client:: | ||
|
||
:: | ||
<zodb> | ||
<zeoclient> | ||
server localhost:8100 | ||
storage 1 | ||
cache-size 20MB | ||
</zeoclient> | ||
</zodb> | ||
|
||
<server> | ||
type Paste.Main | ||
address 8080 | ||
</server> | ||
Refer to this file from ``paste.ini`` this way (and delete the | ||
``file_storage`` setting):: | ||
|
||
<server> | ||
type Paste.Another | ||
address 8180 | ||
</server> | ||
db_definition = db.conf | ||
|
||
3. Define a WSGI application `Paste.Another` in `paste.ini` | ||
Configuring the server | ||
~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
:: | ||
In order to be able to use our Zope application, we only need to add a | ||
server definition. We can use the one that comes with Paste or | ||
PasteScript_, rather:: | ||
|
||
[pipeline:Paste.Main] | ||
pipeline = xslt main | ||
[server:main] | ||
use = egg:PasteScript#wsgiutils | ||
host = 127.0.0.1 | ||
port = 8080 | ||
|
||
[app:main] | ||
paste.app_factory = zope.paste.application:zope_publisher_app_factory | ||
.. _PasteScript: http://pythonpaste.org/script/ | ||
|
||
[filter:xslt] | ||
paste.filter_factory = xslfilter:filter_factory | ||
Now we can start the application using the ``paster`` command that | ||
comes with PasteScript_:: | ||
|
||
[app:Paste.Another] | ||
paste.app_factory = zope.paste.application:zope_publisher_app_factory | ||
$ paster serve paste.ini | ||
|
||
That's it! For more information, learn about the different ways of | ||
configuring applications with `paste.deploy`_. | ||
WSGI middlewares can be configured like described above or on the | ||
PasteDeploy_ website. |
Oops, something went wrong.