gRPC (Google Remote Procedure Call) Example in Python

This guide provides a simple practical example of using gRPC in Python to create a basic server and client for a “Hello, World!” operation.

Step 1: Install gRPC

Make sure you have gRPC installed. You can install it using pip:

pip install grpcio
pip install grpcio-tools

Step 2: Define the gRPC service

Create a file named `hello.proto` with the following content:

syntax = "proto3";

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
 string name = 1;
}

message HelloResponse {
  string message = 1;
}

Step 3: Generate gRPC files

Run the following commands to generate the Python files from the protobuf file:

python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. hello.proto

This will generate `hello_pb2.py` and `hello_pb2_grpc.py`.

Step 4: Implement the Server

In this step, you will create a Python script named `server.py` to implement the gRPC server. Follow these detailed instructions to understand each component:

Step 4.1 to Step 4.4: Define a class `HelloServicer` that inherits from the generated `HelloServiceServicer` class. Implement the `SayHello` method to handle the “Hello, World!” operation.

Step 4.5 to Step 4.10: Define a function `serve` to set up and start the gRPC server. This includes creating a server, adding the servicer implementation, specifying a port, and starting the server.

Step 4.11 to Step 4.12: Check if the script is being run directly and call the `serve` function to start the server.

import grpc
from concurrent import futures
import hello_pb2
import hello_pb2_grpc

# Step 4.1: Define a class that inherits from the generated servicer base class
class HelloServicer(hello_pb2_grpc.HelloServiceServicer):
    # Step 4.2: Implement the service method defined in the proto file
    def SayHello(self, request, context):
        # Step 4.3: Create a response object and set the message
        response = hello_pb2.HelloResponse()
        response.message = f"Hello, {request.name}!"
        # Step 4.4: Return the response
        return response

# Step 4.5: Define a function to start the gRPC server
def serve():
    # Step 4.6: Create a gRPC server with a thread pool for handling requests
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    
    # Step 4.7: Add the servicer implementation to the server
    hello_pb2_grpc.add_HelloServiceServicer_to_server(HelloServicer(), server)
    
    # Step 4.8: Add an insecure port to the server (you should use a secure port in production)
    server.add_insecure_port('[::]:50051')
    
    # Step 4.9: Start the server
    server.start()
    print("Server running on port 50051")
  
    # Step 4.10: Wait for the server to be terminated
    server.wait_for_termination()

# Step 4.11: Check if the script is being run directly
if __name__ == '__main__':
    # Step 4.12: Call the serve function to start the server
    serve()

Step 5: Implement the client

Create a file named `client.py` with the following content:

import grpc
import hello_pb2
import hello_pb2_grpc

  def run():
    channel = grpc.insecure_channel('localhost:50051')
    stub = hello_pb2_grpc.HelloServiceStub(channel)
    response = stub.SayHello(hello_pb2.HelloRequest(name='World'))
    print("Client received: " + response.message)

if __name__ == '__main__':
    run()

Step 6: Run the server and client

In one terminal, run the server:

python server.py

In another terminal, run the client:

python client.py

You should see the output:

Client received: Hello, World!