I have been asked something similar a number of times. I don't know
why but it is always to me direct and not on the mailing list. Not
sure if it means the others were embarrassed about their yearnings for
something more like PHP or not. ;-)
Anyway, what you are wanting is not WSGI. That said, it doesn't mean
that you cannot write a WSGI application which acts as an intermediary
or proxy to interpret the files contents however you want. In effect
you are just creating a variant of a Python templating system. Rather
than you independently having to implement all the URL dispatch
yourself though, one can use aspects of Apache configuration to allow
Apache to do it for you. The result isn't strictly a pure WSGI
application as it will only work under Apache/mod_wsgi, but if you
don't care, then that is not an issue.
Quoting some bits from prior mails I have sent about this ....
The Apache configuration you want is:
Action pyhp-scripts /pyhp-interpreter
WSGIScriptAlias /pyhp-interpreter /some/path/pyhp.wsgi
AddHandler pyhp-scripts .pyhp
You would then put your .pyhp files where ever you want in directories
covered by the AddHandler. When ever a request comes in for a file
with .pyhp extension, Apache will actually invoke WSGI application at
/pyhp-interpreter to handle the request.
The WSGI environ for the WSGI application would be something like:
DOCUMENT_ROOT: '/Library/WebServer/Documents'
GATEWAY_INTERFACE: 'CGI/1.1'
HTTP_ACCEPT: 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
HTTP_ACCEPT_ENCODING: 'gzip, deflate'
HTTP_ACCEPT_LANGUAGE: 'en-us'
HTTP_CONNECTION: 'keep-alive'
HTTP_HOST: 'localhost'
HTTP_USER_AGENT: 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5;
en-us) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2
Safari/525.20.1'
PATH: '/usr/bin:/bin:/usr/sbin:/sbin'
PATH_INFO: '/~grahamd/foo.pyhp'
PATH_TRANSLATED: '/Users/grahamd/Sites/foo.pyhp'
QUERY_STRING: ''
REDIRECT_HANDLER: 'pyhp-scripts'
REDIRECT_SCRIPT_URI: 'http://localhost/~grahamd/foo.pyhp'
REDIRECT_SCRIPT_URL: '/~grahamd/foo.pyhp'
REDIRECT_STATUS: '200'
REDIRECT_URL: '/~grahamd/foo.pyhp'
REMOTE_ADDR: '::1'
REMOTE_PORT: '50491'
REQUEST_METHOD: 'GET'
REQUEST_URI: '/~grahamd/foo.pyhp'
SCRIPT_FILENAME: '/Users/grahamd/Sites/echo.wsgi'
SCRIPT_NAME: '/pyhp-interpreter'
SCRIPT_URI: 'http://localhost/~grahamd/foo.pyhp'
SCRIPT_URL: '/~grahamd/foo.pyhp'
SERVER_ADDR: '::1'
SERVER_ADMIN: 'y...@example.com'
SERVER_NAME: 'localhost'
SERVER_PORT: '80'
SERVER_PROTOCOL: 'HTTP/1.1'
SERVER_SIGNATURE: ''
SERVER_SOFTWARE: 'Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.7l
DAV/2 mod_wsgi/3.0-TRUNK Python/2.5.1'
mod_wsgi.application_group: 'graham-dumpletons-imac-2.local|/pyhp-interpreter'
mod_wsgi.callable_object: 'application'
mod_wsgi.listener_host: ''
mod_wsgi.listener_port: '80'
mod_wsgi.process_group: '~grahamd'
mod_wsgi.script_reloading: '1'
mod_wsgi.version: (3, 0)
wsgi.errors: <mod_wsgi.Log object at 0x1007888d0>
wsgi.file_wrapper: <built-in method file_wrapper of mod_wsgi.Adapter
object at 0x100726a80>
wsgi.input: <mod_wsgi.Input object at 0x10077fcb0>
wsgi.multiprocess: False
wsgi.multithread: True
wsgi.run_once: False
wsgi.url_scheme: 'http'
wsgi.version: (1, 0)
The actual file which was the matched target of the request would be
in 'PATH_TRANSLATED'. The WSGI application would then read and process
that file however it wants. This might include it parsing file,
converting it into executable Python code, performing caching and only
rereading files from disk when target file changes etc etc. What you
do is really up to you at this point, but at least Apache has done the
URL dispatching to file based resources for you so you do not have to
worry about that.
Graham
It doesn't need C code and can be just as fast as normal WSGI
application. Am too busy at the moment to explain further, maybe later
today.
Graham
Presumably abandoned when they realised that it wasn't perhaps a
useful thing after all.
Last updated: October 21, 2003
Graham
Either that, or the Spanish Inquisition got to him after that last update ;-)
--
Best Regards,
Nimrod A. Abing
W http://arsenic.ph/
W http://preownedcar.com/
W http://preownedbike.com/
W http://abing.gotdns.com/
You should avoid 'eval', at least in any context where the input could
come from a remote user by way of URL, post data, query string etc
etc. What are you trying to do that requires eval?
Graham
You're probably looking for something like RestrictedPython:
http://pypi.python.org/pypi/RestrictedPython/
I'd personally avoid this, though and - er - just write a WSGI
application!
Cheers,
Dan
--
Dan Fairs <dan....@gmail.com> | http://www.fezconsulting.com/
You should perhaps look at how Python Server Pages (PSP) in mod_python
is implemented. Documentation at:
http://www.modpython.org/live/current/doc-html/pyapi-psp.html
But look at mod_python source code.
Your comments about 'print' show up one of the problems with a lot of
these attempts to add Python into HTML. That is the expectation that
'print' output should appear in response stream.
There are two approaches which people normally use for this. The first
is to replace sys.stdout with some object which routes output back
into response stream. The problem with replacing sys.stdout is
ensuring it is safe in multithreaded environment. You can't just
replace sys.stdout for life time of your request as in multithreaded
context another request handler could do same thing and output could
go to wrong response. You also have problems where third party module
has used 'print' to produce debug output. Instead of going to a log
file, that debug output will end up in response when not intended.
The second approach is to compile template code and then replace
'print' opcode with alternate opcodes which direct output to a
specific stream object corresponding to response. This is the better
approach but requires more work and better done in conjunction with a
page code caching scheme to avoid having to do it every time.
A scheme which just tries to do textual substitution of 'print' in
code before evaling/compiling it is not a good idea.
Which of the above are you trying to use to ensure 'print' goes where you want?
As to eval, ultimately somewhere the code has to be compiled and run
and so you can't avoid evaluating it. The problem is just ensuring
that text which comes from URL, headers or post content doesn't get
expanded into code string before being evaluated.
Where exactly are you using 'eval'?
Graham
The problem with textual substitution, where you aren't properly
parsing code is that you might replace 'print' in a context where it
is not as a key word. For example, in text strings. Your substitution
thus has to be partly intelligent.
>> Which of the above are you trying to use to ensure 'print' goes where you want?
>>
>> As to eval, ultimately somewhere the code has to be compiled and run
>> and so you can't avoid evaluating it. The problem is just ensuring
>> that text which comes from URL, headers or post content doesn't get
>> expanded into code string before being evaluated.
>
> this where a good example would help. The way the code is compiled
> from the server-side source, I'm not clear on how text from URL,
> headers or post content could manifest itself in the source code
> before compilation.
It may well not be an issue, in which case finding an alternative to
'eval' may not be necessary. Still do check out what mod_python PSP
does. Even if you don't use its C based lexer stuff, you might learn
from how it in the end executes the code it creates.
Graham