sioscgi is an implementation of the Simple Common Gateway Interface (SCGI) protocol under the Sans-I/O philosophy.
SCGI is a protocol used for communication between HTTP servers and Web applications. Compared to CGI, SCGI is more efficient because it does not fork and execute a separate instance of the application for every request; instead, the application is launched ahead of time and receives multiple requests (either sequentially or concurrently) via socket connections. Compared to FastCGI, SCGI is a much simpler protocol as it uses a separate socket connection for each request, rather than including framing within a single connection to multiplex requests (a feature which is rarely used in FastCGI anyway due to the lack of per-request flow control).
See the Wikipedia and Python SCGI pages for more information.
Sans-I/O is a philosophy for developing protocol processing libraries in which the library does not do any I/O. Instead, a user of the library is responsible for transferring blocks of bytes between the socket or pipe and the protocol library, and for receiving application-level protocol items from and sending them to the library. This obviously makes a sans-I/O library a little more difficult to use, but comes with the advantage that the same library can be used with any I/O and concurrency mechanism: the same library should be usable in a single-request-at-a-time server, a process-per-request or thread-per-request blocking server, a server using select/poll and continuations, or a server using asyncio, Twisted, or any other asynchronous framework.
See SansIO for more information.
sioscgi’s releases are published on PyPI for installation through pip. You can
run pip install sioscgi.
For development, the source is available at GitLab and GitHub.
In general terms, as follows:
- Accept an SCGI connection from the HTTP server (or other SCGI client).
- Construct an
SCGIConnectionobject. - Receive the request from the SCGI client by repeating the following until a
RequestEndevent occurs:- Read some bytes from the connection and pass them to
SCGIConnection.receive_data. - Call
SCGIConnection.next_eventto receive high-level events corresponding to the received data (oneRequestHeaders, zero or moreRequestBodyevents, and oneRequestEnd).
- Read some bytes from the connection and pass them to
- Send the response to the SCGI client using
SCGIConnection.send, sending first aResponseHeadersevent, then zero or moreResponseBodyevents, then aResponseEndevent, and sending the returned bytes over the connection.
This being a sans-I/O library, how exactly you implement each step will depend
on what I/O and application framework you’re working under. For example, for a
thread-per-request or process-per-request server, you would likely do a
blocking receive from a normal function in step 3.1; in an asyncio-based server
you would instead await new data from a coroutine.
For detailed information about the classes and methods available, see the
module documentation provided in the docstrings by running import sioscgi
followed by help(sioscgi).