gRPC Programming of Tensorflow (3)

Keywords: Python github git Google

This section is mainly about python's tutorial. here

gRPC Foundation: Python

This tutorial provides guidance for Python programmers on how to use gRPC.

By learning the examples in the tutorial, you can learn how to:

  • Define services in A. proto file.
  • Generate server and client code with protocol buffer compiler.
  • Use the Python API of gRPC to implement a simple client and server for your service.

Suppose you have read it. overview And familiar with protocol buffers . Note that the example in the tutorial uses proto3 version of protocol buffers language, which is currently only alpha version: you can proto3 Language Guide Github repository with protocol buffers Version Notes Find out more about the new version.

This is not a comprehensive guide to using gRPC in Python: there will be more references in the future.

Why use gRPC?

Our example is a simple routing mapping application that allows clients to obtain information about routing characteristics, generate summaries of routing, and interact with routing information, such as traffic updates for servers and other clients.

With gRPC, we can define services in A. proto file at one time and use any language that supports them to implement clients and servers. In turn, they can help you solve the communication duplication between different languages and environments in various environments, from Google's servers to your own tablet computer, gRPC. Heterogeneity. There are other benefits to using protocol buffers, including efficient serial numbers, simple IDL s, and easy interface updates.

Example code and settings

Here's the code for the tutorial grpc/grpc/examples/python/route_guide . To download the example, clone the grpc code base by running the following command:

$ git clone https://github.com/grpc/grpc.git

Change the current directory to examples/python/route_guide:

$ cd examples/python/route_guide

You also need to install tools to generate server and client interface code -- if you haven't already installed, check out the following setup guidelines Python Quick Start Guide.

Defining services

Your first step (from overview It is used. protocol buffers Define gRPC service and Method request and The type of response. You can be at examples/protos/route_guide.proto See the complete proto file.

To define a service, you must specify it in your. proto file service:

service RouteGuide {
   // (Method definitions not shown)
}

Then define it in your service rpc method, specifying the request and response type. gRPC allows you to define four types of service methods in RouteGuide services are available:

  • A simple RPC, where the client sends the request to the server using a stub and waits for the response to return, is like a normal function call.
   // Obtains the feature at a given position.
   rpc GetFeature(Point) returns (Feature) {}
  • A reply flow RPC, the client sends the request to the server and gets a stream to read the returned message sequence. The client reads the returned stream until there is no message in it. As you can see from the example, by inserting the stream keyword before the response type, you can specify a stream method on the server side.
  // Obtains the Features available within the given Rectangle.  Results are
  // streamed rather than returned at once (e.g. in a response message with a
  // repeated field), as the rectangle may cover a large area and contain a
  // huge number of features.
  rpc ListFeatures(Rectangle) returns (stream Feature) {}
  • A request flow RPC, where the client writes a message sequence and sends it to the server, also uses a stream. Once the client has finished writing the message, it waits for the server to complete reading and return its response. Specify a client's flow method by specifying the stream keyword before the request type.
  // Accepts a stream of Points on a route being traversed, returning a
  // RouteSummary when traversal is completed.
  rpc RecordRoute(stream Point) returns (RouteSummary) {}
  • A bidirectional streaming RPC is a sequence of messages sent by both parties using read and write streams. The two streams operate independently, so the client and server can read and write in any preferred order: for example, the server can wait to receive all client messages before writing the response, or can read and write messages alternately, or other combinations of reads and writes. The message order in each stream is reserved. You can type methods by adding stream keywords before requests and responses.
  // Accepts a stream of RouteNotes sent while a route is being traversed,
  // while receiving other RouteNotes (e.g. from other users).
  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}

Your. proto file also contains the protocol buffer message type definitions for all requests and the response types used in the service methods -- for example, the following Point message types:

// Points are represented as latitude-longitude pairs in the E7 representation
// (degrees multiplied by 10**7 and rounded to the nearest integer).
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {
  int32 latitude = 1;
  int32 longitude = 2;
}

Generating client-side and server-side code

Next you need to generate gRPC client-side and server-side interfaces from. proto's service definition. You can use the protocol buffer compiler Protoc and a special gRPC Python plug-in to complete. Make sure you have protoc installed and follow the gRPC Python plug-in installation instructions Operation.

Installed After protoc and gRPC Python plug-ins, use the following commands to generate Python code:

$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` ../../protos/route_guide.proto

Note that we have provided a version of the generated code in the sample code base. Running this command will regenerate the corresponding file instead of creating a new version. The generated code file is called route_guide_pb2.py and includes:

  • Message class defined in route_guide.proto
  • An abstract class of services defined in route_guide.proto
    • BetaRouteGuideServicer, The interface of RouteGuide service implementation is defined.
    • Beta Route Guide Stub, which can be activated by the client RouteGuide RPC
  • Functions used in applications
    • beta_create_RouteGuide_server to create a BetaRouteGuide Servicer object based on the existing BetaRouteGuide Servicer object gRPC Server
    • beta_create_RouteGuide_stub, which client can use to create a stub object

Create a server

Let's first look at how we can create a RouteGuide server. If you are only interested in creating gRPC clients, you can skip this section and go directly to Create Client (Of course, you may find it interesting too.)

Create and run RouteGuide services can be divided into two parts:

  • Implementing the generated service interface of our service definition: a function that does the actual "work" of our service.
  • Run a gRPC server to listen for requests from clients and transmit service responses.

You can go from examples/python/route_guide/route_guide_server.py See our Examples of RouteGuide servers.

Implementing RouteGuide

route_guide_server.py There is an implementation generated Route_guide_pb2. BetaRouteGuideService interface RouteGuideService class:

# RouteGuideServicer provides an implementation of the methods of the RouteGuide service.
class RouteGuideServicer(route_guide_pb2.BetaRouteGuideServicer):

RouteGuideServicer Realization All RouteGuide service methods:

Simple RPC

First let's look at the simplest types. GetFeature, which gets one from the client Point object, and then from the return contains feature information obtained from the database Feature.

  def GetFeature(self, request, context):
    feature = get_feature(self.db, request)
    if feature is None:
      return route_guide_pb2.Feature(name="", location=request)
    else:
      return feature

The method is introduced into a The RPC request for route_guide_pb2.Point and one that provides RPC-specific information, such as timeout limits, ServicerContext object.

Response Flow RPC

Now let's look at the next approach. List Features A reply stream RPC that sends multiple Feature to the client.

  def ListFeatures(self, request, context):
    left = min(request.lo.longitude, request.hi.longitude)
    right = max(request.lo.longitude, request.hi.longitude)
    top = max(request.lo.latitude, request.hi.latitude)
    bottom = min(request.lo.latitude, request.hi.latitude)
    for feature in self.db:
      if (feature.location.longitude >= left and
          feature.location.longitude <= right and
          feature.location.latitude >= bottom and
          feature.location.latitude <= top):
        yield feature

The request information here is route_guide_pb2.Rectangle, the client wants to find it here Feature. This method produces 0 or more responses rather than a single one.

Request flow RPC

Request flow method RecordRoute uses a request value iterator A single response value is returned.

  def RecordRoute(self, request_iterator, context):
    point_count = 0
    feature_count = 0
    distance = 0.0
    prev_point = None

    start_time = time.time()
    for point in request_iterator:
      point_count += 1
      if get_feature(self.db, point):
        feature_count += 1
      if prev_point:
        distance += get_distance(prev_point, point)
      prev_point = point

    elapsed_time = time.time() - start_time
    return route_guide_pb2.RouteSummary(point_count=point_count,
                                        feature_count=feature_count,
                                        distance=int(distance),
                                        elapsed_time=int(elapsed_time))

Bidirectional Flow RPC

Finally, let's look at the two-way flow method. RouteChat.

  def RouteChat(self, request_iterator, context):
    prev_notes = []
    for new_note in request_iterator:
      for prev_note in prev_notes:
        if prev_note.location == new_note.location:
          yield prev_note
      prev_notes.append(new_note)

The semantics of the method is a combination of request flow method and response flow method. It passes in an iterator of the request value and is itself an iterator of the response value.

Start the server

Once we have achieved all of them RouteGuide method, the next step is to start a gRPC server, so that the client can use the service:

def serve():
  server = route_guide_pb2.beta_create_RouteGuide_server(RouteGuideServicer())
  server.add_insecure_port('[::]:50051')
  server.start()

because start() won't block, and if your code doesn't have anything else to do at runtime, you may need to wait in a loop.

Create Client

You can be at examples/python/route_guide/route_guide_client.py See the complete example code.

Create a stub

In order to be able to invoke the method of the service, we first need to create a Roots.

We use the. proto generated The function beta_create_RouteGuide_stub of route_guide_pb2 module.

channel = implementations.insecure_channel('localhost', 50051)
stub = beta_create_RouteGuide_stub(channel)

The returned object is defined in the All objects in the BetaRouteGuideStub interface.

Calling service methods

For RPC methods that return a single response ("response-unary" method), gRPC Python supports both synchronous (blocking) and asynchronous (non-blocking) control flow semantics. For the reply flow RPC method, the call immediately returns an iterator of the reply value. Calling the iterator The next() method blocks until the response generated from the iterator becomes available.

Simple RPC

Simple RPC calls synchronously GetFeature is almost as intuitive as calling a local method. RPC calls wait for a server reply, either returning the reply or causing an exception:

feature = stub.GetFeature(point, timeout_in_seconds)

GetFeature Asynchronous invocation is similar to asynchronous invocation of a local method in a thread pool:

feature_future = stub.GetFeature.future(point, timeout_in_seconds)
feature = feature_future.result()

Response flow RPC

Call response flow ListFeatures are similar to using sequence types:

for feature in stub.ListFeatures(rectangle, timeout_in_seconds):

Request flow RPC

Call request flow RecordRoute is similar to passing in a sequence to a local method. Like the previous simple RPC, it also returns a single response that can be invoked synchronously or asynchronously:

route_summary = stub.RecordRoute(point_sequence, timeout_in_seconds)
route_summary_future = stub.RecordRoute.future(point_sequence, timeout_in_seconds)
route_summary = route_summary_future.result()

Bidirectional flow RPC

Call bidirectional flow RouteChat is a combination of request flow and response flow semantics (this scenario is on the server side):

for received_route_note in stub.RouteChat(sent_routes, timeout_in_seconds):

Come and try!

Running the server, it will listen on port 50051:

$ python route_guide_server.py

Run the client on another terminal:

$ python route_guide_client.py

Posted by anne13 on Wed, 10 Jul 2019 16:41:29 -0700