Skip to main content

WSGI server implemented in Rust.

Project description

https://gitlab.com/tschorr/pyruvate/badges/main/pipeline.svg https://codecov.io/gl/tschorr/pyruvate/branch/main/graph/badge.svg http://img.shields.io/pypi/v/pyruvate.svg

Pyruvate is a fast, multithreaded WSGI server implemented in Rust. It is implementing a pre-fork worker model, making it a good choice for applications that are not completely thread safe or maintain per thread objects that are expensive to create (e.g. pooled database connections).

Features

Installation

If you are on Linux and use a recent Python version,

$ pip install pyruvate

is probably all you need to do.

Binary Packages

manylinux_2_28 and musllinux_1_2 wheels are available for the x86_64 architecture and active Python 3 versions (currently 3.10-3.14).

Source Installation

On macOS or if for any other reason you want to install the source tarball (e.g. using pip install –no-binary) you will need to install Rust first. Then you will need to switch to Rust Nightly:

$ rustup install nightly
$ rustup default nightly

Development Installation

  • Install Rust

  • Install Rust Nightly Toolchain and make it the default:

$ rustup install nightly
$ rustup default nightly
$ pip install maturin
  • Clone Pyruvate with git and cd into your copy:

$ git clone https://gitlab.com/tschorr/pyruvate.git
$ cd pyruvate
  • Install Pyruvate as editable:

$ maturin develop

Using Pyruvate in your WSGI application

From Python using a TCP port

A hello world WSGI application using Pyruvate listening on 127.0.0.1:7878 and using 2 worker threads looks like this:

import pyruvate

def application(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers, None)
    return [b"Hello world!\n"]

pyruvate.serve(application, "127.0.0.1:7878", 2)

From Python using a Unix socket

A hello world WSGI application using Pyruvate listening on unix:/tmp/pyruvate.socket and using 2 worker threads looks like this:

import pyruvate

def application(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers, None)
    return [b"Hello world!\n"]

pyruvate.serve(application, "/tmp/pyruvate.socket", 2)

Using PasteDeploy

Again listening on 127.0.0.1:7878 and using 2 worker threads:

[server:main]
use = egg:pyruvate#main
socket = 127.0.0.1:7878
workers = 2

Configuration Options

socket

Required: The TCP socket Pyruvate should bind to. Pyruvate also supports systemd socket activation If you specify None as the socket value, Pyruvate will try to acquire a socket bound by systemd.

workers

Required: Number of worker threads to use.

async_logging

Optional: Log asynchronously using a dedicated thread. Defaults to True.

chunked_transfer

Optional: Whether to use chunked transfer encoding if no Content-Length header is present. Defaults to False.

keepalive_timeout

Optional: Specify a timeout in integer seconds for keepalive connection. The persistent connection will be closed after the timeout expires. Defaults to 60 seconds.

max_number_headers

Optional: Maximum number of request headers that will be parsed. If a request contains more headers than configured, request processing will stop with an error indicating an incomplete request. The default is 32 headers

max_reuse_count

Optional: Specify how often to reuse an existing connection. Setting this parameter to 0 will effectively disable keep-alive connections. This is the default.

qmon_warn_threshold

Optional: Warning threshold for the number of requests in the request queue. A warning will be logged if the number of queued requests reaches this value. The value must be a positive integer. The default is None which disables the queue monitor.

send_timeout

Optional: Time to wait for a client connection to become available for writing after EAGAIN, in seconds. Connections that do not receive data within this time are closed. The value must be a positive integer. The default is 60 seconds.

Logging

Pyruvate uses the standard Python logging facility. The logger name is pyruvate. See the Python documentation (logging, logging.config) for configuration options.

Example Configurations

Django

After installing Pyruvate in your Django virtualenv, create or modify your wsgi.py file (one worker listening on 127.0.0.1:8000):

import os
import pyruvate

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_django_application.settings")

application = get_wsgi_application()

pyruvate.serve(application, "127.0.0.1:8000", 1)

You can now start Django + Pyruvate with:

$ python -m your_django_application.wsgi

Override settings by using the DJANGO_SETTINGS_MODULE environment variable when appropriate. Tested with Django 5.2.x.

MapProxy

First create a basic WSGI configuration following the MapProxy deployment documentation. Then modify config.py so it is using Pyruvate (2 workers listening on 127.0.0.1:8005):

import os.path
import pyruvate

from mapproxy.wsgiapp import make_wsgi_app
application = make_wsgi_app(r'/path/to/mapproxy/mapproxy.yaml')

pyruvate.serve(application, "127.0.0.1:8005", 2)

Start from your virtualenv:

$ python config.py

Last tested with Mapproxy 5.1.x.

Plone

Install Plone in whatever fashion you prefer (Cookieplone, pip, zc.buildout). Then change the server section in your zope.ini file:

[server:main]
use = egg:pyruvate#main
socket = localhost:7878
workers = 2

Modify the socket and number of workers to fit your needs. For buildout users there is a minimal buildout example configuration for Plone 6.1 in the examples directory of the package.

Tested with Plone 6.1.x, 6.0.x.

Pyramid

Install Pyruvate in your Pyramid virtualenv using pip:

$ pip install pyruvate

Modify the server section in your .ini file to use Pyruvate’s PasteDeploy entry point (listening on 127.0.0.1:7878 and using 5 workers):

[server:main]
use = egg:pyruvate#main
socket = 127.0.0.1:7878
workers = 5

Start your application as usual using pserve:

$ pserve path/to/your/configfile.ini

Tested with Pyramid 2.0, 1.10.x.

Radicale

You can find an example configuration for Radicale in the examples directory of the package. Tested with Radicale 3.5.x.

Nginx settings

Like other WSGI servers Pyruvate should be used behind a reverse proxy, e.g. Nginx:

...
location / {
    proxy_pass http://localhost:7878;
    ...
}
...

Nginx doesn’t use keepalive connections by default so you will need to modify your configuration if you want persistent connections.

Project details


Release history Release notifications | RSS feed

Download files

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

Source Distribution

pyruvate-1.6.1.tar.gz (19.6 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyruvate-1.6.1-cp314-cp314-musllinux_1_2_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

pyruvate-1.6.1-cp314-cp314-manylinux_2_28_x86_64.whl (518.6 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

pyruvate-1.6.1-cp314-cp314-macosx_11_0_arm64.whl (905.4 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

pyruvate-1.6.1-cp313-cp313-musllinux_1_2_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

pyruvate-1.6.1-cp313-cp313-manylinux_2_28_x86_64.whl (518.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

pyruvate-1.6.1-cp313-cp313-macosx_11_0_arm64.whl (906.2 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pyruvate-1.6.1-cp312-cp312-musllinux_1_2_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

pyruvate-1.6.1-cp312-cp312-manylinux_2_28_x86_64.whl (518.5 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

pyruvate-1.6.1-cp312-cp312-macosx_11_0_arm64.whl (907.2 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pyruvate-1.6.1-cp311-cp311-musllinux_1_2_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

pyruvate-1.6.1-cp311-cp311-manylinux_2_28_x86_64.whl (520.1 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

pyruvate-1.6.1-cp311-cp311-macosx_11_0_arm64.whl (911.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pyruvate-1.6.1-cp310-cp310-musllinux_1_2_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

pyruvate-1.6.1-cp310-cp310-manylinux_2_28_x86_64.whl (519.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

pyruvate-1.6.1-cp310-cp310-macosx_11_0_arm64.whl (913.4 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file pyruvate-1.6.1.tar.gz.

File metadata

  • Download URL: pyruvate-1.6.1.tar.gz
  • Upload date:
  • Size: 19.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for pyruvate-1.6.1.tar.gz
Algorithm Hash digest
SHA256 9d482c6e2388c4c4b3233e7a00fc4213933dd7d36d7e75e4c4d01005b54517de
MD5 fc7d827c12aca906c978751594361b6d
BLAKE2b-256 30269dd30f8b188bd4f01b2e7df4d82b24bb29714e8934e5e4ac464556efe150

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp314-cp314-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 5d8aaaa495bd1ea8ba908506d8cb80b2d83b8be6a97478b1ad757af5a0df4921
MD5 7d5847224107bbab1c9220457a37fa7a
BLAKE2b-256 ab306da4afe4d9ee523616814e3f1013dab17eb311fb13197aa3fd16012874f2

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f4e25e837b9c5f25dfb3412941b96dd028646e14a0ab78ea12953826b87e3ba3
MD5 41c23fc141189df18da16b8a0eb41e4c
BLAKE2b-256 e30c22ce4a9f68fd21d7b1464bfc8c6fc5c5f4dfb0bb35fede747d07c279e1a8

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dc712733fe7279263cd01d808a54346a9a291e6f8e8a3523e02b4072a4684ad9
MD5 d5b14b1f5027b71e25a3f33e56c711b2
BLAKE2b-256 e73d55373999e031e24fc1ccfc7240018938e790b5dfd3e8aee3bb56aeefb5a0

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e298262fd0bc00d814180ddb0a2bdbd5caebca3cce53ad012397e650da2217eb
MD5 f4f03d67573069f24c0a7963a0ef7702
BLAKE2b-256 488a0054dcbfd1ab4f3e24d62dfb37a1b6bc485da42600ab21cd6b5975940bbc

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0ff8d33536880be6822deeeb216e0855d9db5135fd90f546867d834dd31c908f
MD5 459264dcf608c934b6d7c7581a0a26cb
BLAKE2b-256 21c465add31314b809fae19f45a3d41ec72716cea09114916b1614b2fc3d582d

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4fe37ae64a1e75c689ffbe8aa0b81c28dc3406d7f5a82666f9358f8e214ff0a2
MD5 3aa304923679bd9162969b30d3645632
BLAKE2b-256 ca3b788d622411d19538ac9f5ecef89590e61f160e90c5ebc9905946007788cd

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 53a16cdd6463f3098b0e3c053d28f498265e419c34cf0ea95eeae4e633ffd87e
MD5 6d220df2d4847383e7aeae288cd04ef2
BLAKE2b-256 c6edcd4a05a1bc0788b9b6506891f39d332e23f3e134e44b0539149bd16b8481

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1be4f8547b4005659a53392313b870ca00d1155ce384a7d80ebf9fdfd4cb32f9
MD5 8e4f824e7cf874a41067f775d91a65e6
BLAKE2b-256 b851257b5370df7005f93931ab72e559f66be6c70acba0a7296a89c14d9211dd

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 350ed8865a4de1270f966c2427cce6f5fc699affa91d472ccb63b0d126e89f98
MD5 597093468c731e00cf06c7545ca90692
BLAKE2b-256 d1bb06893aae96d4eae41a360dbd2aaddde0895769502edda8d8572fd0898dec

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8015364168c34c713abb6d8f17127117bbe8c5e0aab85a1c5166951bd707cef1
MD5 c07a755608c6f7e9b6dabd962a4d8d31
BLAKE2b-256 626a5e0f5f978fce14182079e179cc1370983d2af9640f8d88c5f64b3e64a1a9

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 709e85656dfb11ab7c260e4f367fb4d34820471f0f41873304199f6565a3741f
MD5 e2814e57c801f23bdcafe914fefa22aa
BLAKE2b-256 ff6151ad05a72252b9f17681885db4a37e17483b08577ec993da71b88032b231

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a824cc1340ac36417d92a18bacb06255149a5cb7848c29e1dab4c612f7a8b16e
MD5 6abcef56c82e4ada327eeeed77e00556
BLAKE2b-256 09f9784ab1b79b2461cbeb1ee97a2412a2c047e26fcc3d50de339e07fb10d5ed

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6ce5f5907f6e084dc464e3ff90941da6b38ee8c7348af8d5568f1685a8017458
MD5 0e04ab33bea5d703eee5ed33142ddaf7
BLAKE2b-256 8413c3219a10acff0d1c6a5f6e4048929d6faa8070ff9db05ca6fb83ff634d54

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ef1e29f875f15d7a3456c648084ed692398ada19729788cbf7d22a0813fac4cb
MD5 9fcdb2353396ea0c956619b924293a1c
BLAKE2b-256 87e81feefb485fbe4af7448f3e072fc9226881fa31039506a9a2eec19947e73d

See more details on using hashes here.

File details

Details for the file pyruvate-1.6.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyruvate-1.6.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 51ea958e30ca997dbdeca4b5e079983ce9e87f8145f599f3a98e74d550cd8b93
MD5 bd7c83805fe88a6ff0a61004116b255e
BLAKE2b-256 ded5696250644ced1c7c830bbe5b3c46d3dba7ae569da644761fbe47020ddd01

See more details on using hashes here.

Supported by

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