Skip to content

Commit 9036dcb

Browse files
wlu2016dpebot
authored andcommitted
add grpc bookstore python samples (#660)
1 parent aa8a463 commit 9036dcb

File tree

11 files changed

+1324
-1
lines changed

11 files changed

+1324
-1
lines changed

endpoints/bookstore-grpc/Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
ADD . /bookstore/
16+
17+
WORKDIR /bookstore
18+
RUN pip install -r requirements.txt
19+
20+
EXPOSE 8000
21+
22+
ENTRYPOINT ["python", "/bookstore/bookstore_server.py"]

endpoints/bookstore-grpc/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Google Cloud Endpoints Bookstore App in Python
2+
3+
## Installing the dependencies using virtualenv:
4+
5+
virtualenv bookstore-env
6+
source bookstore-env/bin/activate
7+
8+
Install all the Python dependencies:
9+
10+
pip install -r requirements.txt
11+
12+
Install the [gRPC libraries and tools](http://www.grpc.io/docs/quickstart/python.html#prerequisites)
13+
14+
## Running the Server Locally
15+
16+
To run the server:
17+
18+
python bookstore_server.py
19+
20+
The `-h` command line flag shows the various settings available.
21+
22+
## Running the Client Locally
23+
24+
To run the client:
25+
26+
python bookstore_client.py
27+
28+
As with the server, the `-h` command line flag shows the various settings
29+
available.
30+
31+
## Regenerating the API stubs
32+
33+
The bookstore gRPC API is defined by `bookstore.proto`
34+
The API client stubs and server interfaces are generated by tools.
35+
36+
To make it easier to get something up and running, we've included the generated
37+
code in the sample distribution. To modify the sample or create your own gRPC
38+
API definition, you'll need to update the generated code. To do this, once the
39+
gRPC libraries and tools are installed, run:
40+
41+
python -m grpc.tools.protoc --python_out=generated_pb2 \
42+
--grpc_python_out=generated_pb2 --proto_path=. bookstore.proto
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright 2016 Google Inc. All Rights Reserved.
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+
17+
syntax = "proto3";
18+
19+
package endpoints.examples.bookstore;
20+
21+
option java_multiple_files = true;
22+
option java_outer_classname = "BookstoreProto";
23+
option java_package = "com.google.endpoints.examples.bookstore";
24+
25+
26+
import "google/protobuf/empty.proto";
27+
28+
// A simple Bookstore API.
29+
//
30+
// The API manages shelves and books resources. Shelves contain books.
31+
service Bookstore {
32+
// Returns a list of all shelves in the bookstore.
33+
rpc ListShelves(google.protobuf.Empty) returns (ListShelvesResponse) {}
34+
// Creates a new shelf in the bookstore.
35+
rpc CreateShelf(CreateShelfRequest) returns (Shelf) {}
36+
// Returns a specific bookstore shelf.
37+
rpc GetShelf(GetShelfRequest) returns (Shelf) {}
38+
// Deletes a shelf, including all books that are stored on the shelf.
39+
rpc DeleteShelf(DeleteShelfRequest) returns (google.protobuf.Empty) {}
40+
// Returns a list of books on a shelf.
41+
rpc ListBooks(ListBooksRequest) returns (ListBooksResponse) {}
42+
// Creates a new book.
43+
rpc CreateBook(CreateBookRequest) returns (Book) {}
44+
// Returns a specific book.
45+
rpc GetBook(GetBookRequest) returns (Book) {}
46+
// Deletes a book from a shelf.
47+
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {}
48+
}
49+
50+
// A shelf resource.
51+
message Shelf {
52+
// A unique shelf id.
53+
int64 id = 1;
54+
// A theme of the shelf (fiction, poetry, etc).
55+
string theme = 2;
56+
}
57+
58+
// A book resource.
59+
message Book {
60+
// A unique book id.
61+
int64 id = 1;
62+
// An author of the book.
63+
string author = 2;
64+
// A book title.
65+
string title = 3;
66+
}
67+
68+
// Response to ListShelves call.
69+
message ListShelvesResponse {
70+
// Shelves in the bookstore.
71+
repeated Shelf shelves = 1;
72+
}
73+
74+
// Request message for CreateShelf method.
75+
message CreateShelfRequest {
76+
// The shelf resource to create.
77+
Shelf shelf = 1;
78+
}
79+
80+
// Request message for GetShelf method.
81+
message GetShelfRequest {
82+
// The ID of the shelf resource to retrieve.
83+
int64 shelf = 1;
84+
}
85+
86+
// Request message for DeleteShelf method.
87+
message DeleteShelfRequest {
88+
// The ID of the shelf to delete.
89+
int64 shelf = 1;
90+
}
91+
92+
// Request message for ListBooks method.
93+
message ListBooksRequest {
94+
// ID of the shelf which books to list.
95+
int64 shelf = 1;
96+
}
97+
98+
// Response message to ListBooks method.
99+
message ListBooksResponse {
100+
// The books on the shelf.
101+
repeated Book books = 1;
102+
}
103+
104+
// Request message for CreateBook method.
105+
message CreateBookRequest {
106+
// The ID of the shelf on which to create a book.
107+
int64 shelf = 1;
108+
// A book resource to create on the shelf.
109+
Book book = 2;
110+
}
111+
112+
// Request message for GetBook method.
113+
message GetBookRequest {
114+
// The ID of the shelf from which to retrieve a book.
115+
int64 shelf = 1;
116+
// The ID of the book to retrieve.
117+
int64 book = 2;
118+
}
119+
120+
// Request message for DeleteBook method.
121+
message DeleteBookRequest {
122+
// The ID of the shelf from which to delete a book.
123+
int64 shelf = 1;
124+
// The ID of the book to delete.
125+
int64 book = 2;
126+
}

endpoints/bookstore-grpc/bookstore.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright 2016 Google Inc. All Rights Reserved.
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+
import threading
16+
17+
18+
class ShelfInfo(object):
19+
"""The contents of a single shelf."""
20+
def __init__(self, shelf):
21+
self._shelf = shelf
22+
self._last_book_id = 0
23+
self._books = dict()
24+
25+
26+
class Bookstore(object):
27+
"""An in-memory backend for storing Bookstore data."""
28+
29+
def __init__(self):
30+
self._last_shelf_id = 0
31+
self._shelves = dict()
32+
self._lock = threading.Lock()
33+
34+
def list_shelf(self):
35+
with self._lock:
36+
return [s._shelf for (_, s) in self._shelves.iteritems()]
37+
38+
def create_shelf(self, shelf):
39+
with self._lock:
40+
self._last_shelf_id += 1
41+
shelf_id = self._last_shelf_id
42+
shelf.id = shelf_id
43+
self._shelves[shelf_id] = ShelfInfo(shelf)
44+
return (shelf, shelf_id)
45+
46+
def get_shelf(self, shelf_id):
47+
with self._lock:
48+
return self._shelves[shelf_id]._shelf
49+
50+
def delete_shelf(self, shelf_id):
51+
with self._lock:
52+
del self._shelves[shelf_id]
53+
54+
def list_books(self, shelf_id):
55+
with self._lock:
56+
return [book for (
57+
_, book) in self._shelves[shelf_id]._books.iteritems()]
58+
59+
def create_book(self, shelf_id, book):
60+
with self._lock:
61+
shelf_info = self._shelves[shelf_id]
62+
shelf_info._last_book_id += 1
63+
book_id = shelf_info._last_book_id
64+
book.id = book_id
65+
shelf_info._books[book_id] = book
66+
return book
67+
68+
def get_book(self, shelf_id, book_id):
69+
with self._lock:
70+
return self._shelves[shelf_id]._books[book_id]
71+
72+
def delete_book(self, shelf_id, book_id):
73+
with self._lock:
74+
del self._shelves[shelf_id]._books[book_id]
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright 2016 Google Inc. All Rights Reserved.
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+
"""The Python gRPC Bookstore Client Example."""
16+
17+
import argparse
18+
19+
from google.protobuf import empty_pb2
20+
21+
from generated_pb2 import bookstore_pb2
22+
import grpc
23+
24+
25+
def run(host, port, api_key, timeout):
26+
"""Makes a basic ListShelves call against a gRPC Bookstore server."""
27+
28+
channel = grpc.insecure_channel('{}:{}'.format(host, port))
29+
30+
stub = bookstore_pb2.BookstoreStub(channel)
31+
metadata = [('x-api-key', api_key)] if api_key else None
32+
shelves = stub.ListShelves(empty_pb2.Empty(), timeout, metadata=metadata)
33+
print('ListShelves: {}'.format(shelves))
34+
35+
36+
if __name__ == '__main__':
37+
parser = argparse.ArgumentParser(
38+
description=__doc__,
39+
formatter_class=argparse.RawDescriptionHelpFormatter)
40+
parser.add_argument(
41+
'--host', default='localhost', help='The host to connect to')
42+
parser.add_argument(
43+
'--port', type=int, default=8000, help='The port to connect to')
44+
parser.add_argument(
45+
'--timeout', type=int, default=10, help='The call timeout, in seconds')
46+
parser.add_argument(
47+
'--api_key', default=None, help='The API key to use for the call')
48+
args = parser.parse_args()
49+
run(args.host, args.port, args.api_key, args.timeout)

0 commit comments

Comments
 (0)