How to setup Python with Lighttpd and FastCGI (like PHP)

9,146

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

Share:
9,146

Related videos on Youtube

johndir
Author by

johndir

Updated on September 18, 2022

Comments

  • johndir
    johndir over 1 year

    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()
    
    • Admin
      Admin over 12 years
      Why not just use WSGI?
    • Admin
      Admin over 12 years
      Because then I would have to add every single script to Lighttpd's configuration (... "bin-path" => "/path/to/invdividual-script.py").
    • Admin
      Admin over 10 years
      +1 vote for wsgi - I suggest you at least a little googling for it.