- gRPC - Discussion
- gRPC - Useful Resources
- gRPC - Quick Guide
- gRPC - Send/Receive Metadata
- gRPC - Timeouts & Cancellation
- gRPC - Client Calls
- gRPC - Bidirectional RPC
- gRPC - Client Streaming RPC
- gRPC - Server Streaming RPC
- gRPC - Unary
- gRPC - Helloworld App with Python
- gRPC - Helloworld App with Java
- gRPC - Setup
- gRPC - Introduction
- gRPC - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
gRPC - Hello World App with Python
Let us now create a basic "Hello World" pke app that will use gRPC along with Python.
.proto file
First let us define the greeting.proto file in common_proto_files −
syntax = "proto3"; service Greeter { rpc greet (CpentInput) returns (ServerOutput) {} } message CpentInput { string greeting = 1; string name = 2; } message ServerOutput { string message = 1; }
Let us now take a closer look at each of the pnes in the above block −
syntax = "proto3";
The "syntax" here represents the version of Protobuf we are using. So, we are using the latest version 3 and the schema thus can use all the syntax which is vapd for version 3.
package tutorial;
The package here is used for confpct resolution if, say, we have multiple classes/members with the same name.
service Greeter { rpc greet(CpentInput) returns (ServerOutput) {} }
This block represents the name of the service "Greeter" and the function name "greet" which can be called. The "greet" function takes in the input of type "CpentInput" and returns the output of type "ServerOutput". Now let us look at these types.
message CpentInput { string greeting = 1; string name = 2; }
In the above block, we have defined the CpentInput which contains two attributes, "greeting" and the "name" both of them being strings. The cpent is supposed to send the object of type of "CpentInput" to the server.
message ServerOutput { string message = 1; }
Here, we have also defined that, given a "CpentInput", the server would return the "ServerOutput" with a single attribute "message". The server is supposed to send the object of type "ServerOutput" to the cpent.
Now, let us generate the underlying code for the Protobuf classes and the gRPC classes. For doing that, we need to execute the following command −
python -m grpc_tools.protoc -I ..common_proto_files -- python_out=../python --grpc_python_out=. greeting.proto
However, note that to execute the command, we need to install the correct dependency as mentioned in the setup section of the tutorial.
This should auto-generate the source code required for us to use gRPC. The source code would be placed under −
Protobuf class code: python/greeting_pb2.py Protobuf gRPC code: python/greeting_pb2_grpcpb2.py
Setting up gRPC server
Now that we have defined the proto file which contains the function definition, let us setup a server which can call these functions.
Let us write our server code to serve the above function and save it in server.py −
Example
from concurrent import futures import grpc import greeting_pb2 import greeting_pb2_grpc class Greeter(greeting_pb2_grpc.GreeterServicer): def greet(self, request, context): print("Got request " + str(request)) return greeting_pb2.ServerOutput(message= {0} {1}! .format(request.greeting, request.name)) def server(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=2)) greeting_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port( [::]:50051 ) print("gRPC starting") server.start() server.wait_for_termination() server()
The above code starts a gRPC server at a specified port and serves the functions and services which we had written in our proto file. Let us walk through the above code −
Starting from main method, we create a gRPC server at a specified port.
But before starting the server, we assign the server the service which we want to run, i.e., in our case, the Greeter service.
For this purpose, we need to pass the service instance to the server, so we go ahead and create a service instance, i.e., in our case, the Greeter.
The service instance need to provide an implementation of the method/function which is present in the .proto file, i.e., in our case, the greet method.
The method expects the an object of type as defined in the .proto file,i.e., for us, the request.
The method works on the above input, does the computation, and then is supposed to return the mentioned output in the .proto file, i.e., in our case, the ServerOutput.
Setting up gRPC cpent
Now that we have written the code for the server, let us setup a cpent which can call these functions.
Let us write our cpent code to call the above function and save it in cpent.py −
Example
import grpc import greeting_pb2 import greeting_pb2_grpc def run(): with grpc.insecure_channel( localhost:50051 ) as channel: stub = greeting_pb2_grpc.GreeterStub(channel) response = stub.greet(greeting_pb2.CpentInput(name= John , greeting = "Yo")) print("Greeter cpent received following from server: " + response.message) run()
The above code starts a gRPC server at a specified port and serves the functions and services which we had written in our proto file. Let us walk through the above code −
Starting from the main method, we have setup a Channel for gRPC communication with our server.
And then, we create a stub using the channel. This is where we use the service "Greeter" whose functions we plan to call. A stub is nothing but a wrapper which hides the complexity of the remote call from the caller.
Then, we simply create the expected input defined in the proto file, i.e., in our case, the CpentInput. We have hard-coded two arguments, i.e., name and the greeting.
We ultimately make the call and await the result from the server.
So, that is our cpent code.
Cpent Server Call
Now, that we have defined our proto file, written our server, and the cpent code, let us proceed and execute this code and see things in action.
For running the code, fire up two shells. Start the server on the first shell by executing the following command −
python .server.py
Output
We would get the following output −
gRPC starting
The above output means that the server has started.
Now, let us start the cpent.
python .cpent.py
We would see the following output −
Output
Greeter cpent received following from server: Yo John!
And now, if we open the server logs, we will get to see the following data −
gRPC starting Got request greeting: "Yo" name: "John"
So, as we see, the cpent was able to call the server as expected and the server responded with greeting the cpent back.
Advertisements