

.Net Core 3 is slated for release at the end of September, and with it’s release, a variety of new features will be available, such as Blazor, C# 8, Single-file executables, and a whole lot more. This article is going to explore gRPC support in ASP.NET Core 3 by building a service in ASP.NET Core 3 and a Python client. The finished code can be found here.
What is gRPC?
gRPC is an open source RPC framework developed at Google that is meant to be platform agnostic, highly productive by using protocols and auto-code generation for models/services, and efficiently connect microservices by leveraging HTTP/2.
What You’ll Need
- The latest preview version of Visual Studio 2019 (if before the release of .NET Core 3)
- .NET Core 3
- Python 3
- Preferred Text Editor or IDE for python (I used VS Code)
gRPC Service
We’ll start off by creating a new project in Visual Studio. Search for ‘grpc service’ in the template search bar:

Once the project is created, we can go into the Protos folder and create a new file called person.proto and create add the following code:
The PersonServ section defines what methods are available on the service to the client. It also defines what the request and return models are. The models defined are Person and GetPersonRequest.
Next, you will need to add the below line to the .csproj file for your project. This line will trigger the build process to auto-generate a service interface and model classes to use in your service implementation. Be sure to put the line within the correct item group! See the example flow below:
After you add person.proto to the Protobuf Itemgroup and you have Grpc.Tools nuget package installed (this package is a part of Grpc.AspNetCore package that comes with the Grpc template), the build process should recognize the new proto file and generate model and interfaces classes. The new classes won’t be visible to you in your project files but can be found in the obj folder.
Now to implement the newly created PersonServ interface that is in the obj folder. Under the ‘Services’ folder in your solution, create a new class called PersonService. From there, you will inherit from PersonServ.PersonServBase class and implement the GetPerson method. The GetPerson method has two arguments: GetPersonRequest and ServerCallContext. GetPersonRequest is the request model defined in the Protos/person.proto file and ServerCallContext provides some meta information and methods around the call including the ability to get an HttpContext object.
If you remember from implementing the protobuf for PersonServ, the GetPersonRequest includes an Id. For now, we will return a dummy person with the id baked into the name:
Notice that PersonService behaves very similar to a typical ASP.Net controller. There is a constructor that allows for objects to be passed via Dependency Injection but the “controller” methods are what are defined in person.proto.
Lastly, we will register the new PersonService in Startup.cs so that ASP.Net Core recognizes it during runtime:
Startup.cs:
One important thing in Startup.cs: the gRPC service is registered within the Configure method when endpoints are configured. This is a new feature in ASP.Net Core 3, UseEndpoints acts as a one-stop shop for registering various services and controllers. It replaces individual calls to services such as SignalR and MVC.
Change your app url from “https://” to “http://” in the Debug window in your project properties. This will simplify the client connection for this demo.
Finally, build and run your service to ensure that things are working as expected. You should see a console window that looks similar to this:

gRPC Python Client
Previously, we built a gRPC service leveraging .NET Core 3, and now we need a way to communicate with it. For this demo, we will build a simple Python client. A common use case for gRPC is for inter-service communication, such as microservice-to-microservice.
Configuring the Client Environment
We will need to ensure that we have Python 3 installed and the appropriate libraries to connect to our gRPC service. These libraries are:
- grpcio
- grpcio-tools
- requests
We can do this all in one simple powershell script:
You can either run this as a file by executing ./gRPC_Client_PythonSetup.ps1 or running each line individually in a powershell window. The choice is yours and yours alone…
Next, create a new folder next to the root folder of your service called PythonClient. Fire up Visual Studio Code and open that folder location.
We’re going to keep the folder simple but one additional folder that should be created is “/protos” within “/PythonClient”. This will be where we place the person.proto file for the Python client. Typically, companies will have a mono-repository where services and clients live with proto files in a shared folder that are accessible to everything. This limits versioning mistakes and duplication. For our purposes, we will duplicate the file as it’s simple and this is a demo. Copy and paste person.proto from your service to your newly created “PythonClient/protos/” folder. Your folder should look like this now in VS Code:

With our person.proto file in place, we need to utilize grpcio-tools to auto-generate our person models and service stubs for the client. Fire up powershell (will have bash later) and navigate to your PythonClient directory. Once there, execute this command:
We should now see two new files in “/PythonClient”: person_pb2_grpc.py and person_pb2.py. These files contain:
- Classes for the messages defined in our proto file
- Classes for the service defined in our proto file
- Stubs for our service methods (called via RPC)
- Interface for implementations of our service
- A function for the service defined in our proto
Now that all the building blocks are in place, we can now create a simple gRPC Python client that will make an arbitrary number of calls to the PersonService.
First, create a new file in the root “/PythonClient” directory called PersonClient.py.
We will need to import a bunch of libraries to get this client to work:
Next, we’ll create a method called run_grpc() that will do our loop and calls. In order to connect to the gRPC Person Service, you will need to know the host/port it’s operating on. This can be determined at runtime, so we’ll make variable called port. Next, we’ll create a channel and stub:
The channel is the mechanism for connecting to our service and the stub defines the methods which we can call against that service. The actual call comprises of stub.whatever method you call here(object defined by proto). For us, it should look something like: stub.GetPerson(person_pb2.GetPersonRequest(id = x)) with the x being the incremented counter:
With a few slight changes to add parameters to run_grpc to capture arguments, our simple client should look like this:
Executing the Demo
Run the script ExecuteExample.ps1 by navigating to the script location and entering ./ExecuteSample.ps1 and watch your hard work pay off!
Next Steps
In the next entry, we’ll add to this simple example and add database calls, a REST API, and benchmarking. Stay tuned!
