Skip to main content

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

  1. Bump the version in gevent_toolbelt/__init__.py (constant VERSION; __version__ follows it), then create and push an annotated tag vX.Y.Z (for example v1.0.13). You can also use bump2version with .bumpversion.cfg.
  2. Build and publish are handled by .github/workflows/release.yml when the tag is pushed: it builds with uv build --no-sources, smoke-tests the wheel and sdist, then runs uv publish using PyPI Trusted Publishing (OIDC). On GitHub, create an environment named pypi (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


Download files

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

Source Distribution

gevent_toolbelt-1.0.12.tar.gz (8.5 kB view details)

Uploaded Source

Built Distribution

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

gevent_toolbelt-1.0.12-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

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

Hashes for gevent_toolbelt-1.0.12.tar.gz
Algorithm Hash digest
SHA256 c6d264a99a3fdebaefefe3f5322b96bb091349274a6a5745bc92b6f2b1454bb4
MD5 3ea1f137ba8844224376682eecc39fb3
BLAKE2b-256 17b696c91f51a55c21a2dea943a27d9dea0f80184392d67554632ad0ab439a43

See more details on using hashes here.

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

Hashes for gevent_toolbelt-1.0.12-py3-none-any.whl
Algorithm Hash digest
SHA256 7fbffd609d79d9ff1a2504cc46c3693228794d9ad5e2809ce8b9f4b7773409bb
MD5 9f1bed2d23085151bb62f2795c970bd3
BLAKE2b-256 fc39d23249c3605975ceaa22c3de6d6d7f49cea8b174a350161571bdf8facce0

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