python / flup and fastcgi

In order to put up a python3 application on apache with mod_fastcgi I turned to the flup fastcgi-to-wsgi adapter which is also used by the django project for fastcgi deployment.

## flup is a pure-python wsgi gateway/server that works with fastcgi, simple cgi aka scgi, and apache jserv protocol aka ajp; used as a fastcgi-to-wsgi server adapter it's used to create wsgi applications in python that can be called via the fastcgi protocol; when fastcgi starts such an application the flup wsgi server starts up and waits for a fastcgi connection over a socket

! using ubuntu 12.04, python 3.3.5, apache 2.2.22, mod_fastcgi 2.4.7

! links

! apparently there is no longer any commonly-used python fastcgi library i.e. that offers a native api; instead there are only fastcgi-to-wsgi server adapters such as flup by alan saddi; the flup package contains wsgi adapters for fastcgi as well as for scgi and ajp

! mod_fastcgi with flup offers many of the same advantages as mod_wsgi in daemon mode e.g. flexible process architecture and less disruptive restarts

## installed flup for python3 package from local using pip

! UPDATE: flup now seems to be maintained again and is on pypi; the flup package is 1.0.2 for python2; the flup.1.0.3.devyyyymmmdd version is for python3
! flup is in the ubuntu repo as python-flup for python2; it also installs python-webpy and python-cheetah by default

root@dev:# pip install flup==1.0.3.dev20161029
Collecting flup==1.0.3.dev20161029
  Downloading flup-1.0.3.dev20161029-py3-none-any.whl (74kB)
    100% |...| 81kB 906kB/s 
Installing collected packages: flup
Successfully installed flup-1.0.3.dev20161029

! files/directories

## for apache mpm worker i.e. with multithreading use flup.server.fcgi.WSGIServer which has wsgi.multithread = True and wsgi.multiprocess = False

! for apache mpm prefork use flup.server.fcgi_fork.WSGIServer

! needed to modify flup/server/ because it calls import thread which has been renamed to _thread in python3; deleted its pyc file in __pycache__

## unlike mod_wsgi wsgi scripts flup wsgi scripts are normal python scripts run in the usual way i.e. they must be permissioned executable and a #! line is used to specify the interpreter; a script must define a wsgi callable and pass its name to the flup server; flup adds the standard wsgi envvars to the environment passed to the application

! typical hello python3 wsgi script with #! line and module-level code added to use flup with mod_fastcgi


from html import escape

def application(environ, start_response):

    envvar = ['%s=%s' % (key, value) for key, value in sorted(environ.items())]

    body = ('<html><body><h2>h€lló wörld (python3 fcgi)</h2><pre>' + escape('\n'.join(envvar)) + '</pre></body></html>').encode()
    status = '200 OK'
    headers = [('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', str(len(body)))]
    start_response(status, headers)

    return [body]

if __name__ == '__main__':
    from flup.server.fcgi import WSGIServer

! envvar output

...(usual cgi envvars)...
wsgi.errors=<flup.server.fcgi_base.OutputStream object at 0x7f89f63798d0>
wsgi.input=<flup.server.fcgi_base.InputStream object at 0x7f89f6379850>
wsgi.version=(1, 0)

! pstree with mpm worker

     │         ├─apache2───hello.fcgi───5*[{hello.fcgi}]   # if #!/usr/bin/env python3 is used then the application in pstree appears as python3
     │         └─2*[apache2───26*[{apache2}]]

     │         ├─apache2─┬─hello.fcgi───5*[{hello.fcgi}]
     │         │         └─hello2.fcgi───5*[{hello2.fcgi}]
     │         └─2*[apache2───26*[{apache2}]]

Currently unrated





RSS / Atom