Skip to main content

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.

Release files for fastcgi 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastcgi 0.0.3
File Size Uploaded
fastcgi-0.0.3.tar.gz 13.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastcgi 0.0.3
File Interpreter ABI Platform
fastcgi-0.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 25.4 kB

Release files / fastcgi-0.0.3.tar.gz

Download URL fastcgi-0.0.3.tar.gz
Size 13.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6c41a8c8ab4ea7f5cd30010df8ee9aa14b5a0ba1bf683e29f343e1a61358453f
BLAKE2b-256 checksum
How to use checksums
8b67a75ce9b74797824ef54c5782b292168dcd27021b41c699f5939375752405
Upload date
Uploaded using Trusted Publishing?
What is 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

Release files / fastcgi-0.0.3-py3-none-any.whl

Download URL fastcgi-0.0.3-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f749fe88cfebc1bdcb34baa020c4eec22e60b272ec616c262d7e7f85c12a07ee
BLAKE2b-256 checksum
How to use checksums
52f71147d46ebbbbae09610df9af029dfc92ab06112dc5fb7999c3b44a13b266
Upload date
Uploaded using Trusted Publishing?
What is 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

Release history Release notifications | RSS feed

This release

0.0.3 This release

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page