Gevent

raw JSON →
25.9.1 verified Tue May 12 auth: no python install: verified quickstart: stale

Gevent is a coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API on top of the libev or libuv event loop. It enables writing concurrent code that looks sequential, primarily for I/O-bound tasks. The current version is 25.9.1, and it follows a CalVer (YY.0M.Micro) release cadence, aiming for at least monthly releases if changes are present in master.

pip install gevent
error ModuleNotFoundError: No module named 'gevent'
cause The `gevent` library is not installed in the current Python environment or is not accessible in the `PYTHONPATH`. This can also occur if `gevent` was installed for a different Python version than the one currently in use.
fix
Install gevent using pip: pip install gevent. Ensure you are in the correct virtual environment if you are using one, and that the Python interpreter running your code is the one for which gevent was installed.
error gevent.hub.LoopExit: This operation would block forever
cause This error occurs when a greenlet attempts a synchronous, blocking I/O operation (or a CPU-intensive task) that `gevent` cannot make cooperative, and there are no other active greenlets to switch to, effectively halting the event loop. It can also be caused by greenlets deadlocking on a lock or incorrectly using `gevent` objects with native thread affinity from different threads.
fix
Identify and replace the blocking operation with its gevent-cooperative equivalent (e.g., using gevent.socket instead of socket), offload CPU-bound tasks to a thread pool (gevent.threadpool) or a separate process, or ensure that gevent.monkey.patch_all() is called at the very beginning of the application to patch standard library blocking calls.
error ERROR: Command errored out with exit status 1: command: python setup.py egg_info
cause This generic error during `gevent` installation, often accompanied by messages about `gcc` or missing headers, indicates a failure to compile `gevent` from source. This typically happens when essential build tools (like `gcc`), Python development headers (`python-devel` or `python3-devel`), or `libevent-dev` are missing from the system. It can also be due to an outdated `setuptools` or `pip` version, or incompatibility with a specific Python or `greenlet` version.
fix
Install the required build dependencies for your operating system (e.g., sudo apt-get install build-essential python3-dev libevent-dev on Debian/Ubuntu, or similar for other distros). Upgrade pip and setuptools to their latest versions (pip install --upgrade pip setuptools). Ensure your Python version is compatible with the gevent version you are trying to install.
error ModuleNotFoundError: No module named 'gevent.wsgi'
cause The `gevent.wsgi` module has been deprecated and was removed in `gevent` version 1.3.
fix
Replace from gevent.wsgi import WSGIServer with from gevent.pywsgi import WSGIServer. The gevent.pywsgi module is the modern replacement for WSGI server functionality.
error Monkey patching not being set in subprocesses
cause This occurs when `gevent.monkey.patch_all()` is not applied in subprocesses or is applied too late in their execution, meaning standard library functions within those subprocesses remain unpatched and blocking. This is particularly problematic in scenarios like `pytest-xdist` or custom multiprocessing setups.
fix
Ensure from gevent import monkey; monkey.patch_all() is executed as early as possible in the lifecycle of *every* process where cooperative concurrency is desired, including subprocesses. For frameworks like Gunicorn, this is often handled automatically, but for custom subprocesses, you might need to explicitly call it within the subprocess's entry point.
gotcha Monkey patching (`gevent.monkey.patch_all()`) must be performed as early as possible in your application's lifecycle, ideally as the very first lines of code in your main module, on the main thread, and before any other modules that might use blocking I/O are imported. Delaying this can lead to unpredictable behavior, conflicts, or errors because parts of the standard library might already be imported in their unpatched, blocking versions.
fix Place `from gevent import monkey; monkey.patch_all()` at the absolute top of your main script or entry point, even before other imports. If using a framework like Gunicorn with `gevent` workers, check its documentation as it might handle patching for you.
gotcha Using Python's `multiprocessing` module in conjunction with `gevent.monkey.patch_all()` (especially if `socket` is patched, which is the default) can be highly problematic and lead to subtle, hard-to-debug issues, as `multiprocessing` relies on standard (unpatched) OS-level threading/socket behavior.
fix If you need multiprocessing with Gevent, consider using `gipc` (gevent-cooperative child processes and IPC), which is designed to integrate safely with Gevent. Alternatively, explicitly disable `socket` patching if `multiprocessing` is used.
gotcha Gevent is designed to make I/O-bound operations (like network requests, disk I/O) concurrent by yielding control during blocking calls. It does not provide true parallelism for CPU-bound tasks within a single process due to Python's Global Interpreter Lock (GIL). Using Gevent for CPU-intensive workloads will not improve performance and can actually make your application slower by adding cooperative multitasking overhead.
fix For CPU-bound tasks, use `multiprocessing` or a task queue system with multiple worker processes. Only apply Gevent where your application's bottleneck is I/O waiting time.
deprecated The magic proxy object `gevent.signal`, which served as both a deprecated alias for `gevent.signal_handler` and the `gevent.signal` module, was removed because it caused confusion for users and static analysis tools.
fix Use `gevent.signal_handler` directly when handling signals.
breaking In Gevent v25, changes in import ordering might break projects relying on `gevent.monkey` if `concurrent.futures` is imported before user-defined code. This is because `concurrent.futures` can hold references to unpatched threading threads that cannot be patched by Gevent later.
fix Ensure `gevent.monkey.patch_all()` is called at the absolute earliest point in your application, before any other imports, especially those that might implicitly or explicitly import `concurrent.futures` or related threading modules. You may need to restructure imports if this issue arises.
gotcha Gevent does not support CPython's experimental free-threading mode (introduced in Python 3.13 and 3.14). If used in such an interpreter, Gevent (and its underlying `greenlet` library) will cause the GIL to be re-enabled. Attempting to use Gevent in free-threading mode is not recommended and may lead to resource leaks.
fix Avoid using Gevent with CPython interpreters configured for experimental free-threading mode. Ensure your environment uses a standard CPython build if you rely on Gevent.
breaking Gevent, like many Python packages with C extensions, requires a C compiler (e.g., gcc) to be present in the environment during installation. Minimal Docker images (e.g., `python:X.Y-slim` or `alpine`) often do not include build tools by default, leading to installation failures.
fix Ensure a C compiler and other necessary build tools are installed in your environment before attempting to install gevent. For Debian-based systems (like `python:*-slim`), you can install them using `apt-get update && apt-get install -y build-essential`. For Alpine, use `apk add gcc musl-dev`.
breaking The Python 'requests' library is not installed in the environment. This will cause a `ModuleNotFoundError` when the application attempts to import it.
fix Install the 'requests' library using pip: `pip install requests`. Ensure all necessary dependencies are listed in a `requirements.txt` file and installed in the build process.
python os / libc status wheel install import disk
3.10 alpine (musl) sdist - 0.22s 34.3M
3.10 alpine (musl) - - 0.26s 34.3M
3.10 slim (glibc) wheel 3.0s 0.17s 32M
3.10 slim (glibc) - - 0.17s 32M
3.11 alpine (musl) sdist - 0.32s 37.7M
3.11 alpine (musl) - - 0.36s 37.7M
3.11 slim (glibc) wheel 2.5s 0.27s 35M
3.11 slim (glibc) - - 0.26s 35M
3.12 alpine (musl) sdist - 0.28s 29.1M
3.12 alpine (musl) - - 0.28s 29.1M
3.12 slim (glibc) wheel 2.3s 0.27s 26M
3.12 slim (glibc) - - 0.27s 26M
3.13 alpine (musl) sdist - 0.23s 28.9M
3.13 alpine (musl) - - 0.24s 28.7M
3.13 slim (glibc) wheel 2.4s 0.24s 26M
3.13 slim (glibc) - - 0.24s 26M
3.9 alpine (musl) build_error - - - -
3.9 alpine (musl) - - 0.28s 33.1M
3.9 slim (glibc) build_error - 11.3s - -
3.9 slim (glibc) - - 0.23s 31M

This quickstart demonstrates the core usage of Gevent: first, it applies monkey patching to make standard library functions cooperative. Then, it spawns multiple greenlets to perform I/O-bound tasks (fetching URLs) concurrently, and finally, it waits for all of them to complete.

from gevent import monkey; monkey.patch_all()
import gevent
import requests

def fetch_url(url):
    print(f"Fetching {url}...")
    try:
        response = requests.get(url, timeout=5) # requests uses patched socket
        print(f"Finished fetching {url}, status: {response.status_code}")
        return len(response.content)
    except requests.exceptions.RequestException as e:
        print(f"Error fetching {url}: {e}")
        return 0

urls = [
    "https://www.google.com",
    "https://www.github.com",
    "https://www.python.org"
]

# Spawn greenlets for each URL fetch
greenlets = [gevent.spawn(fetch_url, url) for url in urls]

# Wait for all greenlets to complete
gevent.joinall(greenlets)

total_bytes = sum(g.value for g in greenlets if g.successful())
print(f"Total bytes fetched: {total_bytes}")