Utilities for gevent-based services: graceful shutdown, health checks, StatsD metrics, and testing helpers.
Project description
gevent-toolbelt
Small utilities for gevent that do not belong in gevent itself: cooperative services, graceful shutdown, optional StatsD health metrics, and test helpers.
Install
From PyPI (after you publish a release):
pip install gevent-toolbelt
With uv:
uv add gevent-toolbelt
Requirements
Python 3.10 or newer.
Table of contents
Configuration
GEVENT_MAX_BLOCKING_TIME
Default: 5
If the monitor thread is enabled, this is approximately how long (in seconds) the event loop may block before a warning is issued.
GEVENT_MONITOR_THREAD_ENABLE
Default: True
If true, the monitor thread is created the first time the hub is switched to.
STATSD_HOST
Default: 'localhost'
StatsD host for metrics when using the StatsD-backed health helpers.
STATSD_PORT
Default: 8125
StatsD port.
Usage
gevent_toolbelt.service.Service
import gevent
from gevent_toolbelt.service import Service
class MyService(Service):
def handle(self):
while not self.stop_event.is_set():
gevent.sleep()
my_service = MyService()
my_service.serve_forever()
gevent_toolbelt.service.ServiceFunc
import gevent
from gevent_toolbelt.service import ServiceFunc
def my_service_func(stop_event):
while not stop_event.is_set():
gevent.sleep()
my_service = ServiceFunc(my_service_func)
my_service.serve_forever()
gevent_toolbelt.service.ServiceGroup
import gevent
from gevent_toolbelt.service import ServiceFunc, ServiceGroup
def my_service_func(stop_event):
while not stop_event.is_set():
gevent.sleep()
my_service_group = ServiceGroup(
[
ServiceFunc(my_service_func),
ServiceFunc(my_service_func),
ServiceFunc(my_service_func),
]
)
my_service_group.serve_forever()
StatsD metrics (ServiceWithMetrics, ServiceFuncWithMetrics, ServiceGroupWithMetrics)
Same roles as Service, ServiceFunc, and ServiceGroup, but emit worker gauges over StatsD when the event loop reports blocking. See gevent_toolbelt.service.healthcheck.statsd.
Test helpers
gevent_toolbelt.test.joinall_gracefully joins greenlets and runs a sidecar that calls stop_func after a timeout.
import gevent
from gevent.event import Event
from gevent_toolbelt.test import joinall_gracefully
stop_event = Event()
def my_service_func(stop_event):
while not stop_event.is_set():
gevent.sleep()
joinall_gracefully(gevent.spawn(my_service_func, stop_event), timeout=5)
Graceful shutdown
from gevent_toolbelt.service import Service
from gevent_toolbelt.signals import install_signal_handler
my_service = Service(...)
install_signal_handler(my_service.stop)
my_service.serve_forever()
Development
Clone the repository, then install dependencies with uv (includes dev tools such as pytest and Ruff):
uv sync
Run the linter and formatter:
uv run ruff check gevent_toolbelt tests
uv run ruff format gevent_toolbelt tests
Run tests (pytest is started via gevent’s monkey entry point so socket patches in tests line up with StatsD and the hub):
uv run python -m gevent.monkey "$(uv run which pytest)"
Publishing to PyPI
- Bump the version in
gevent_toolbelt/__init__.py(constantVERSION;__version__follows it), then create and push an annotated tagvX.Y.Z(for examplev1.0.13). You can also use bump2version with.bumpversion.cfg. - Build and publish are handled by
.github/workflows/release.ymlwhen the tag is pushed: it builds withuv build --no-sources, smoke-tests the wheel and sdist, then runsuv publishusing PyPI Trusted Publishing (OIDC). On GitHub, create an environment namedpypi(optionally with required reviewers) and register that publisher on PyPI so uploads are approved the same way as in wsgiven.
Alternatively, build locally and upload with a PyPI API token:
uv build --no-sources
UV_PUBLISH_TOKEN=… uv publish
Configure the Homepage / Repository URLs in pyproject.toml if your GitHub organization or repository name differs from the placeholders.
License
MIT — see LICENSE.
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 Distribution
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 gevent_toolbelt-1.0.12.tar.gz.
File metadata
- Download URL: gevent_toolbelt-1.0.12.tar.gz
- Upload date:
- Size: 8.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6d264a99a3fdebaefefe3f5322b96bb091349274a6a5745bc92b6f2b1454bb4
|
|
| MD5 |
3ea1f137ba8844224376682eecc39fb3
|
|
| BLAKE2b-256 |
17b696c91f51a55c21a2dea943a27d9dea0f80184392d67554632ad0ab439a43
|
File details
Details for the file gevent_toolbelt-1.0.12-py3-none-any.whl.
File metadata
- Download URL: gevent_toolbelt-1.0.12-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fbffd609d79d9ff1a2504cc46c3693228794d9ad5e2809ce8b9f4b7773409bb
|
|
| MD5 |
9f1bed2d23085151bb62f2795c970bd3
|
|
| BLAKE2b-256 |
fc39d23249c3605975ceaa22c3de6d6d7f49cea8b174a350161571bdf8facce0
|