grpclib

raw JSON →
0.4.9 verified Tue May 12 auth: no python install: verified

grpclib is a pure-Python implementation of the gRPC protocol for asyncio, designed to give developers full control over HTTP/2 streams. It allows for building high-performance client and server applications using asynchronous Python. The current version is 0.4.9 and it requires Python 3.10 or newer. The library receives regular updates with bug fixes and new features.

pip install "grpclib[protobuf]"
error grpclib.exceptions.GRPCError
cause A gRPC call failed, either on the client or server side, due to a protocol error, invalid argument, internal server error, network issue, or explicit cancellation.
fix
On the client, catch GRPCError and inspect error.status and error.message to handle specific gRPC status codes. On the server, raise GRPCError with an appropriate Status enum value and an optional message to signal specific failures to the client.
error StreamTerminatedError: Stream reset by remote party
cause The underlying HTTP/2 stream was unexpectedly terminated by the remote party (client or server), often due to a protocol violation, network issue, or a premature shutdown.
fix
Ensure both client and server applications handle stream closures gracefully; clients should call stream.end() for streaming calls, and servers should handle asyncio.CancelledError in request handlers during shutdown. Consider enabling grpclib debugging logs for more insights into the HTTP/2 frames.
error ModuleNotFoundError: No module named 'your_service_pb2'
cause The Python interpreter cannot find the protobuf-generated `_pb2.py` or gRPC stub `_grpc.py` files because they are not in the Python import path, or the `protoc` command was used incorrectly during generation.
fix
Ensure __init__.py files exist in all directories forming the Python package structure. Generate the protobuf files using the protoc command with correct -I (proto import path) and output (--python_out, --grpclib_python_out) arguments, relative to the root of your Python package. Adjust Python import statements to reflect the correct package structure (e.g., from . import your_service_pb2).
error AttributeError: module 'grpc' has no attribute 'aio'
cause This error typically occurs when attempting to use the asynchronous API of the `grpcio` library (`grpc.aio`) while `grpcio` is not installed, is an outdated version, or when `grpclib` is intended for use (which has its own distinct async API).
fix
If you intend to use grpcio's async API, ensure grpcio is installed and updated to a version that supports grpc.aio. If you are using grpclib, use its native asynchronous components like grpclib.client.Channel and grpclib.server.Server instead of grpc.aio constructs.
error grpclib.exceptions.ProtocolError
cause An underlying HTTP/2 protocol error occurred, indicating a violation of the HTTP/2 specification during communication between the gRPC client and server.
fix
This error often points to deeper issues. Review full tracebacks for details. Check for misconfigured proxies, load balancers, or firewalls that might be interfering with HTTP/2 traffic. Ensure grpclib versions are compatible across client and server if possible, and that both sides are handling HTTP/2 streams according to the gRPC protocol.
breaking Upgrading `grpclib` often requires updating your `protobuf` installation. `grpclib` regenerates its internal protobuf files, which can introduce new minimum `protobuf` runtime version requirements. For example, v0.4.6 required `protobuf>=3.20.0`. Always check the changelog for specific version bumps.
fix Ensure your `protobuf` package (`pip install --upgrade protobuf`) and `protoc` compiler (`brew upgrade protobuf` or similar) are up-to-date when upgrading `grpclib`.
breaking The `protoc` plugin option `--python_grpc_out` was renamed to `--grpclib_python_out` in `grpclib` v0.3.2. Build scripts using the old option will fail.
fix Update your `protoc` command to use `--grpclib_python_out` instead of `--python_grpc_out` for generating `grpclib` specific stubs. Example: `python3 -m grpc_tools.protoc -I. --python_out=. --grpclib_python_out=. helloworld.proto`.
deprecated The `loop` argument in public APIs (e.g., `Channel`, `Server` constructors) has been deprecated as `asyncio` automatically manages the event loop.
fix Remove the `loop` argument from calls to `Channel`, `Server`, and other public APIs where it was previously accepted. `asyncio.run()` will handle loop management.
gotcha The `grpclib.utils.graceful_exit` utility, used for handling server shutdown signals, is not supported on Windows operating systems.
fix On Windows, implement custom signal handling (e.g., using `asyncio.Event` and `signal.signal` for `SIGINT` on Python 3.8+ if available) or an alternative shutdown mechanism for your `grpclib` server.
gotcha In v0.4.0, metadata validation was fixed. This may cause exceptions if your application was previously sending invalid metadata values that did not conform to gRPC specifications (e.g., non-printable ASCII characters for text metadata or improperly encoded binary metadata).
fix Ensure all metadata keys and values conform to gRPC wire format specifications: keys with `-bin` suffix for binary values (bytes type), and printable ASCII for text values (str type). `grpclib` handles base64 encoding/decoding for `-bin` suffixed values automatically.
breaking Protobuf message and service stubs (e.g., `_pb2.py`, `_grpclib.py`) must be generated from your `.proto` files using the `protoc` compiler and the `grpclib` plugin. If these files are missing or not in the Python path, your application will encounter a `ModuleNotFoundError`.
fix Run the `protoc` compiler with the `grpclib` plugin to generate stubs for your `.proto` files. Example: `python3 -m grpc_tools.protoc -I. --python_out=. --grpclib_python_out=. your_service.proto`. Ensure the generated files are placed in a location discoverable by your Python application (e.g., in the same directory as your Python script or added to `PYTHONPATH`).
pip install grpcio-tools
python os / libc variant status wheel install import disk
3.10 alpine (musl) protobuf wheel - 1.18s 22.4M
3.10 alpine (musl) protobuf - - 1.10s 22.4M
3.10 alpine (musl) grpcio-tools wheel - - 110.9M
3.10 alpine (musl) grpcio-tools - - - -
3.10 slim (glibc) protobuf wheel 2.6s 1.59s 24M
3.10 slim (glibc) protobuf - - 1.90s 24M
3.10 slim (glibc) grpcio-tools wheel 4.4s - 176M
3.10 slim (glibc) grpcio-tools - - - -
3.11 alpine (musl) protobuf wheel - 0.74s 24.4M
3.11 alpine (musl) protobuf - - 0.78s 24.4M
3.11 alpine (musl) grpcio-tools wheel - - 118.0M
3.11 alpine (musl) grpcio-tools - - - -
3.11 slim (glibc) protobuf wheel 2.4s 0.61s 26M
3.11 slim (glibc) protobuf - - 0.63s 26M
3.11 slim (glibc) grpcio-tools wheel 3.3s - 183M
3.11 slim (glibc) grpcio-tools - - - -
3.12 alpine (musl) protobuf wheel - 0.76s 16.3M
3.12 alpine (musl) protobuf - - 0.86s 16.3M
3.12 alpine (musl) grpcio-tools wheel - - 118.6M
3.12 alpine (musl) grpcio-tools - - - -
3.12 slim (glibc) protobuf wheel 2.1s 0.77s 17M
3.12 slim (glibc) protobuf - - 0.88s 17M
3.12 slim (glibc) grpcio-tools wheel 3.3s - 183M
3.12 slim (glibc) grpcio-tools - - - -
3.13 alpine (musl) protobuf wheel - 0.76s 16.0M
3.13 alpine (musl) protobuf - - 0.78s 15.9M
3.13 alpine (musl) grpcio-tools wheel - - 115.2M
3.13 alpine (musl) grpcio-tools - - - -
3.13 slim (glibc) protobuf wheel 2.1s 0.75s 17M
3.13 slim (glibc) protobuf - - 0.83s 17M
3.13 slim (glibc) grpcio-tools wheel 3.5s - 182M
3.13 slim (glibc) grpcio-tools - - - -
3.9 alpine (musl) protobuf wheel - 0.16s 21.6M
3.9 alpine (musl) protobuf - - 0.17s 21.6M
3.9 alpine (musl) grpcio-tools wheel - - 110.1M
3.9 alpine (musl) grpcio-tools - - - -
3.9 slim (glibc) protobuf wheel 3.2s 0.14s 23M
3.9 slim (glibc) protobuf - - 0.15s 23M
3.9 slim (glibc) grpcio-tools wheel 5.0s - 175M
3.9 slim (glibc) grpcio-tools - - - -

This quickstart demonstrates how to set up a basic gRPC server and client using `grpclib`. First, define your service in a `.proto` file, then use `protoc` with the `grpclib` plugin to generate Python stubs. Finally, implement your server logic and client calls using the generated stubs.

# 1. Define your service in a .proto file (e.g., helloworld.proto):
# syntax = "proto3";
# package helloworld;
# message HelloRequest { string name = 1; }
# message HelloReply { string message = 1; }
# service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); }

# 2. Generate Python code from the .proto file:
# python3 -m grpc_tools.protoc -I. --python_out=. --grpclib_python_out=. helloworld.proto

# 3. Server implementation (server.py)
import asyncio
from grpclib.utils import graceful_exit
from grpclib.server import Server

# Generated by protoc from helloworld.proto
from helloworld_pb2 import HelloReply
from helloworld_grpc import GreeterBase

class Greeter(GreeterBase):
    async def SayHello(self, stream):
        request = await stream.recv_message()
        message = f'Hello, {request.name}!'
        await stream.send_message(HelloReply(message=message))

async def main_server(*, host='127.0.0.1', port=50051):
    server = Server([Greeter()])
    # Note: graceful_exit isn't supported in Windows
    with graceful_exit([server]):
        await server.start(host, port)
        print(f'Serving on {host}:{port}')
        await server.wait_closed()

# 4. Client implementation (client.py)
from grpclib.client import Channel

# Generated by protoc from helloworld.proto
from helloworld_pb2 import HelloRequest, HelloReply
from helloworld_grpc import GreeterStub

async def main_client():
    async with Channel('127.0.0.1', 50051) as channel:
        greeter = GreeterStub(channel)
        reply = await greeter.SayHello(HelloRequest(name='Dr. Strange'))
        print(reply.message)

# To run the server and then the client:
# if __name__ == '__main__':
#    asyncio.run(main_server())
#    # In another terminal, run:
#    # asyncio.run(main_client())