Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e6a5ff4

Browse filesBrowse files
ryanmatsJon Wayne Parrott
authored andcommitted
Endpoints GRPC Python Sample (GoogleCloudPlatform#852)
1 parent 003c30c commit e6a5ff4
Copy full SHA for e6a5ff4

File tree

Expand file treeCollapse file tree

11 files changed

+798
-1
lines changed
Filter options
Expand file treeCollapse file tree

11 files changed

+798
-1
lines changed
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# The Google Cloud Platform Python runtime is based on Debian Jessie
2+
# You can read more about the runtime at:
3+
# https://github.com/GoogleCloudPlatform/python-runtime
4+
FROM gcr.io/google_appengine/python
5+
6+
# Create a virtualenv for dependencies. This isolates these packages from
7+
# system-level packages.
8+
RUN virtualenv /env
9+
10+
# Setting these environment variables are the same as running
11+
# source /env/bin/activate.
12+
ENV VIRTUAL_ENV -p python3.5 /env
13+
ENV PATH /env/bin:$PATH
14+
15+
COPY requirements.txt /app/
16+
RUN pip install --requirement /app/requirements.txt
17+
COPY . /app/
18+
19+
ENTRYPOINT []
20+
21+
CMD ["python", "/app/greeter_server.py"]
+178Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Endpoints Getting Started with gRPC & Python Quickstart
2+
3+
It is assumed that you have a working Python environment and a Google
4+
Cloud account and [SDK](https://cloud.google.com/sdk/) configured.
5+
6+
1. Install dependencies using virtualenv:
7+
8+
```bash
9+
virtualenv -p python3 env
10+
source env/bin/activate
11+
pip install -r requirements.txt
12+
```
13+
14+
1. Test running the code, optional:
15+
16+
```bash
17+
# Run the server:
18+
python greeter_server.py
19+
20+
# Open another command line tab and enter the virtual environment:
21+
source env/bin/activate
22+
23+
# In the new command line tab, run the client:
24+
python greeter_client.py
25+
```
26+
27+
1. The gRPC Services have already been generated. If you change the proto, or
28+
just wish to regenerate these files, run:
29+
30+
```bash
31+
python -m grpc_tools.protoc -I protos --python_out=. --grpc_python_out=. protos/helloworld.proto
32+
```
33+
34+
1. Generate the `out.pb` from the proto file:
35+
36+
```bash
37+
python -m grpc_tools.protoc --include_imports --include_source_info -I protos protos/helloworld.proto --descriptor_set_out out.pb
38+
```
39+
40+
1. Edit, `api_config.yaml`. Replace `MY_PROJECT_ID` with your project id.
41+
42+
1. Deploy your service config to Service Management:
43+
44+
```bash
45+
gcloud service-management deploy out.pb api_config.yaml
46+
# The Config ID should be printed out, looks like: 2017-02-01r0, remember this
47+
48+
# Set your project ID as a variable to make commands easier:
49+
GCLOUD_PROJECT=<Your Project ID>
50+
51+
# Print out your Config ID again, in case you missed it:
52+
gcloud service-management configs list --service hellogrpc.endpoints.${GCLOUD_PROJECT}.cloud.goog
53+
```
54+
55+
1. Also get an API key from the Console's API Manager for use in the
56+
client later. (https://console.cloud.google.com/apis/credentials)
57+
58+
1. Enable the Cloud Build API:
59+
60+
```bash
61+
gcloud service-management enable cloudbuild.googleapis.com
62+
```
63+
64+
1. Build a docker image for your gRPC server, and store it in your Registry:
65+
66+
```bash
67+
gcloud container builds submit --tag gcr.io/${GCLOUD_PROJECT}/python-grpc-hello:1.0 .
68+
```
69+
70+
1. Either deploy to GCE (below) or GKE (further down).
71+
72+
### GCE
73+
74+
1. Enable the Compute Engine API:
75+
76+
```bash
77+
gcloud service-management enable compute-component.googleapis.com
78+
```
79+
80+
1. Create your instance and ssh in:
81+
82+
```bash
83+
gcloud compute instances create grpc-host --image-family gci-stable --image-project google-containers --tags=http-server
84+
gcloud compute ssh grpc-host
85+
```
86+
87+
1. Set some variables to make commands easier:
88+
89+
```bash
90+
GCLOUD_PROJECT=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google")
91+
SERVICE_NAME=hellogrpc.endpoints.${GCLOUD_PROJECT}.cloud.goog
92+
SERVICE_CONFIG_ID=<Your Config ID>
93+
```
94+
95+
1. Pull your credentials to access Container Registry, and run your gRPC server
96+
container:
97+
98+
```bash
99+
/usr/share/google/dockercfg_update.sh
100+
docker run -d --name=grpc-hello gcr.io/${GCLOUD_PROJECT}/python-grpc-hello:1.0
101+
```
102+
103+
1. Run the Endpoints proxy:
104+
105+
```bash
106+
docker run --detach --name=esp \
107+
-p 80:9000 \
108+
--link=grpc-hello:grpc-hello \
109+
gcr.io/endpoints-release/endpoints-runtime:1 \
110+
-s ${SERVICE_NAME} \
111+
-v ${SERVICE_CONFIG_ID} \
112+
-P 9000 \
113+
-a grpc://grpc-hello:50051
114+
```
115+
116+
1. Back on your local machine, get the external IP of your GCE instance:
117+
118+
```bash
119+
gcloud compute instances list
120+
```
121+
122+
1. Run the client:
123+
124+
```bash
125+
python greeter_client.py --host=<IP of GCE Instance>:80 --api_key=<API Key from Console>
126+
```
127+
128+
1. Cleanup:
129+
130+
```bash
131+
gcloud compute instances delete grpc-host
132+
```
133+
134+
### GKE
135+
136+
1. Create a cluster. You can specify a different zone than us-central1-a if you
137+
want:
138+
139+
```bash
140+
gcloud container clusters create my-cluster --zone=us-central1-a
141+
```
142+
143+
1. Edit `container-engine.yaml`. Replace `SERVICE_NAME`, `SERVICE_CONFIG_ID`,
144+
and `GCLOUD_PROJECT` with your values:
145+
146+
`SERVICE_NAME` is equal to hellogrpc.endpoints.GCLOUD_PROJECT.cloud.goog,
147+
replacing GCLOUD_PROJECT with your project ID.
148+
149+
`SERVICE_CONFIG_ID` can be found by running the following command, replacing
150+
GCLOUD_PROJECT with your project ID.
151+
152+
```bash
153+
gcloud service-management configs list --service hellogrpc.endpoints.GCLOUD_PROJECT.cloud.goog
154+
```
155+
156+
1. Deploy to GKE:
157+
158+
```bash
159+
kubectl create -f ./container-engine.yaml
160+
```
161+
162+
1. Get IP of load balancer, run until you see an External IP:
163+
164+
```bash
165+
kubectl get svc grpc-hello
166+
```
167+
168+
1. Run the client:
169+
170+
```bash
171+
python greeter_client.py --host=<IP of GKE LoadBalancer>:80 --api_key=<API Key from Console>
172+
```
173+
174+
1. Cleanup:
175+
176+
```bash
177+
gcloud container clusters delete my-cluster --zone=us-central1-a
178+
```
+36Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright 2017 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
#
16+
# An example API configuration.
17+
#
18+
# Below, replace MY_PROJECT_ID with your Google Cloud Project ID.
19+
#
20+
21+
# The configuration schema is defined by service.proto file
22+
# https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
23+
type: google.api.Service
24+
config_version: 3
25+
26+
#
27+
# Name of the service configuration.
28+
#
29+
name: hellogrpc.endpoints.MY_PROJECT_ID.cloud.goog
30+
31+
#
32+
# API title to appear in the user interface (Google Cloud Console).
33+
#
34+
title: Hello gRPC API
35+
apis:
36+
- name: helloworld.Greeter
+54Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Copyright 2017 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: v1
16+
kind: Service
17+
metadata:
18+
name: grpc-hello
19+
spec:
20+
ports:
21+
- port: 80
22+
targetPort: 9000
23+
protocol: TCP
24+
name: http
25+
selector:
26+
app: grpc-hello
27+
type: LoadBalancer
28+
---
29+
apiVersion: extensions/v1beta1
30+
kind: Deployment
31+
metadata:
32+
name: grpc-hello
33+
spec:
34+
replicas: 1
35+
template:
36+
metadata:
37+
labels:
38+
app: grpc-hello
39+
spec:
40+
containers:
41+
- name: esp
42+
image: gcr.io/endpoints-release/endpoints-runtime:1
43+
args: [
44+
"-P", "9000",
45+
"-a", "grpc://127.0.0.1:50051",
46+
"-s", "SERVICE_NAME",
47+
"-v", "SERVICE_CONFIG_ID",
48+
]
49+
ports:
50+
- containerPort: 9000
51+
- name: python-grpc-hello
52+
image: gcr.io/GCLOUD_PROJECT/python-grpc-hello:1.0
53+
ports:
54+
- containerPort: 50051
+63Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright 2015, Google Inc.
2+
# All rights reserved.
3+
#
4+
# Redistribution and use in source and binary forms, with or without
5+
# modification, are permitted provided that the following conditions are
6+
# met:
7+
#
8+
# * Redistributions of source code must retain the above copyright
9+
# notice, this list of conditions and the following disclaimer.
10+
# * Redistributions in binary form must reproduce the above
11+
# copyright notice, this list of conditions and the following disclaimer
12+
# in the documentation and/or other materials provided with the
13+
# distribution.
14+
# * Neither the name of Google Inc. nor the names of its
15+
# contributors may be used to endorse or promote products derived from
16+
# this software without specific prior written permission.
17+
#
18+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
30+
"""The Python implementation of the GRPC helloworld.Greeter client."""
31+
32+
import argparse
33+
34+
import grpc
35+
36+
import helloworld_pb2
37+
import helloworld_pb2_grpc
38+
39+
40+
def run(host, api_key):
41+
channel = grpc.insecure_channel(host)
42+
stub = helloworld_pb2_grpc.GreeterStub(channel)
43+
metadata = []
44+
if api_key:
45+
metadata.append(('x-api-key', api_key))
46+
response = stub.SayHello(
47+
helloworld_pb2.HelloRequest(name='you'), metadata=metadata)
48+
print('Greeter client received: ' + response.message)
49+
response = stub.SayHelloAgain(
50+
helloworld_pb2.HelloRequest(name='you'), metadata=metadata)
51+
print('Greeter client received: ' + response.message)
52+
53+
54+
if __name__ == '__main__':
55+
parser = argparse.ArgumentParser(
56+
description=__doc__,
57+
formatter_class=argparse.RawDescriptionHelpFormatter)
58+
parser.add_argument(
59+
'--host', default='localhost:50051', help='The server host.')
60+
parser.add_argument(
61+
'--api_key', default=None, help='The API key to use for the call.')
62+
args = parser.parse_args()
63+
run(args.host, args.api_key)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.