quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sterling Hughes <sterl...@bumblebury.com>
Subject Re: Python Server Pages
Date Sat, 05 Apr 2003 06:49:06 GMT
On Sat, 2003-04-05 at 00:17, Gregory (Grisha) Trubetskoy wrote: 
> On 4 Apr 2003, Sterling Hughes wrote:
> > PSP supports
> > modifying request and response parameters, however it also provides
> > reasonable defaults.  So for example, the content-type of an application
> > starts with text/html.  Headers are automatically sent when the
> > application first produces output, etc.
> If I understood it correctly, this is made available via a global request
> object - it might be a better option if this was the mod_python's request
> object, which I think has more features. I don't know much about the
> mod_psp request, but mod_python's is modeled heavily after apache's
> request_rec. The details are here:
> http://www.modpython.org/live/current/doc-html/pyapi-mprequest.html
> BTW, the latest mod_python uses Python's new class implementation, whereas
> the 2.x version uses the old "built-in" object style. The implication is
> that new objects require Python higher version than 2.2.1 (I think).

Yep, I'm thinking more and more a handler is the way to go, I just have
one concern (below.)  

I was bit by this while trying to implement primitive support for psp in

> > 1) mod_python gains two new MIME handlers, application/x-httpd-python
> > and application/x-httpd-psp.  These MIME handlers behave similairly to
> > how they did in mod_psp.
> In mod_python I didn't use MIME types, it is mapped by use of AddHandler,
> don't know if this is good or bad. So the association of a file with
> mod_python typically looks like this:
> AddHandler python-program .py
> (As a side note, I think I saw that mod_perl's new handler name is
> mod_perl, so their config looks like "AddHandler mod_perl .pl", which I
> think is an idea worth borrowing).

I agree. :)

> Anyway - if someone could explain the advantages/disadvantages of using
> mime types, I'd appreciate since I don't seem to grasp the idea at the
> moment.

Well, from my perspective MIME types are the clear way of saying "every
file ending in .psp is a python server pages file," and "every file
ending in .py is a python file."

MIME types are catch all, whereas handlers are meant more specifically. 
At least that's my understanding.

> In any event, the handling of handlers is different between httpd 1.3 and
> 2.0. In 1.3 you passed a list of handlers/mime-types as part of module
> config, and then httpd took care of calling your handler when needed. In
> httpd 2.0 the handlers are called for every request and the responsibility
> for examining the mime type now belongs to the individual module, so
> handler code typically begins with something like:
>     if (!req->handler || strcmp(req->handler, "python-program"))
>         return DECLINED;
> So there is a (probably insignificant) performance hit to adding new
> types.
> The mod_python reqeust processing looks something like this:
>     python_handler() in mod_python.c
>         o  check to see whther there is a mod_python handler (not to
>              be confused with apache handler - mod_python handler is
>              the name of a python module which will handle the request and
>              it is set via PythonHandler directive). It's possible to
>              specify multiple handlers, in which case they will be called
>              sequentially. There is a special C structure called hstack
>              which contains this list of handlers. Handlers can also be
>              added onto the stack dynamically from inside Python.
>         o  select subinterpreter name based on virtual host name
> 	     and possibly directory/file name
>         o  if this subinterpeter exists, switch to it, otherwise create
>              it, then switch to it. This is done in get_interpreter().
>              get_interpreter() actually imports the mod_python.apache
>              module (written in Python) and instantiates a CallBack obj.
>              (the instantiation is only done once when subinterepreter is
>              created, from there on the object is reused)
>         o  create the mod_python request object
>         o  call into Python (specically call CallBack.HandlerDispatch())
> 	   -- from this point we're running Python code --
>            1. HandlerDispatch() looks at the hstack object to find out
>                which python handler (i.e. a normal Python module) to
>                import
>            2. The module is imported (and possibly re-imported if it
>                changed on disk since last import)
>            3. The name of the module is removed from hstack
>            4. Control is passed to a method inside this module.
>               o This is where content is generated, and written
>                   to the client using req.write()
>            5. Loop back to step 1. and repeat until hstack is empty
> > 2) The Python Server Pages functionality gets exported in a traditional
> > mod_python module, and therefore you could do something like:
> >
> > from mod_python import psp
> >
> > def handler(req):
> > 	code = psp.parse(filename)
> >
> > You can also use the psp.include() function to parse and execute psp
> > code from within mod_python handlers and application/x-httpd-python
> > python scripts.  mod_psp already has this functionality.
> So as a starting point, given that there'd exist a mod_python._psp module,
> (which would be _psp.so I guess) a mod_python handler could be implemented
> without any changes to mod_python and look something like:
> from mod_python import apache
> from mod_python import _psp
> def handler(req):
>     try:
>         # the request object is passed in because somehow it would
>         # be made available to the inlined Python, or is this something
>         # that can be done just prior to exec?
>         code = _psp.parse(req, filename)
>         exec code
>     except SomeErrors:
>         # do something...
>         return apache.SOME_ERROR
>     return apache.OK
> If the above code snippet lived in a file callde psp.py, then a typical
> httpd.conf would look like:
> AddHandler python-program .psp
> PythonHandler mod_python.psp
> OK, now that I just typed all this I realized I don't know how mod_psp
> sends its output to the client - in mod_python it's done via
> req.write()...

response.write() in mod_psp, modeled after (*gasp* ;) asp.  A script
such as:

<title>Hello World</title>

is translated into: 

response.write("<title>Hello World</title>")

Hacking this into req.write() is a 4 line patch.

> Now, if we want a special mime-type for psp, then I think the above is
> still good, we just need to insert a snippet of code at the beginning of
> python_handler() C function that adds mod_python.psp to hstack if it sees
> that particular mime type.
> Feel free to comment, the above was typed straight off the top of my head
> and probably contains errors/ommissions, but I think we have a starting
> point of a discussion.

My main concern with a handler is the speed issues, although I it seems
to be a good starting point.  The solution you present would require
reparsing the code each request.  If we do this internally, it allows us
to be more intelligent about caching code objects.  Currently a typical
mod_psp request requires a hashlookup + stat, that's it.  (well, ok,
realpath() causes an extra stat, or 5 on messed up systems, but that can
be eliminated with apache2).

Is there anyway for python to evaluate a compiled PyObject * OP
structure directly in Python code?  If so, I think this would work well
as a permanent solution too (although I'd still like to add a MIME
handler in the code, its just easier for people to install.)


View raw message