WSGI server implemented in Rust.
Project description
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
Non-blocking read/write using mio
Request parsing using httparse
pyo3-ffi based Python interface
Worker pool based on threadpool
PasteDeploy entry point
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
Install and activate a Python 3 (>= 3.10) virtualenv
Install maturin using pip:
$ 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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd63ee1f0aead4c440d92ecd06077f3112f93290e5c2ca36affc630d79bf5050
|
|
| MD5 |
9e8d7d88b552f9435dff37079910c636
|
|
| BLAKE2b-256 |
173657695d073fa7d0e3efcdea246843a16f8dc1470792f3d4e1e5f8414c4c04
|
File details
Details for the file pyruvate-1.6.0-cp314-cp314-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp314-cp314-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 5.6 MB
- Tags: CPython 3.14, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ba2bcc0a4d7325669bc561738e17e62f902dc0f1dcab0200a661086135f7fb1
|
|
| MD5 |
8493ef2945cff2f7d3fe4a355b87b76c
|
|
| BLAKE2b-256 |
df1bc40ff3724ee658e63ac43203ed3d66f1080ce63476edef92fc9fad17d4e3
|
File details
Details for the file pyruvate-1.6.0-cp314-cp314-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp314-cp314-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 548.9 kB
- Tags: CPython 3.14, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73af1182d55d681caba1524bc0df95755aa634a9750b8b4e924a40d96a731274
|
|
| MD5 |
5e9a3cfc178020fd7d904b73a5665dfc
|
|
| BLAKE2b-256 |
b86aa3149dcca6cb0dc556b0d6bc5b7c6d61e199973408dec0540db60f5b3a2d
|
File details
Details for the file pyruvate-1.6.0-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c36065340f4eb34ffa6fc2811dc06e76c2d038360b44e45f845cea5290e7fcb
|
|
| MD5 |
80c05ed3497c9b829e214e0455a3d777
|
|
| BLAKE2b-256 |
c151534ab3ff064cf77c097a121150546b560d128f2ff648b7a6539539ec104f
|
File details
Details for the file pyruvate-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 5.6 MB
- Tags: CPython 3.13, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f46932b619ecb3b663839a56fc8651d7a28f42a8d0467638fbab6f23f1f4f08a
|
|
| MD5 |
9b7e9993e3fd7fc75f629e76a4be43b0
|
|
| BLAKE2b-256 |
3b74e23346643610dabe1822d6e3f0b7fdbe149f5e137f9c09918d56d570f278
|
File details
Details for the file pyruvate-1.6.0-cp313-cp313-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp313-cp313-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 548.3 kB
- Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62833509c1a9cff1879c6b25c62265a41086b35270dbaa7d6edbe5b70b242609
|
|
| MD5 |
ea68098ecff03185600912f2f33c1618
|
|
| BLAKE2b-256 |
b57233c0c1e6c6990b0cd0a7b9e97bd6d8bab9e956b5cec06e3b74d78c2e8fc1
|
File details
Details for the file pyruvate-1.6.0-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3c8e196dc5560d660fbedb5548bf120af0e8a06f639f1b14d9a2e02c2b10eb3
|
|
| MD5 |
a8c41aee7f3b462ba18c6889a5abf282
|
|
| BLAKE2b-256 |
01b5269108f792ae0f3f0d3e18ab589e39401a5b592c32c4a6d0b3084d81416b
|
File details
Details for the file pyruvate-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 5.6 MB
- Tags: CPython 3.12, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93488c5ca9f9aebc594f418ec25c0b74a9c6fa997e451bedea2ea8123d307365
|
|
| MD5 |
a34a1cbf05a5d9d9226130eee6b148ee
|
|
| BLAKE2b-256 |
ec8e3216d032b3504a94a53c4d50b18144c996a47e78c3bc959549c8b841a702
|
File details
Details for the file pyruvate-1.6.0-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 548.9 kB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41f445ea4f414f24c5c935b80f6ba87144dbaed16f93a52f97207fe949246f82
|
|
| MD5 |
cb0b6b15aa04b774a431dd688eb36a0d
|
|
| BLAKE2b-256 |
03f1f9c60b27bde5c3838d35fe24e3db008a0238ab80bfba97f22790dafff653
|
File details
Details for the file pyruvate-1.6.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac29634f30434929ff23d48be919905abb4f49304b1b9780b4f782b8b2ae75ad
|
|
| MD5 |
a4d758c559cfbf1846c1414a471da7ac
|
|
| BLAKE2b-256 |
e44653305ffe6fbaa372335275594d3ab80e4865d6827f73c3a95a178767c081
|
File details
Details for the file pyruvate-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 5.6 MB
- Tags: CPython 3.11, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ead140dac3f0676c3a7d6b861ee268a305a1e2c9d92c17329bb482dabe77cfc4
|
|
| MD5 |
b44a620aa5081d3c4401e2c08f55c89b
|
|
| BLAKE2b-256 |
f874193c91d12f20a79c4c2e1c1847e26ac55976e222f7133d3f17575c190d93
|
File details
Details for the file pyruvate-1.6.0-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 546.4 kB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee5e4d961a6948dcb69bc3015fcdac3dd8bcec891ee0da0a177d56f877f90e6c
|
|
| MD5 |
6b4406f60366fc6aef5aa7905510f3c8
|
|
| BLAKE2b-256 |
4c4f8b08285dbc7483645ecbe70868b7c7f7636b0ccea669586d468fe86891d1
|
File details
Details for the file pyruvate-1.6.0-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32660d1b998c24c70742ae8c653e470a0b1180a83e55c81eac87fd6d5b67bdde
|
|
| MD5 |
6966f0acc8ec3efaac5e4ebfe42d757d
|
|
| BLAKE2b-256 |
321e0885acb3c24149fb0d4a7e1e27694e84aae0796296afa1f3b171bc430646
|
File details
Details for the file pyruvate-1.6.0-cp310-cp310-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp310-cp310-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 5.6 MB
- Tags: CPython 3.10, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d855c58f64ec3c9e726dbb203437ac8eae015bf35fb00095d15acbcb2db3863
|
|
| MD5 |
e2b63a1ae9b08a766dc7d075fd70974b
|
|
| BLAKE2b-256 |
5a3a9ad3b0bfe060e716eb361802e36683bfcc8a60de9499cb0a2e453787ecc8
|
File details
Details for the file pyruvate-1.6.0-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 546.8 kB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
365da23f1530379b7443f25a25acf8679527cc1af8d904b8c0483bc470ba9c57
|
|
| MD5 |
8cbf1c8f1edbaae0114c33b25283f0ac
|
|
| BLAKE2b-256 |
261beb378d8f5340257f8426160a5f7ac4eb9778484146de0bc3ce665855258e
|
File details
Details for the file pyruvate-1.6.0-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyruvate-1.6.0-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4df7c9e95f1cf5b007ee810793c3029e8f87b1a47d802a8bbf5a2247872b247
|
|
| MD5 |
fe6d3dca5709ea75d73a8049cc761232
|
|
| BLAKE2b-256 |
a31def4cb3fe40a1764f4d0b0661d205893559d346fe79e316457ac0495331c1
|