### Start grpclib Server Source: https://github.com/vmagamedov/grpclib/blob/master/examples/README.rst Starts the grpclib helloworld server. This command is executed in the shell and invokes a Python module. ```shell $ python3 -m helloworld.server ``` -------------------------------- ### Python: grpclib Server Example Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Illustrates setting up a gRPC server with grpclib and asyncio. It defines a service implementation and starts the server to listen for incoming requests. Requires generated protobuf stub files. ```python import asyncio from grpclib.utils import graceful_exit from grpclib.server import Server # generated by protoc 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(*, 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() if __name__ == '__main__': asyncio.run(main()) ``` -------------------------------- ### Installing certifi for SSL Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Instructions for installing the `certifi` package, which provides a curated bundle of CA certificates for more reliable SSL verification in Python applications, including grpclib. ```console $ pip3 install certifi ``` -------------------------------- ### Console: Install grpclib with Protobuf Support Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Installs the grpclib library along with the necessary protobuf dependencies using pip. This command is essential for setting up the gRPC environment. ```console $ pip3 install "grpclib[protobuf]" ``` -------------------------------- ### Console: Install Protobuf Compiler (macOS) Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Provides an example command for installing the protobuf compiler (protoc) on macOS using Homebrew. The protoc compiler is required for generating gRPC code from .proto files. ```console $ brew install protobuf # example for macOS users ``` -------------------------------- ### Install googleapis-common-protos Source: https://github.com/vmagamedov/grpclib/blob/master/docs/errors.rst Install the necessary package to enable rich error details encoding using google.rpc.Status messages. ```console pip3 install googleapis-common-protos ``` -------------------------------- ### Run grpclib Client Source: https://github.com/vmagamedov/grpclib/blob/master/examples/README.rst Executes the grpclib helloworld client. This command is executed in the shell and invokes a Python module. ```shell $ python3 -m helloworld.client ``` -------------------------------- ### Console: Install grpclib Pre-release Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Installs the latest pre-release version of grpclib, which may include new features or bug fixes not yet in the stable release. Also includes protobuf support. ```console $ pip3 install --upgrade --pre "grpclib[protobuf]" ``` -------------------------------- ### Console: Install grpcio-tools Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Installs the grpcio-tools Python package, which provides the protoc compiler and plugins. This is an alternative method for obtaining the protoc compiler, especially useful within Python environments. ```console $ pip3 install grpcio-tools ``` -------------------------------- ### Console: Check grpcio-tools Version Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Checks the version of the installed grpcio-tools package. This confirms that the tools necessary for gRPC code generation are available and correctly installed. ```console $ python3 -m grpc_tools.protoc --version libprotoc ... ``` -------------------------------- ### Graceful Server Shutdown Source: https://github.com/vmagamedov/grpclib/blob/master/docs/server.rst Shows how to start a grpclib server and ensure a graceful shutdown by handling SIGINT and SIGTERM signals using the graceful_exit utility. ```python with graceful_exit([server]): await server.start(host, port) print(f'Serving on {host}:{port}') await server.wait_closed() ``` -------------------------------- ### grpclib Server Example with Custom Codec Source: https://github.com/vmagamedov/grpclib/blob/master/docs/encoding.rst Shows how to set up a grpclib server using a custom codec. It includes a sample `PingServiceHandler` and how to instantiate the `Server` with the custom codec, handling unary-unary RPCs. ```python from grpclib.const import Cardinality, Handler from grpclib.server import Server class PingServiceHandler: async def Ping(self, stream): request = await stream.recv_message() # Process request await stream.send_message({'value': 'pong'}) def __mapping__(self): return { '/ping.PingService/Ping': Handler( self.UnaryUnary, Cardinality.UNARY_UNARY, None, None, ), } # Assuming JSONCodec is defined elsewhere # server = Server([PingServiceHandler()], codec=JSONCodec()) ``` -------------------------------- ### Console: Check Protobuf Compiler Version Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Verifies the installation and version of the protobuf compiler (protoc). This is a crucial step to ensure the compiler is correctly set up before generating gRPC code. ```console $ protoc --version libprotoc ... ``` -------------------------------- ### Python: grpclib Client Example Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Demonstrates how to create a gRPC client using grpclib with asyncio. It connects to a server, sends a request, and prints the received reply. Requires generated protobuf stub files. ```python import asyncio from grpclib.client import Channel # generated by protoc from .helloworld_pb2 import HelloRequest, HelloReply from .helloworld_grpc import GreeterStub async def main(): async with Channel('127.0.0.1', 50051) as channel: greeter = GreeterStub(channel) reply = await greeter.SayHello(HelloRequest(name='Dr. Strange')) print(reply.message) if __name__ == '__main__': asyncio.run(main()) ``` -------------------------------- ### Metadata as HTTP Headers Source: https://github.com/vmagamedov/grpclib/blob/master/docs/metadata.rst Shows how metadata is sent as regular HTTP headers, including examples for plain ASCII text and binary data, with specific conventions for binary keys and base64 encoding. ```text auth-token: 0d16ad85-6ce4-4773-a1be-9f62b2e886a3 auth-token-bin: DRathWzkR3Ohvp9isuiGow ``` -------------------------------- ### Regenerate grpclib gRPC Files Source: https://github.com/vmagamedov/grpclib/blob/master/examples/README.rst Regenerates the Python gRPC stub files from a .proto definition using grpc_tools.protoc. This command is executed in the shell and utilizes Python tools. ```shell $ python3 -m grpc_tools.protoc -I. --python_out=. --grpclib_python_out=. helloworld/helloworld.proto ``` -------------------------------- ### grpclib Client Example with Custom Codec Source: https://github.com/vmagamedov/grpclib/blob/master/docs/encoding.rst Illustrates how to configure a grpclib client to use a custom codec. It defines a `PingServiceStub` and shows how to create a `Channel` with the custom codec for making RPC calls. ```python from grpclib.client import Channel, UnaryUnaryMethod class PingServiceStub: def __init__(self, channel): self.Ping = UnaryUnaryMethod( channel, '/ping.PingService/Ping', None, None, ) # Assuming JSONCodec is defined elsewhere # channel = Channel(codec=JSONCodec()) # ping_stub = PingServiceStub(channel) # await ping_stub.Ping({'value': 'ping'}) ``` -------------------------------- ### Calling Streaming RPC Methods Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Provides an example of how to handle advanced RPC calls, specifically bidirectional streaming, using grpclib. It involves opening a stream, sending requests, and receiving responses within a loop. ```python3 async with stub.BiDiMethod.open() as stream: await stream.send_request() # needed to initiate a call while True: task = await task_queue.get() if task is None: await stream.end() break else: await stream.send_message(task) result = await stream.recv_message() await result_queue.add(task) ``` -------------------------------- ### grpclib Naming Conventions for Services/Methods Source: https://github.com/vmagamedov/grpclib/blob/master/docs/encoding.rst Details the naming conventions for gRPC services and methods, particularly how they map to the `:path` pseudo header. It follows Protocol Buffers Style Guide recommendations for CamelCase naming. ```apidoc :path = /dotted.package.CamelCaseServiceName/CamelCaseMethodName Service names and RPC method names should use CamelCase (with an initial capital). ``` -------------------------------- ### Client-Side: Sending Metadata Source: https://github.com/vmagamedov/grpclib/blob/master/docs/metadata.rst Provides an example of how to send metadata from the client when making a gRPC call using grpclib. The metadata is passed as a dictionary to the stub method. ```python3 reply = await stub.Method(Request(), metadata={'auth-token': auth_token}) ``` -------------------------------- ### Deadline Propagation Example Source: https://github.com/vmagamedov/grpclib/blob/master/docs/overview.rst Demonstrates how timeouts are managed and propagated across service calls in a distributed system to meet initial timeout constraints. This involves calculating remaining time for subsequent requests. ```python3 deadline = time.monotonic() + grpc_timeout ``` ```python3 new_timeout = max(deadline - time.monotonic(), 0) # == 80ms ``` -------------------------------- ### Initialize Server with Services Source: https://github.com/vmagamedov/grpclib/blob/master/docs/server.rst Demonstrates how to create a grpclib Server instance by passing a list of service implementations. ```python server = Server([foo_svc, bar_svc, baz_svc]) ``` -------------------------------- ### Creating a grpclib Channel Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Demonstrates the basic usage of creating a grpclib client channel using an asynchronous context manager. A single channel represents a connection to the server, supporting multiplexed RPC calls over HTTP/2. ```python3 async with Channel(host, port) as channel: pass ``` -------------------------------- ### Console: grpclib Protoc Plugin Usage Source: https://github.com/vmagamedov/grpclib/blob/master/README.rst Demonstrates the command-line usage of the protoc compiler with the grpclib plugin. This command generates Python stub files (`_pb2.py` and `_grpc.py`) required for grpclib client and server implementations. ```console $ python3 -m grpc_tools.protoc -I. --python_out=. --grpclib_python_out=. helloworld/helloworld.proto ^----- note -----^ ``` -------------------------------- ### grpcannon Benchmarking: PyPy vs CPython Source: https://github.com/vmagamedov/grpclib/wiki/Home Demonstrates performance benchmarking of gRPC services using the grpcannon tool. It shows the command-line execution and the resulting performance metrics for both PyPy and CPython environments, highlighting differences in speed and latency. ```shell Python 3.5.3 (fdd60ed87e941677e8ea11acf9f1819466521bf2, Apr 26 2018, 01:25:35) [PyPy 6.0.0 with GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.1)] on darwin $ grpcannon -proto example/helloworld/helloworld.proto -call helloworld.Greeter.UnaryUnaryGreeting -d '{"name":"John Doe"}' -n 4000 -c 16 127.0.0.1:50051 Summary: Count: 4000 Total: 924.86 ms Slowest: 21.08 ms Fastest: 2.52 ms Average: 3.68 ms Requests/sec: 4324.96 Response time histogram: 2.518 [1] | 4.374 [3655] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ 6.231 [166] |∎∎ 8.087 [76] |∎ 9.944 [18] | 11.800 [21] | 13.657 [37] | 15.513 [2] | 17.370 [16] | 19.226 [5] | 21.083 [3] | Latency distribution: 10% in 3.02 ms 25% in 3.12 ms 50% in 3.25 ms 75% in 3.48 ms 90% in 4.10 ms 95% in 5.99 ms 99% in 12.45 ms Status code distribution: [OK] 4000 responses ``` ```shell Python 3.6.5 (default, Jun 17 2018, 12:13:06) [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin $ grpcannon -proto example/helloworld/helloworld.proto -call helloworld.Greeter.UnaryUnaryGreeting -d '{"name":"John Doe"}' -n 4000 -c 16 127.0.0.1:50051 Summary: Count: 4000 Total: 2893.29 ms Slowest: 31.91 ms Fastest: 7.10 ms Average: 11.54 ms Requests/sec: 1382.51 Response time histogram: 7.104 [1] | 9.585 [4] | 12.066 [3511] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ 14.546 [231] |∎∎∎ 17.027 [191] |∎∎ 19.508 [18] | 21.989 [12] | 24.469 [12] | 26.950 [18] | 29.431 [1] | 31.911 [1] | Latency distribution: 10% in 10.78 ms 25% in 10.88 ms 50% in 11.02 ms 75% in 11.25 ms 90% in 13.39 ms 95% in 14.65 ms 99% in 20.67 ms Status code distribution: [OK] 4000 responses ``` -------------------------------- ### Configure grpclib Channel with Configuration Source: https://github.com/vmagamedov/grpclib/blob/master/docs/config.rst Demonstrates how to create a `grpclib.config.Configuration` object and pass it to the `grpclib.client.Channel` constructor to modify default behavior, such as setting the HTTP/2 connection window size. ```python3 from grpclib.config import Configuration from grpclib.client import Channel config = Configuration( http2_connection_window_size=2**20, # 1 MiB ) channel = Channel('localhost', 50051, config=config) ``` -------------------------------- ### Advanced Lifecycle Management Source: https://github.com/vmagamedov/grpclib/blob/master/docs/server.rst Illustrates managing server lifecycle and resources, such as database connections, using AsyncExitStack and graceful_exit for robust application management. ```python async with AsyncExitStack() as stack: db = await stack.enter_async_context(setup_db()) foo_svc = FooService(db) server = Server([foo_svc]) stack.enter_context(graceful_exit([server])) await server.start(host, port) print(f'Serving on {host}:{port}') await server.wait_closed() ``` -------------------------------- ### List Service Methods with grpc_cli Source: https://github.com/vmagamedov/grpclib/blob/master/docs/reflection.rst Retrieves detailed information about a specific service, including its methods, request/response types, and the proto file definition. The -l flag provides the full service definition. ```shell $ grpc_cli ls localhost:50051 helloworld.Greeter -l filename: helloworld/helloworld.proto package: helloworld; service Greeter { rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} } ``` -------------------------------- ### List Services with grpc_cli Source: https://github.com/vmagamedov/grpclib/blob/master/docs/reflection.rst Lists all available services exposed by the gRPC server. This command helps in discovering the services running on a specific host and port. ```shell $ grpc_cli ls localhost:50051 helloworld.Greeter ``` -------------------------------- ### Using certifi with grpclib Channel Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Shows how to explicitly configure grpclib's Channel to use certificates provided by the `certifi` package for SSL verification. ```python import ssl channel = Channel(host, port, ssl=ssl.get_default_verify_paths()) ``` -------------------------------- ### Establishing a Secure Channel Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Demonstrates how to configure grpclib to use SSL for secure connections to a gRPC server. It shows the basic `ssl=True` option. ```python3 channel = Channel(host, port, ssl=True) ``` -------------------------------- ### Using a Channel for Multiple Service Stubs Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Illustrates how a single grpclib Channel can be reused to create stubs for multiple services implemented by the same server. This promotes efficient connection management. ```python3 foo_svc = FooServiceStub(channel) bar_svc = BarServiceStub(channel) baz_svc = BazServiceStub(channel) ``` -------------------------------- ### grpclib Python Dependencies Manifest Source: https://github.com/vmagamedov/grpclib/blob/master/setup.txt This manifest lists the Python packages and their specific versions required for the grpclib project, as generated by pip-compile. It includes package names, versions, and comments indicating their origin or purpose within the project. ```Python # # This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # pip-compile --annotation-style=line --output-file=setup.txt setup.py # h2==4.1.0 # via grpclib (setup.py) hpack==4.0.0 # via h2 hyperframe==6.0.1 # via h2 multidict==6.0.5 # via grpclib (setup.py) ``` -------------------------------- ### Customizing SSL Verification Paths Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Demonstrates how to customize the CA certificate paths used by grpclib for SSL verification by modifying the `DefaultVerifyPaths` object returned by `ssl.get_default_verify_paths()`. ```python import ssl ssl.get_default_verify_paths()._replace(cafile=YOUR_CA_FILE) ``` -------------------------------- ### Import Status and GRPCError Source: https://github.com/vmagamedov/grpclib/blob/master/docs/changelog/index.rst Demonstrates the correct import paths for Status and GRPCError classes from the grpclib library, essential for handling gRPC errors and status codes. ```python from grpclib import Status, GRPCError ``` -------------------------------- ### grpclib Metadata Reference Source: https://github.com/vmagamedov/grpclib/blob/master/docs/metadata.rst API documentation for grpclib components related to metadata. This includes the Deadline class for managing call deadlines and the Peer class for peer information. ```APIDOC grpclib.metadata.Deadline Represents the deadline for a gRPC call. Attributes: time_remaining: The remaining time in seconds. deadline: The absolute deadline timestamp. grpclib.protocol.Peer Represents the peer address for a gRPC connection. Attributes: host: The hostname or IP address of the peer. port: The port number of the peer. ``` -------------------------------- ### gRPC Call Structure with Metadata Source: https://github.com/vmagamedov/grpclib/blob/master/docs/metadata.rst Illustrates the typical structure of a gRPC call, highlighting where request and reply metadata are exchanged, similar to regular HTTP requests but with trailers. ```text > :path /package/Method/ > ... > ... request metadata > data (request) < :status 200 < ... < ... initial metadata < data (reply) < grpc-status 0 < ... < ... trailing metadata ``` -------------------------------- ### Using System CA Certificates for SSL Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Illustrates how grpclib leverages system CA certificates for SSL verification when `ssl=True` is set on the Channel. This is the default behavior. ```python3 channel = Channel(host, port, ssl=True) ^^^^^^^^^^ ``` -------------------------------- ### Server Request Lifecycle and Metadata Source: https://github.com/vmagamedov/grpclib/blob/master/docs/_static/diagram.html Details the sequence of operations for a server handling an RPC request, including sending and receiving initial metadata, processing data frames, and sending trailing metadata (trailers) to indicate RPC status. ```APIDOC Server Request Handling: 1. send_initial_metadata() - Sends initial metadata (HEADERS frame) before receiving client messages. - RPC success or failure is indicated in trailers. 2. recv_initial_metadata() - Receives initial metadata from the client. 3. send_message(message) - Sends a DATA frame containing the message payload. 4. recv_message() - Receives DATA frames from the client. 5. send_trailing_metadata() - Sends trailing metadata (HEADERS frame as trailers) to signal RPC completion or status. 6. recv_trailing_metadata() - Receives trailing metadata from the client. ``` -------------------------------- ### grpclib Server Stream Handling Source: https://github.com/vmagamedov/grpclib/blob/master/docs/diagram.txt Explains how the server handles incoming gRPC requests, including receiving messages, sending initial metadata, and sending trailing metadata to indicate RPC status. ```APIDOC Server Stream Operations: 1. **Receive Request**: - Server receives initial `HEADERS` frame from the client. - Client -> Server: `HEADERS` frame. - Note Server: `request accepted`. 2. **Receive Messages**: - Server receives `DATA` frames containing the message payload. - Client -> Server: `DATA` ... `DATA` frames. - Note Server: `recv_message`. 3. **Send Initial Metadata**: - The server can send initial metadata even before receiving client messages. - Client <- Server: `HEADERS` frame. - Note Client: `recv_initial_metadata` *[auto]*. 4. **Send Trailing Metadata**: - RPC success or failure is indicated in trailers (trailing metadata). - Client <- Server: `HEADERS` frame as trailers. - Note Client: `recv_trailing_metadata` *[auto]*. Note: - `send_initial_metadata` and `send_trailing_metadata` are often handled automatically by the framework. ``` -------------------------------- ### Calling Unary RPC Methods Source: https://github.com/vmagamedov/grpclib/blob/master/docs/client.rst Shows the straightforward method for invoking unary-unary RPC calls on a service stub. This pattern is suitable for simple request-response interactions. ```python3 reply = await stub.Method(Request()) ``` -------------------------------- ### Call Service Method with grpc_cli Source: https://github.com/vmagamedov/grpclib/blob/master/docs/reflection.rst Executes a specific method on the gRPC server with provided request data. This demonstrates making a direct call to a service endpoint using the client tool. ```shell $ grpc_cli call localhost:50051 helloworld.Greeter.SayHello "name: 'Dr. Strange'" connecting to localhost:50051 message: "Hello, Dr. Strange!" Rpc succeeded with OK status ``` -------------------------------- ### Client-Side: Sending and Receiving Metadata Source: https://github.com/vmagamedov/grpclib/blob/master/docs/metadata.rst Shows how a client can send initial metadata, receive initial metadata, send a message, receive a reply, and finally receive trailing metadata using an asynchronous stream context manager. ```python3 async with stub.Method.open(metadata={'auth-token': auth_token}) as stream: await stream.recv_initial_metadata() print(stream.initial_metadata) await stream.send_message(Request()) reply = await stream.recv_message() await stream.recv_trailing_metadata() print(stream.trailing_metadata) ``` -------------------------------- ### Testing Overall Server Health Source: https://github.com/vmagamedov/grpclib/blob/master/docs/health.rst Demonstrates how to test the overall health of a gRPC server using the grpc_health_probe command-line tool. ```shell $ grpc_health_probe -addr=localhost:50051 healthy: SERVING ``` -------------------------------- ### Client-Side GRPCError Handling with Context Manager Source: https://github.com/vmagamedov/grpclib/blob/master/docs/errors.rst Shows the recommended way to handle GRPCError on the client-side when using the `open()` context manager for streams. Errors are propagated and can be caught outside the `with` block. ```python from grpclib.exceptions import GRPCError try: async with stub.SomeMethod.open() as stream: await stream.send_message(Request(...)) reply = await stream.recv_message() except GRPCError as error: print(error.status, error.message) ```