Skip to main content

A fastcgi handler for Python's `socketserver` classes

Project description

fastcgi

FastCGI and HTTP handlers for Python's socketserver classes

FastCGI is a way for front-end servers to talk to back-end workers in a (somewhat) efficient and (somewhat) simple way. Although it's been around since 1996, it is not very widely appreciated, except in the PHP community, where it is very commonly used.

It can be a great approach for hosting Python scripts, avoiding the overhead of creating a new Python process for every request (as standard CGI would otherwise require) and without requiring large dependencies, complex C projects, or fiddly deployments. fastcgi has no dependencies other than fastcore.

There's no new frameworks or concepts to learn. Just call send to send anything you like back to the client, read the parameters from params, and the input from the client from stdin.

fastcgi requires a front-end web server. If you don't already have one set up, we recommend Caddy. To forward all requests to example.com to a fastcgi server listening on port 1234 create a file called Caddyfile with the following contents, and then caddy run:

example.com
reverse_proxy localhost:1234 { transport fastcgi }

This library also provides an HTTP handler that can be used in an identical way, except remove { transport fastcgi } from the above Caddyfile example. Python's standard library already includes an HTTP handler (in http.server), however the documentation warns that that module should not be used in production code. The HTTP handler provided here is trimmed down to a minimal implementation (just 40 lines of code) so that it can easily be studied and extended. It uses the same basic API as Python's other socketserver classes (and the same as FcgiHandler here) so there's fewer new concepts to understand.

Install

pip install fastcgi or conda install -c fastai fastcgi

How to use

See the full docs pages for each class for details. Quick overviews of each approach are shown below.

fastcgi decorator

Using the fastcgi decorator you can use CGI scripts with minimal changes. Just add the decorator above a function used for CGI, and it converts that script automatically into a FastCGI server, e.g if you save this as server.py:

@fastcgi()
def hello():
    query = os.environ["QUERY_STRING"]
    content = sys.stdin.read()
    sys.stdout.write(f"Content-type: text/html\r\n\r\n<html>{content} ; ")
    sys.stdout.write(f"{query}</html>\r\n")

...then if you run python server.py it will make a unix socket available as fcgi.sock in the current directory.

FcgiHandler

FcgiHandler is used in much the same way as Python's BaseRequestHandler. Here's an example:

class TestHandler(FcgiHandler):
    def handle(self):
        print('query:', self.environ['QUERY_STRING'])
        print('content type:', self.environ['HTTP_CONTENT_TYPE'])
        print('stdin:', self['stdin'].read())
        self['stdout'].write(b"Content-type: text/html\r\n\r\n<html>foobar</html>\r\n")

You can run this using any of Python's socketserver classes, e.g to listen on localhost port 1234:

with TCPServer(('localhost',1234), TestHandler) as srv:
    srv.handle_request()

See the API docs for FcgiHandler for an end-to-end example.

You can also create a forking or threading server by using Python's mixins or predefined classes.

In your handle method, you can use the stdin, stdout, and stderr attributes, which each contain a BytesIO stream.

MinimalHTTPHandler

fastcgi also comes with the MinimalHTTPHandler class, which provides very similar functionality to FcgiHandler, but using the HTTP protocol instead of the FastCGI protocol. Here's an example:

class _TestHandler(MinimalHTTPHandler):
    def handle(self):
        print(f'Command/path/version: {self.command} {self.path} {self.request_version}')
        print(self.headers)
        self.send_response(200)
        self.send_header("Content-Type", "text/plain")
        self.send_header('Content-Length', '2')
        self.end_headers()
        self.wfile.write(b'ok')

You can run it with a socketserver server in the same way shown above for FcgiHandler.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastcgi-0.0.3.tar.gz (13.0 kB view details)

Uploaded Source

Built Distribution

fastcgi-0.0.3-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file fastcgi-0.0.3.tar.gz.

File metadata

  • Download URL: fastcgi-0.0.3.tar.gz
  • Upload date:
  • Size: 13.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.6.0.post20200925 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.7.7

File hashes

Hashes for fastcgi-0.0.3.tar.gz
Algorithm Hash digest
SHA256 6c41a8c8ab4ea7f5cd30010df8ee9aa14b5a0ba1bf683e29f343e1a61358453f
MD5 ec4fdfb671c9ae25505771f3a4a915ff
BLAKE2b-256 8b67a75ce9b74797824ef54c5782b292168dcd27021b41c699f5939375752405

See more details on using hashes here.

File details

Details for the file fastcgi-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: fastcgi-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.6.0.post20200925 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.7.7

File hashes

Hashes for fastcgi-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 f749fe88cfebc1bdcb34baa020c4eec22e60b272ec616c262d7e7f85c12a07ee
MD5 f781c10b5230daa52fce7aaa6a0f2710
BLAKE2b-256 52f71147d46ebbbbae09610df9af029dfc92ab06112dc5fb7999c3b44a13b266

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page