How to setup Python with Lighttpd and FastCGI (like PHP)
Running Lighttpd on Linux, I would like to be able to execute Python scripts just the way I execute PHP scripts.
The goal is to be able to execute arbitrary script files stored in the WWW directory, e.g. http://www.example.com/*.py
.
I would not like to spawn a new Python instance (interpreter) for every request (like done in regular CGI, if I'm not mistaken), which is why I'm using FastCGI.
-
Following Lighttpd's documentation, the following is the FastCGI part of my config file. The problem is that it always runs the
/usr/local/bin/python-fcgi
script for every *.py file, regardless of the content of that file:http://www.example.com/script.py [output=>] "python-fcgi: test"
(regardless of the content of
script.py
) I'm not interested in using any framework, but simply executing individual [web] scripts.
How can I make it act like PHP, executing any script in the WWW directory by requesting it's path?
/etc/lighttpd/conf.d/fastcgi.conf:
server.modules += ( "mod_fastcgi" )
index-file.names += ( "index.php" )
fastcgi.server = (
".php" => (
"localhost" => (
"bin-path" => "/usr/bin/php-cgi",
"socket" => "/var/run/lighttpd/php-fastcgi.sock",
"max-procs" => 4, # default value
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "1", # default value
),
"broken-scriptfilename" => "enable"
)
),
".py" =>
(
"python-fcgi" =>
(
"socket" => "/var/run/lighttpd/fastcgi.python.socket",
"bin-path" => "/usr/local/bin/python-fcgi",
"check-local" => "disable",
"max-procs" => 1,
)
)
)
/usr/local/bin/python-fcgi:
#!/usr/bin/python2
def myapp(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['python-fcgi: test\n']
if __name__ == '__main__':
from flup.server.fcgi import WSGIServer
WSGIServer(myapp).run()
The PHP (FastCGI) interpreter was build to run PHP files in this way; i.e. it runs one script, then forgets all the internal state for it, and start again.
Python was not build for this.
You could try to build a solution on top of flup; you would __import__
the requested script and call a "handleRequest" function in it or similar.
You can "reload" a module to update it: https://stackoverflow.com/questions/437589/how-do-i-unload-reload-a-python-module
But you cannot unload modules, so memory usage will grow: https://stackoverflow.com/questions/3105801/unload-a-module-in-python