From 6c76b630d68e661d94edaafc5db1e6134df23a9a Mon Sep 17 00:00:00 2001 From: Ryan Matsumoto Date: Tue, 14 Mar 2017 16:54:13 -0700 Subject: [PATCH 1/5] Endpoints GRPC Python sample --- endpoints/getting-started-grpc/Dockerfile | 28 ++ endpoints/getting-started-grpc/README.md | 168 +++++++++++ .../getting-started-grpc/api_config.yaml | 36 +++ .../container-engine.yaml | 54 ++++ .../helloworld/.gitignore | 1 + .../getting-started-grpc/helloworld/README.md | 1 + .../helloworld/greeter_client.py | 65 +++++ .../helloworld/greeter_server.py | 66 +++++ .../helloworld/helloworld_pb2.py | 261 ++++++++++++++++++ .../helloworld/helloworld_pb2_grpc.py | 65 +++++ endpoints/getting-started-grpc/protos/BUILD | 37 +++ .../protos/helloworld.proto | 55 ++++ .../getting-started-grpc/requirements.txt | 2 + 13 files changed, 839 insertions(+) create mode 100644 endpoints/getting-started-grpc/Dockerfile create mode 100644 endpoints/getting-started-grpc/README.md create mode 100644 endpoints/getting-started-grpc/api_config.yaml create mode 100644 endpoints/getting-started-grpc/container-engine.yaml create mode 100644 endpoints/getting-started-grpc/helloworld/.gitignore create mode 100644 endpoints/getting-started-grpc/helloworld/README.md create mode 100644 endpoints/getting-started-grpc/helloworld/greeter_client.py create mode 100644 endpoints/getting-started-grpc/helloworld/greeter_server.py create mode 100644 endpoints/getting-started-grpc/helloworld/helloworld_pb2.py create mode 100644 endpoints/getting-started-grpc/helloworld/helloworld_pb2_grpc.py create mode 100644 endpoints/getting-started-grpc/protos/BUILD create mode 100644 endpoints/getting-started-grpc/protos/helloworld.proto create mode 100644 endpoints/getting-started-grpc/requirements.txt diff --git a/endpoints/getting-started-grpc/Dockerfile b/endpoints/getting-started-grpc/Dockerfile new file mode 100644 index 00000000000..ecdb54622bc --- /dev/null +++ b/endpoints/getting-started-grpc/Dockerfile @@ -0,0 +1,28 @@ +# The Google Cloud Platform Python runtime is based on Debian Jessie +# You can read more about the runtime at: +# https://github.com/GoogleCloudPlatform/python-runtime +FROM gcr.io/google_appengine/python + +# Create a virtualenv for dependencies. This isolates these packages from +# system-level packages. +RUN virtualenv /env + +# Setting these environment variables are the same as running +# source /env/bin/activate. +ENV VIRTUAL_ENV -p python3.5 /env +ENV PATH /env/bin:$PATH + +ADD . /hello/ + +WORKDIR /hello + +RUN pip install -r requirements.txt + +EXPOSE 8000 + +# Copy Server +COPY . /hello/ + +ENTRYPOINT [] + +CMD ["python", "helloworld/greeter_server.py"] diff --git a/endpoints/getting-started-grpc/README.md b/endpoints/getting-started-grpc/README.md new file mode 100644 index 00000000000..c3b7c50e369 --- /dev/null +++ b/endpoints/getting-started-grpc/README.md @@ -0,0 +1,168 @@ +# Endpoints Getting Started with gRPC & Python Quickstart + +It is assumed that you have a working Python environment and a Google +Cloud account and [SDK](https://cloud.google.com/sdk/) configured. + +1. Install dependencies using virtualenv: + + ```bash + virtualenv -p python3 env + source env/bin/activate + pip install -r requirements.txt + ``` + +1. Test running the code, optional: + + ```bash + # Run the server: + python helloworld/greeter_server.py + + # Open another command line tab and enter the virtual environment: + source env/bin/activate + + # In the new command line tab, run the client: + python helloworld/greeter_client.py + ``` + +1. The gRPC Services have already been generated in `helloworld/`. If you + change the proto, or just wish to regenerate these files, run: + + ```bash + python -m grpc_tools.protoc -I protos --python_out=helloworld --grpc_python_out=helloworld protos/helloworld.proto + ``` + +1. Generate the `out.pb` from the proto file. + + ```bash + python -m grpc_tools.protoc --include_imports --include_source_info -I protos protos/helloworld.proto --descriptor_set_out out.pb + ``` + +1. Edit, `api_config.yaml`. Replace `MY_PROJECT_ID` with your project id. + +1. Deploy your service config to Service Management: + + ```bash + gcloud service-management deploy out.pb api_config.yaml + # The Config ID should be printed out, looks like: 2017-02-01r0, remember this + + # set your project to make commands easier + GCLOUD_PROJECT= + + # Print out your Config ID again, in case you missed it + gcloud service-management configs list --service hellogrpc.endpoints.${GCLOUD_PROJECT}.cloud.goog + ``` + +1. Also get an API key from the Console's API Manager for use in the + client later. (https://console.cloud.google.com/apis/credentials) + +1. Enable the Cloud Build API: + + ```bash + gcloud service-management enable cloudbuild.googleapis.com + ``` + +1. Build a docker image for your gRPC server, store in your Registry + + ```bash + gcloud container builds submit --tag gcr.io/${GCLOUD_PROJECT}/python-grpc-hello:1.0 . + ``` + +1. Either deploy to GCE (below) or GKE (further down) + +### GCE + +1. Enable the Compute Engine API. + + ```bash + gcloud service-management enable compute-component.googleapis.com + ``` + +1. Create your instance and ssh in. + + ```bash + gcloud compute instances create grpc-host --image-family gci-stable --image-project google-containers --tags=http-server + gcloud compute ssh grpc-host + ``` + +1. Set some variables to make commands easier + + ```bash + GCLOUD_PROJECT=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google") + SERVICE_NAME=hellogrpc.endpoints.${GCLOUD_PROJECT}.cloud.goog + SERVICE_CONFIG_ID= + ``` + +1. Pull your credentials to access Container Registry, and run your + gRPC server container + + ```bash + /usr/share/google/dockercfg_update.sh + docker run -d --name=grpc-hello gcr.io/${GCLOUD_PROJECT}/python-grpc-hello:1.0 + ``` + +1. Run the Endpoints proxy + + ```bash + docker run --detach --name=esp \ + -p 80:9000 \ + --link=grpc-hello:grpc-hello \ + gcr.io/endpoints-release/endpoints-runtime:1 \ + -s ${SERVICE_NAME} \ + -v ${SERVICE_CONFIG_ID} \ + -P 9000 \ + -a grpc://grpc-hello:50051 + ``` + +1. Back on your local machine, get the external IP of your GCE instance. + + ```bash + gcloud compute instances list + ``` + +1. Run the client + + ```bash + python helloworld/greeter_client.py --host=:80 --api_key= + ``` + +1. Cleanup + + ```bash + gcloud compute instances delete grpc-host + ``` + +### GKE + +1. Create a cluster. You can specify a different zone than us-central1-a if you + want. + + ```bash + gcloud container clusters create my-cluster --zone=us-central1-a + ``` + +1. Edit `container-engine.yaml`. Replace `SERVICE_NAME`, + `SERVICE_CONFIG_ID`, and `GCLOUD_PROJECT` with your values. + +1. Deploy to GKE + + ```bash + kubectl create -f ./container-engine.yaml + ``` + +1. Get IP of load balancer, run until you see an External IP. + + ```bash + kubectl get svc grpc-hello + ``` + +1. Run the client + + ```bash + python helloworld/greeter_client.py :80 + ``` + +1. Cleanup + + ```bash + gcloud container clusters delete my-cluster --zone=us-central1-a + ``` diff --git a/endpoints/getting-started-grpc/api_config.yaml b/endpoints/getting-started-grpc/api_config.yaml new file mode 100644 index 00000000000..eb521979979 --- /dev/null +++ b/endpoints/getting-started-grpc/api_config.yaml @@ -0,0 +1,36 @@ +# Copyright 2017 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# An example API configuration. +# +# Below, replace MY_PROJECT_ID with your Google Cloud Project ID. +# + +# The configuration schema is defined by service.proto file +# https://github.com/googleapis/googleapis/blob/master/google/api/service.proto +type: google.api.Service +config_version: 3 + +# +# Name of the service configuration. +# +name: hellogrpc.endpoints.MY_PROJECT_ID.cloud.goog + +# +# API title to appear in the user interface (Google Cloud Console). +# +title: Hello gRPC API +apis: +- name: helloworld.Greeter diff --git a/endpoints/getting-started-grpc/container-engine.yaml b/endpoints/getting-started-grpc/container-engine.yaml new file mode 100644 index 00000000000..20c0d7eb7f7 --- /dev/null +++ b/endpoints/getting-started-grpc/container-engine.yaml @@ -0,0 +1,54 @@ +# Copyright 2017 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + name: grpc-hello +spec: + ports: + - port: 80 + targetPort: 9000 + protocol: TCP + name: http + selector: + app: grpc-hello + type: LoadBalancer +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: grpc-hello +spec: + replicas: 1 + template: + metadata: + labels: + app: grpc-hello + spec: + containers: + - name: esp + image: gcr.io/endpoints-release/endpoints-runtime:1 + args: [ + "-P", "9000", + "-a", "grpc://127.0.0.1:50051", + "-s", "SERVICE_NAME", + "-v", "SERVICE_CONFIG_ID", + ] + ports: + - containerPort: 9000 + - name: python-grpc-hello + image: gcr.io/GCLOUD_PROJECT/python-grpc-hello:1.0 + ports: + - containerPort: 50051 diff --git a/endpoints/getting-started-grpc/helloworld/.gitignore b/endpoints/getting-started-grpc/helloworld/.gitignore new file mode 100644 index 00000000000..0d20b6487c6 --- /dev/null +++ b/endpoints/getting-started-grpc/helloworld/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/endpoints/getting-started-grpc/helloworld/README.md b/endpoints/getting-started-grpc/helloworld/README.md new file mode 100644 index 00000000000..d801d0dbca7 --- /dev/null +++ b/endpoints/getting-started-grpc/helloworld/README.md @@ -0,0 +1 @@ +[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html) diff --git a/endpoints/getting-started-grpc/helloworld/greeter_client.py b/endpoints/getting-started-grpc/helloworld/greeter_client.py new file mode 100644 index 00000000000..3f756a8ad12 --- /dev/null +++ b/endpoints/getting-started-grpc/helloworld/greeter_client.py @@ -0,0 +1,65 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""The Python implementation of the GRPC helloworld.Greeter client.""" + +from __future__ import print_function + +import argparse + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(host, api_key): + channel = grpc.insecure_channel(host) + stub = helloworld_pb2_grpc.GreeterStub(channel) + metadata = [] + if api_key: + metadata.append(('x-api-key', api_key)) + response = stub.SayHello( + helloworld_pb2.HelloRequest(name='you'), metadata=metadata) + print("Greeter client received: " + response.message) + response = stub.SayHelloAgain( + helloworld_pb2.HelloRequest(name='you'), metadata=metadata) + print("Greeter client received: " + response.message) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--host', default='localhost:50051', help='The server host.') + parser.add_argument( + '--api_key', default=None, help='The API key to use for the call.') + args = parser.parse_args() + run(args.host, args.api_key) diff --git a/endpoints/getting-started-grpc/helloworld/greeter_server.py b/endpoints/getting-started-grpc/helloworld/greeter_server.py new file mode 100644 index 00000000000..a45696e0b6c --- /dev/null +++ b/endpoints/getting-started-grpc/helloworld/greeter_server.py @@ -0,0 +1,66 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""The Python implementation of the GRPC helloworld.Greeter server.""" + +from concurrent import futures +import time + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def SayHello(self, request, context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + def SayHelloAgain(self, request, context): + return helloworld_pb2.HelloReply( + message='Hello again, %s!' % request.name) + + +def serve(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) + server.add_insecure_port('[::]:50051') + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(0) + + +if __name__ == '__main__': + serve() diff --git a/endpoints/getting-started-grpc/helloworld/helloworld_pb2.py b/endpoints/getting-started-grpc/helloworld/helloworld_pb2.py new file mode 100644 index 00000000000..67c18a3f7cc --- /dev/null +++ b/endpoints/getting-started-grpc/helloworld/helloworld_pb2.py @@ -0,0 +1,261 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='helloworld', + syntax='proto3', + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\x8e\x01\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x12\x43\n\rSayHelloAgain\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='helloworld.HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='helloworld.HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=32, + serialized_end=60, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='helloworld.HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='helloworld.HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=62, + serialized_end=91, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) +try: + # THESE ELEMENTS WILL BE DEPRECATED. + # Please use the generated *_pb2_grpc.py files instead. + import grpc + from grpc.framework.common import cardinality + from grpc.framework.interfaces.face import utilities as face_utilities + from grpc.beta import implementations as beta_implementations + from grpc.beta import interfaces as beta_interfaces + + + class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=HelloRequest.SerializeToString, + response_deserializer=HelloReply.FromString, + ) + self.SayHelloAgain = channel.unary_unary( + '/helloworld.Greeter/SayHelloAgain', + request_serializer=HelloRequest.SerializeToString, + response_deserializer=HelloReply.FromString, + ) + + + class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SayHelloAgain(self, request, context): + """Sends another greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + + def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=HelloRequest.FromString, + response_serializer=HelloReply.SerializeToString, + ), + 'SayHelloAgain': grpc.unary_unary_rpc_method_handler( + servicer.SayHelloAgain, + request_deserializer=HelloRequest.FromString, + response_serializer=HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + class BetaGreeterServicer(object): + """The Beta API is deprecated for 0.15.0 and later. + + It is recommended to use the GA API (classes and functions in this + file not marked beta) for all further purposes. This class was generated + only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" + """The greeting service definition. + """ + def SayHello(self, request, context): + """Sends a greeting + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def SayHelloAgain(self, request, context): + """Sends another greeting + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + + + class BetaGreeterStub(object): + """The Beta API is deprecated for 0.15.0 and later. + + It is recommended to use the GA API (classes and functions in this + file not marked beta) for all further purposes. This class was generated + only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0.""" + """The greeting service definition. + """ + def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """Sends a greeting + """ + raise NotImplementedError() + SayHello.future = None + def SayHelloAgain(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """Sends another greeting + """ + raise NotImplementedError() + SayHelloAgain.future = None + + + def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): + """The Beta API is deprecated for 0.15.0 and later. + + It is recommended to use the GA API (classes and functions in this + file not marked beta) for all further purposes. This function was + generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" + request_deserializers = { + ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString, + ('helloworld.Greeter', 'SayHelloAgain'): HelloRequest.FromString, + } + response_serializers = { + ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString, + ('helloworld.Greeter', 'SayHelloAgain'): HelloReply.SerializeToString, + } + method_implementations = { + ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello), + ('helloworld.Greeter', 'SayHelloAgain'): face_utilities.unary_unary_inline(servicer.SayHelloAgain), + } + server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) + return beta_implementations.server(method_implementations, options=server_options) + + + def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): + """The Beta API is deprecated for 0.15.0 and later. + + It is recommended to use the GA API (classes and functions in this + file not marked beta) for all further purposes. This function was + generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0""" + request_serializers = { + ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString, + ('helloworld.Greeter', 'SayHelloAgain'): HelloRequest.SerializeToString, + } + response_deserializers = { + ('helloworld.Greeter', 'SayHello'): HelloReply.FromString, + ('helloworld.Greeter', 'SayHelloAgain'): HelloReply.FromString, + } + cardinalities = { + 'SayHello': cardinality.Cardinality.UNARY_UNARY, + 'SayHelloAgain': cardinality.Cardinality.UNARY_UNARY, + } + stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) + return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options) +except ImportError: + pass +# @@protoc_insertion_point(module_scope) diff --git a/endpoints/getting-started-grpc/helloworld/helloworld_pb2_grpc.py b/endpoints/getting-started-grpc/helloworld/helloworld_pb2_grpc.py new file mode 100644 index 00000000000..58ab0c27dae --- /dev/null +++ b/endpoints/getting-started-grpc/helloworld/helloworld_pb2_grpc.py @@ -0,0 +1,65 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + +import helloworld_pb2 as helloworld__pb2 + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + self.SayHelloAgain = channel.unary_unary( + '/helloworld.Greeter/SayHelloAgain', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SayHelloAgain(self, request, context): + """Sends another greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + 'SayHelloAgain': grpc.unary_unary_rpc_method_handler( + servicer.SayHelloAgain, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/endpoints/getting-started-grpc/protos/BUILD b/endpoints/getting-started-grpc/protos/BUILD new file mode 100644 index 00000000000..7a40fae61de --- /dev/null +++ b/endpoints/getting-started-grpc/protos/BUILD @@ -0,0 +1,37 @@ +# Copyright 2017, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package(default_visibility = ["//visibility:public"]) + +load("//bazel:grpc_build_system.bzl", "grpc_proto_library") + +grpc_proto_library( + name = "helloworld", + srcs = ["helloworld.proto"], +) diff --git a/endpoints/getting-started-grpc/protos/helloworld.proto b/endpoints/getting-started-grpc/protos/helloworld.proto new file mode 100644 index 00000000000..5a89b906a9b --- /dev/null +++ b/endpoints/getting-started-grpc/protos/helloworld.proto @@ -0,0 +1,55 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.grpc.examples.helloworld"; +option java_outer_classname = "HelloWorldProto"; +option objc_class_prefix = "HLW"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} + // Sends another greeting + rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} diff --git a/endpoints/getting-started-grpc/requirements.txt b/endpoints/getting-started-grpc/requirements.txt new file mode 100644 index 00000000000..5e131f557a2 --- /dev/null +++ b/endpoints/getting-started-grpc/requirements.txt @@ -0,0 +1,2 @@ +grpcio==1.1.3 +grpcio-tools==1.1.3 From b7582905c56eb84d1793d9bc7800fce2b709dd47 Mon Sep 17 00:00:00 2001 From: Ryan Matsumoto Date: Wed, 15 Mar 2017 00:11:11 -0700 Subject: [PATCH 2/5] Made changes based on Jeff's first code review --- endpoints/getting-started-grpc/Dockerfile | 15 ++--- endpoints/getting-started-grpc/README.md | 66 +++++++++++-------- .../{helloworld => }/greeter_client.py | 0 .../{helloworld => }/greeter_server.py | 0 .../helloworld/.gitignore | 1 - .../getting-started-grpc/helloworld/README.md | 1 - .../{helloworld => }/helloworld_pb2.py | 4 +- .../{helloworld => }/helloworld_pb2_grpc.py | 0 endpoints/getting-started-grpc/protos/BUILD | 37 ----------- .../protos/helloworld.proto | 5 -- 10 files changed, 43 insertions(+), 86 deletions(-) rename endpoints/getting-started-grpc/{helloworld => }/greeter_client.py (100%) rename endpoints/getting-started-grpc/{helloworld => }/greeter_server.py (100%) delete mode 100644 endpoints/getting-started-grpc/helloworld/.gitignore delete mode 100644 endpoints/getting-started-grpc/helloworld/README.md rename endpoints/getting-started-grpc/{helloworld => }/helloworld_pb2.py (96%) rename endpoints/getting-started-grpc/{helloworld => }/helloworld_pb2_grpc.py (100%) delete mode 100644 endpoints/getting-started-grpc/protos/BUILD diff --git a/endpoints/getting-started-grpc/Dockerfile b/endpoints/getting-started-grpc/Dockerfile index ecdb54622bc..cf7e1b793dc 100644 --- a/endpoints/getting-started-grpc/Dockerfile +++ b/endpoints/getting-started-grpc/Dockerfile @@ -12,17 +12,10 @@ RUN virtualenv /env ENV VIRTUAL_ENV -p python3.5 /env ENV PATH /env/bin:$PATH -ADD . /hello/ - -WORKDIR /hello - -RUN pip install -r requirements.txt - -EXPOSE 8000 - -# Copy Server -COPY . /hello/ +COPY requirements.txt /tmp/ +RUN pip install --requirement /tmp/requirements.txt +COPY . /tmp/ ENTRYPOINT [] -CMD ["python", "helloworld/greeter_server.py"] +CMD ["python", "/tmp/greeter_server.py"] diff --git a/endpoints/getting-started-grpc/README.md b/endpoints/getting-started-grpc/README.md index c3b7c50e369..3025af616d8 100644 --- a/endpoints/getting-started-grpc/README.md +++ b/endpoints/getting-started-grpc/README.md @@ -15,23 +15,23 @@ Cloud account and [SDK](https://cloud.google.com/sdk/) configured. ```bash # Run the server: - python helloworld/greeter_server.py + python greeter_server.py # Open another command line tab and enter the virtual environment: source env/bin/activate # In the new command line tab, run the client: - python helloworld/greeter_client.py + python greeter_client.py ``` -1. The gRPC Services have already been generated in `helloworld/`. If you - change the proto, or just wish to regenerate these files, run: +1. The gRPC Services have already been generated. If you change the proto, or + just wish to regenerate these files, run: ```bash - python -m grpc_tools.protoc -I protos --python_out=helloworld --grpc_python_out=helloworld protos/helloworld.proto + python -m grpc_tools.protoc -I protos --python_out=. --grpc_python_out=. protos/helloworld.proto ``` -1. Generate the `out.pb` from the proto file. +1. Generate the `out.pb` from the proto file: ```bash python -m grpc_tools.protoc --include_imports --include_source_info -I protos protos/helloworld.proto --descriptor_set_out out.pb @@ -45,10 +45,10 @@ Cloud account and [SDK](https://cloud.google.com/sdk/) configured. gcloud service-management deploy out.pb api_config.yaml # The Config ID should be printed out, looks like: 2017-02-01r0, remember this - # set your project to make commands easier + # Set your project ID as a variable to make commands easier: GCLOUD_PROJECT= - # Print out your Config ID again, in case you missed it + # Print out your Config ID again, in case you missed it: gcloud service-management configs list --service hellogrpc.endpoints.${GCLOUD_PROJECT}.cloud.goog ``` @@ -61,30 +61,30 @@ Cloud account and [SDK](https://cloud.google.com/sdk/) configured. gcloud service-management enable cloudbuild.googleapis.com ``` -1. Build a docker image for your gRPC server, store in your Registry +1. Build a docker image for your gRPC server, and store it in your Registry: ```bash gcloud container builds submit --tag gcr.io/${GCLOUD_PROJECT}/python-grpc-hello:1.0 . ``` -1. Either deploy to GCE (below) or GKE (further down) +1. Either deploy to GCE (below) or GKE (further down). ### GCE -1. Enable the Compute Engine API. +1. Enable the Compute Engine API: ```bash gcloud service-management enable compute-component.googleapis.com ``` -1. Create your instance and ssh in. +1. Create your instance and ssh in: ```bash gcloud compute instances create grpc-host --image-family gci-stable --image-project google-containers --tags=http-server gcloud compute ssh grpc-host ``` -1. Set some variables to make commands easier +1. Set some variables to make commands easier: ```bash GCLOUD_PROJECT=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google") @@ -92,15 +92,15 @@ Cloud account and [SDK](https://cloud.google.com/sdk/) configured. SERVICE_CONFIG_ID= ``` -1. Pull your credentials to access Container Registry, and run your - gRPC server container +1. Pull your credentials to access Container Registry, and run your gRPC server + container: ```bash /usr/share/google/dockercfg_update.sh docker run -d --name=grpc-hello gcr.io/${GCLOUD_PROJECT}/python-grpc-hello:1.0 ``` -1. Run the Endpoints proxy +1. Run the Endpoints proxy: ```bash docker run --detach --name=esp \ @@ -113,19 +113,19 @@ Cloud account and [SDK](https://cloud.google.com/sdk/) configured. -a grpc://grpc-hello:50051 ``` -1. Back on your local machine, get the external IP of your GCE instance. +1. Back on your local machine, get the external IP of your GCE instance: ```bash gcloud compute instances list ``` -1. Run the client +1. Run the client: ```bash - python helloworld/greeter_client.py --host=:80 --api_key= + python greeter_client.py --host=:80 --api_key= ``` -1. Cleanup +1. Cleanup: ```bash gcloud compute instances delete grpc-host @@ -134,34 +134,44 @@ Cloud account and [SDK](https://cloud.google.com/sdk/) configured. ### GKE 1. Create a cluster. You can specify a different zone than us-central1-a if you - want. + want: ```bash gcloud container clusters create my-cluster --zone=us-central1-a ``` -1. Edit `container-engine.yaml`. Replace `SERVICE_NAME`, - `SERVICE_CONFIG_ID`, and `GCLOUD_PROJECT` with your values. +1. Edit `container-engine.yaml`. Replace `SERVICE_NAME`, `SERVICE_CONFIG_ID`, + and `GCLOUD_PROJECT` with your values: -1. Deploy to GKE + `SERVICE_NAME` is equal to hellogrpc.endpoints.GCLOUD_PROJECT.cloud.goog, + replacing GCLOUD_PROJECT with your project ID. + + `SERVICE_CONFIG_ID` can be found by running the following command, replacing + GCLOUD_PROJECT with your project ID. + + ```bash + gcloud service-management configs list --service hellogrpc.endpoints.GCLOUD_PROJECT.cloud.goog + ``` + +1. Deploy to GKE: ```bash kubectl create -f ./container-engine.yaml ``` -1. Get IP of load balancer, run until you see an External IP. +1. Get IP of load balancer, run until you see an External IP: ```bash kubectl get svc grpc-hello ``` -1. Run the client +1. Run the client: ```bash - python helloworld/greeter_client.py :80 + python greeter_client.py --host=:80 --api_key= ``` -1. Cleanup +1. Cleanup: ```bash gcloud container clusters delete my-cluster --zone=us-central1-a diff --git a/endpoints/getting-started-grpc/helloworld/greeter_client.py b/endpoints/getting-started-grpc/greeter_client.py similarity index 100% rename from endpoints/getting-started-grpc/helloworld/greeter_client.py rename to endpoints/getting-started-grpc/greeter_client.py diff --git a/endpoints/getting-started-grpc/helloworld/greeter_server.py b/endpoints/getting-started-grpc/greeter_server.py similarity index 100% rename from endpoints/getting-started-grpc/helloworld/greeter_server.py rename to endpoints/getting-started-grpc/greeter_server.py diff --git a/endpoints/getting-started-grpc/helloworld/.gitignore b/endpoints/getting-started-grpc/helloworld/.gitignore deleted file mode 100644 index 0d20b6487c6..00000000000 --- a/endpoints/getting-started-grpc/helloworld/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/endpoints/getting-started-grpc/helloworld/README.md b/endpoints/getting-started-grpc/helloworld/README.md deleted file mode 100644 index d801d0dbca7..00000000000 --- a/endpoints/getting-started-grpc/helloworld/README.md +++ /dev/null @@ -1 +0,0 @@ -[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html) diff --git a/endpoints/getting-started-grpc/helloworld/helloworld_pb2.py b/endpoints/getting-started-grpc/helloworld_pb2.py similarity index 96% rename from endpoints/getting-started-grpc/helloworld/helloworld_pb2.py rename to endpoints/getting-started-grpc/helloworld_pb2.py index 67c18a3f7cc..9a133df46e8 100644 --- a/endpoints/getting-started-grpc/helloworld/helloworld_pb2.py +++ b/endpoints/getting-started-grpc/helloworld_pb2.py @@ -19,7 +19,7 @@ name='helloworld.proto', package='helloworld', syntax='proto3', - serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\x8e\x01\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x12\x43\n\rSayHelloAgain\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\x8e\x01\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x12\x43\n\rSayHelloAgain\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -105,8 +105,6 @@ _sym_db.RegisterMessage(HelloReply) -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) try: # THESE ELEMENTS WILL BE DEPRECATED. # Please use the generated *_pb2_grpc.py files instead. diff --git a/endpoints/getting-started-grpc/helloworld/helloworld_pb2_grpc.py b/endpoints/getting-started-grpc/helloworld_pb2_grpc.py similarity index 100% rename from endpoints/getting-started-grpc/helloworld/helloworld_pb2_grpc.py rename to endpoints/getting-started-grpc/helloworld_pb2_grpc.py diff --git a/endpoints/getting-started-grpc/protos/BUILD b/endpoints/getting-started-grpc/protos/BUILD deleted file mode 100644 index 7a40fae61de..00000000000 --- a/endpoints/getting-started-grpc/protos/BUILD +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2017, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package(default_visibility = ["//visibility:public"]) - -load("//bazel:grpc_build_system.bzl", "grpc_proto_library") - -grpc_proto_library( - name = "helloworld", - srcs = ["helloworld.proto"], -) diff --git a/endpoints/getting-started-grpc/protos/helloworld.proto b/endpoints/getting-started-grpc/protos/helloworld.proto index 5a89b906a9b..68d8888e6e0 100644 --- a/endpoints/getting-started-grpc/protos/helloworld.proto +++ b/endpoints/getting-started-grpc/protos/helloworld.proto @@ -29,11 +29,6 @@ syntax = "proto3"; -option java_multiple_files = true; -option java_package = "io.grpc.examples.helloworld"; -option java_outer_classname = "HelloWorldProto"; -option objc_class_prefix = "HLW"; - package helloworld; // The greeting service definition. From 3915587ba32a090e5f467f3cc7ee877fe3c64a19 Mon Sep 17 00:00:00 2001 From: Ryan Matsumoto Date: Wed, 15 Mar 2017 17:51:52 -0700 Subject: [PATCH 3/5] Made changes based on Jon's code review --- endpoints/getting-started-grpc/Dockerfile | 8 ++++---- endpoints/getting-started-grpc/greeter_client.py | 6 ++---- endpoints/getting-started-grpc/greeter_server.py | 3 +++ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/endpoints/getting-started-grpc/Dockerfile b/endpoints/getting-started-grpc/Dockerfile index cf7e1b793dc..facd78e7d43 100644 --- a/endpoints/getting-started-grpc/Dockerfile +++ b/endpoints/getting-started-grpc/Dockerfile @@ -12,10 +12,10 @@ RUN virtualenv /env ENV VIRTUAL_ENV -p python3.5 /env ENV PATH /env/bin:$PATH -COPY requirements.txt /tmp/ -RUN pip install --requirement /tmp/requirements.txt -COPY . /tmp/ +COPY requirements.txt /app/ +RUN pip install --requirement /app/requirements.txt +COPY . /app/ ENTRYPOINT [] -CMD ["python", "/tmp/greeter_server.py"] +CMD ["python", "/app/greeter_server.py"] diff --git a/endpoints/getting-started-grpc/greeter_client.py b/endpoints/getting-started-grpc/greeter_client.py index 3f756a8ad12..bdbc1fc5ab7 100644 --- a/endpoints/getting-started-grpc/greeter_client.py +++ b/endpoints/getting-started-grpc/greeter_client.py @@ -29,8 +29,6 @@ """The Python implementation of the GRPC helloworld.Greeter client.""" -from __future__ import print_function - import argparse import grpc @@ -47,10 +45,10 @@ def run(host, api_key): metadata.append(('x-api-key', api_key)) response = stub.SayHello( helloworld_pb2.HelloRequest(name='you'), metadata=metadata) - print("Greeter client received: " + response.message) + print('Greeter client received: ' + response.message) response = stub.SayHelloAgain( helloworld_pb2.HelloRequest(name='you'), metadata=metadata) - print("Greeter client received: " + response.message) + print('Greeter client received: ' + response.message) if __name__ == '__main__': diff --git a/endpoints/getting-started-grpc/greeter_server.py b/endpoints/getting-started-grpc/greeter_server.py index a45696e0b6c..594c146d8d9 100644 --- a/endpoints/getting-started-grpc/greeter_server.py +++ b/endpoints/getting-started-grpc/greeter_server.py @@ -55,6 +55,9 @@ def serve(): helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() + + # gRPC starts a new thread to service requests. Just make the main thread + # sleep. try: while True: time.sleep(_ONE_DAY_IN_SECONDS) From e7ad7ccd5ed12577d1ca34c7dd4fe9d3738416da Mon Sep 17 00:00:00 2001 From: Ryan Matsumoto Date: Thu, 16 Mar 2017 14:42:28 -0700 Subject: [PATCH 4/5] fixed grace period issue --- endpoints/getting-started-grpc/greeter_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/endpoints/getting-started-grpc/greeter_server.py b/endpoints/getting-started-grpc/greeter_server.py index 594c146d8d9..07e2f9d1345 100644 --- a/endpoints/getting-started-grpc/greeter_server.py +++ b/endpoints/getting-started-grpc/greeter_server.py @@ -62,7 +62,7 @@ def serve(): while True: time.sleep(_ONE_DAY_IN_SECONDS) except KeyboardInterrupt: - server.stop(0) + server.stop(grace=0) if __name__ == '__main__': From 729c008f0bd01917b16f1b8c4bef342f69b2181d Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Mon, 20 Mar 2017 14:48:15 -0700 Subject: [PATCH 5/5] Make nox ignore pb2 and pb2_grpc files --- nox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nox.py b/nox.py index 3268f00c2d0..fe8159405cc 100644 --- a/nox.py +++ b/nox.py @@ -140,7 +140,7 @@ def _setup_appengine_sdk(session): FLAKE8_COMMON_ARGS = [ '--show-source', '--builtin', 'gettext', '--max-complexity', '20', '--import-order-style', 'google', - '--exclude', '.nox,.cache,env,lib,generated_pb2', + '--exclude', '.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py', ] # Location of our common testing utilities. This isn't published to PyPI.