grpclib
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.
Warnings
- 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.
- 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.
- deprecated The `loop` argument in public APIs (e.g., `Channel`, `Server` constructors) has been deprecated as `asyncio` automatically manages the event loop.
- gotcha The `grpclib.utils.graceful_exit` utility, used for handling server shutdown signals, is not supported on Windows operating systems.
- 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).
Install
-
pip install "grpclib[protobuf]" -
pip install grpcio-tools
Imports
- Channel
from grpclib.client import Channel
- Server
from grpclib.server import Server
- graceful_exit
from grpclib.utils import graceful_exit
- Status
from grpclib import Status
- GRPCError
from grpclib import GRPCError
- GreeterStub
from .helloworld_grpc import GreeterStub
- GreeterBase
from .helloworld_grpc import GreeterBase
Quickstart
# 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())