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.0.tar.gz (36.5 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.0-cp314-cp314-musllinux_1_2_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

pyruvate-1.6.0-cp314-cp314-manylinux_2_28_x86_64.whl (548.9 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

pyruvate-1.6.0-cp314-cp314-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

pyruvate-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

pyruvate-1.6.0-cp313-cp313-manylinux_2_28_x86_64.whl (548.3 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

pyruvate-1.6.0-cp313-cp313-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pyruvate-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

pyruvate-1.6.0-cp312-cp312-manylinux_2_28_x86_64.whl (548.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

pyruvate-1.6.0-cp312-cp312-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pyruvate-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

pyruvate-1.6.0-cp311-cp311-manylinux_2_28_x86_64.whl (546.4 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

pyruvate-1.6.0-cp311-cp311-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pyruvate-1.6.0-cp310-cp310-musllinux_1_2_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

pyruvate-1.6.0-cp310-cp310-manylinux_2_28_x86_64.whl (546.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

pyruvate-1.6.0-cp310-cp310-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

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

File metadata

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

File hashes

Hashes for pyruvate-1.6.0.tar.gz
Algorithm Hash digest
SHA256 fd63ee1f0aead4c440d92ecd06077f3112f93290e5c2ca36affc630d79bf5050
MD5 9e8d7d88b552f9435dff37079910c636
BLAKE2b-256 173657695d073fa7d0e3efcdea246843a16f8dc1470792f3d4e1e5f8414c4c04

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 2ba2bcc0a4d7325669bc561738e17e62f902dc0f1dcab0200a661086135f7fb1
MD5 8493ef2945cff2f7d3fe4a355b87b76c
BLAKE2b-256 df1bc40ff3724ee658e63ac43203ed3d66f1080ce63476edef92fc9fad17d4e3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 73af1182d55d681caba1524bc0df95755aa634a9750b8b4e924a40d96a731274
MD5 5e9a3cfc178020fd7d904b73a5665dfc
BLAKE2b-256 b86aa3149dcca6cb0dc556b0d6bc5b7c6d61e199973408dec0540db60f5b3a2d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8c36065340f4eb34ffa6fc2811dc06e76c2d038360b44e45f845cea5290e7fcb
MD5 80c05ed3497c9b829e214e0455a3d777
BLAKE2b-256 c151534ab3ff064cf77c097a121150546b560d128f2ff648b7a6539539ec104f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f46932b619ecb3b663839a56fc8651d7a28f42a8d0467638fbab6f23f1f4f08a
MD5 9b7e9993e3fd7fc75f629e76a4be43b0
BLAKE2b-256 3b74e23346643610dabe1822d6e3f0b7fdbe149f5e137f9c09918d56d570f278

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 62833509c1a9cff1879c6b25c62265a41086b35270dbaa7d6edbe5b70b242609
MD5 ea68098ecff03185600912f2f33c1618
BLAKE2b-256 b57233c0c1e6c6990b0cd0a7b9e97bd6d8bab9e956b5cec06e3b74d78c2e8fc1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d3c8e196dc5560d660fbedb5548bf120af0e8a06f639f1b14d9a2e02c2b10eb3
MD5 a8c41aee7f3b462ba18c6889a5abf282
BLAKE2b-256 01b5269108f792ae0f3f0d3e18ab589e39401a5b592c32c4a6d0b3084d81416b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 93488c5ca9f9aebc594f418ec25c0b74a9c6fa997e451bedea2ea8123d307365
MD5 a34a1cbf05a5d9d9226130eee6b148ee
BLAKE2b-256 ec8e3216d032b3504a94a53c4d50b18144c996a47e78c3bc959549c8b841a702

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 41f445ea4f414f24c5c935b80f6ba87144dbaed16f93a52f97207fe949246f82
MD5 cb0b6b15aa04b774a431dd688eb36a0d
BLAKE2b-256 03f1f9c60b27bde5c3838d35fe24e3db008a0238ab80bfba97f22790dafff653

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ac29634f30434929ff23d48be919905abb4f49304b1b9780b4f782b8b2ae75ad
MD5 a4d758c559cfbf1846c1414a471da7ac
BLAKE2b-256 e44653305ffe6fbaa372335275594d3ab80e4865d6827f73c3a95a178767c081

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ead140dac3f0676c3a7d6b861ee268a305a1e2c9d92c17329bb482dabe77cfc4
MD5 b44a620aa5081d3c4401e2c08f55c89b
BLAKE2b-256 f874193c91d12f20a79c4c2e1c1847e26ac55976e222f7133d3f17575c190d93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ee5e4d961a6948dcb69bc3015fcdac3dd8bcec891ee0da0a177d56f877f90e6c
MD5 6b4406f60366fc6aef5aa7905510f3c8
BLAKE2b-256 4c4f8b08285dbc7483645ecbe70868b7c7f7636b0ccea669586d468fe86891d1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 32660d1b998c24c70742ae8c653e470a0b1180a83e55c81eac87fd6d5b67bdde
MD5 6966f0acc8ec3efaac5e4ebfe42d757d
BLAKE2b-256 321e0885acb3c24149fb0d4a7e1e27694e84aae0796296afa1f3b171bc430646

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 3d855c58f64ec3c9e726dbb203437ac8eae015bf35fb00095d15acbcb2db3863
MD5 e2b63a1ae9b08a766dc7d075fd70974b
BLAKE2b-256 5a3a9ad3b0bfe060e716eb361802e36683bfcc8a60de9499cb0a2e453787ecc8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 365da23f1530379b7443f25a25acf8679527cc1af8d904b8c0483bc470ba9c57
MD5 8cbf1c8f1edbaae0114c33b25283f0ac
BLAKE2b-256 261beb378d8f5340257f8426160a5f7ac4eb9778484146de0bc3ce665855258e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyruvate-1.6.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e4df7c9e95f1cf5b007ee810793c3029e8f87b1a47d802a8bbf5a2247872b247
MD5 fe6d3dca5709ea75d73a8049cc761232
BLAKE2b-256 a31def4cb3fe40a1764f4d0b0661d205893559d346fe79e316457ac0495331c1

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