Generated-code reference
Generated-code reference
gRPC Python relies on the protocol buffers compiler (protoc
) to generate
code. It uses a plugin to supplement the generated code by plain protoc
with gRPC-specific code. For a .proto
service description containing
gRPC services, the plain protoc
generated code is synthesized in
a _pb2.py
file, and the gRPC-specific code lands in a _pb2_grpc.py
file.
The latter python module imports the former. The focus of this page is
on the gRPC-specific subset of the generated code.
Example
Consider the following FortuneTeller
proto service:
service FortuneTeller {
// Returns the horoscope and zodiac sign for the given month and day.
rpc TellFortune(HoroscopeRequest) returns (HoroscopeResponse) {
// errors: invalid month or day, fortune unavailable
}
// Replaces the fortune for the given zodiac sign with the provided one.
rpc SuggestFortune(SuggestionRequest) returns (SuggestionResponse) {
// errors: invalid zodiac sign
}
}
When the service is compiled, the gRPC protoc
plugin generates code similar to
the following _pb2_grpc.py
file:
import grpc
import fortune_pb2
class FortuneTellerStub(object):
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.TellFortune = channel.unary_unary(
'/example.FortuneTeller/TellFortune',
request_serializer=fortune_pb2.HoroscopeRequest.SerializeToString,
response_deserializer=fortune_pb2.HoroscopeResponse.FromString,
)
self.SuggestFortune = channel.unary_unary(
'/example.FortuneTeller/SuggestFortune',
request_serializer=fortune_pb2.SuggestionRequest.SerializeToString,
response_deserializer=fortune_pb2.SuggestionResponse.FromString,
)
class FortuneTellerServicer(object):
def TellFortune(self, request, context):
"""Returns the horoscope and zodiac sign for the given month and day.
errors: invalid month or day, fortune unavailable
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SuggestFortune(self, request, context):
"""Replaces the fortune for the given zodiac sign with the provided
one.
errors: invalid zodiac sign
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_FortuneTellerServicer_to_server(servicer, server):
rpc_method_handlers = {
'TellFortune': grpc.unary_unary_rpc_method_handler(
servicer.TellFortune,
request_deserializer=fortune_pb2.HoroscopeRequest.FromString,
response_serializer=fortune_pb2.HoroscopeResponse.SerializeToString,
),
'SuggestFortune': grpc.unary_unary_rpc_method_handler(
servicer.SuggestFortune,
request_deserializer=fortune_pb2.SuggestionRequest.FromString,
response_serializer=fortune_pb2.SuggestionResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'example.FortuneTeller', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
Code Elements
The gRPC generated code starts by importing the grpc
package and the plain
_pb2
module, synthesized by protoc
, which defines non-gRPC-specific code
elements, like the classes corresponding to protocol buffers messages and
descriptors used by reflection.
For each service Foo
in the .proto
file, three primary elements are
generated:
- Stub:
FooStub
used by the client to connect to a gRPC service. - Servicer:
FooServicer
used by the server to implement a gRPC service. - Registration Function:
add_FooServicer_to_server
function used to register a servicer with agrpc.Server
object.
Stub
The generated Stub
class is used by the gRPC clients. It
has a constructor that takes a grpc.Channel
object and initializes the
stub. For each method in the service, the initializer adds a corresponding
attribute to the stub object with the same name. Depending on the RPC type
(unary or streaming), the value of that attribute will be callable
objects of type
UnaryUnaryMultiCallable,
UnaryStreamMultiCallable,
StreamUnaryMultiCallable,
or
StreamStreamMultiCallable.
Servicer
For each service, a Servicer
class is generated, which
serves as the superclass of a service implementation. For
each method in the service, a corresponding function in the Servicer
class
is generated. Override this function with the service
implementation. Comments associated with code elements
in the .proto
file appear as docstrings in
the generated python code.
Registration Function
For each service, a function is
generated that registers a Servicer
object implementing it on a grpc.Server
object, so that the server can route queries to
the respective servicer. This function takes an object that implements the
Servicer
, typically an instance of a subclass of the generated Servicer
code element described above, and a
grpc.Server
object.