gRPC in Python. Part 2: Building a gRPC client

Building fast and scalable APIs using gRPC


The code for this article is available at:

This is part of a series of gRPC in python. We will cover the following

  1. [Implementing a server](

  2. Implementing a client

  3. gRPC Streaming

  4. Advanced features like interceptors, etc.

  5. Serving frontends using gRPC gateway

gRPC client

In the last article in our series, we saw how to create a gRPC server in python. With gRPC, you need to build a client to invoke methods on the server. This is because gRPC is not as simple as REST. Fortunately, with tools such as Protoc, we already get generated code available for us.

Code generation

Please look at [Part 1: Building a gRPC server]( for instructions on how to generate python files from protobuf definitions.

Client definition

Now that we have our service definition files generated, we can go ahead and create our client.

Lets create a folder called client and another file called in our project.

import grpc

from python_grpc_demo.grpc_types.greeting_pb2 import GreetingRequest
from python_grpc_demo.grpc_types.greeting_pb2_grpc import GreeterStub

def run():
    name = input('What is your name?\n')

    with grpc.insecure_channel('localhost:50051') as channel:
        greeter_stub = GreeterStub(channel)
        request_data = GreetingRequest(name=name)
        response = greeter_stub.Greet(request_data)

Let's try and understand what this code is doing.

name = input('What is your name?\n')

Here we simply ask the user to input their name which we store in a variable.

with grpc.insecure_channel('localhost:50051') as channel:

Over here, we are establishing a gRPC connection to the server. We assume the server is hosted on localhost at port 50051. insecure_channel just means that we don't have any authentication, etc. on the connection. Later on in this series, we will see how to add authentication, encryption, etc.

greeter_stub = GreeterStub(channel)

We then create a stub. A stub is basically an interface to the gRPC service that we want to call methods on.

request_data = GreetingRequest(name=name)

We take the user input that we gathered and then create a new request object to pass to the gRPC server. Remember, gRPC is strongly typed so we need to create request and response objects for all our service calls.

response = greeter_stub.Greet(request_data)

We then make the actual call to the gRPC server and receive a response.

Folder structure

In case you've been following along, this is how our folder structure now looks like. We're using a monorepo so we have our client and server in the same folder.

├── poetry.lock
├── pyproject.toml
├── python_grpc_demo
│   ├── client
│   │   ├──
│   │   ├──
│   ├── grpc_types
│   │   ├──
│   │   ├──
│   │   ├── greeting_pb2.pyi
│   │   ├──
│   ├──
│   ├── protos
│   │   ├── greeting.proto
│   │   └──
│   └── server
│       ├──
│       ├──
│       └── servicers
│           ├──
│           ├──
├── README.rst
└── tests

Let's also modify our pyproject.toml to add a command to run the gRPC client.

run-grpc-server = "python_grpc_demo.server.server:serve"
run-grpc-client = "python_grpc_demo.client.client:run"

Testing it all out

Now that we have our client and server ready, we can test it all out.

Installing dependencies

Open a terminal, navigate to the codebase and run the following command

poetry install

Starting the server

We can then start the server with the poetry run run-grpc-server command. You should see the following output on your screen.

$ poetry run run-grpc-server
Server started

Running the client

In another terminal window, navigate to the same directory and run the client with the following command poetry run run-grpc-client . You should then see the following output in you terminal.

$ poetry run run-grpc-client
What is your name?
Harry Potter
Hello Harry Potter

We can see that the server is working correctly and responding with the data we expect.

In our next post, we'll see how we can add streaming features to our server and client.