diff --git a/python/route_guide/.gitignore b/python/route_guide/.gitignore new file mode 100644 index 00000000000..0d20b6487c6 --- /dev/null +++ b/python/route_guide/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/python/route_guide/route_guide.proto b/python/route_guide/route_guide.proto new file mode 100644 index 00000000000..62567dfdd8a --- /dev/null +++ b/python/route_guide/route_guide.proto @@ -0,0 +1,119 @@ +// 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 = "proto2"; + +//TODO: see https://github.com/grpc/grpc/issues/814 +//package examples; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // 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 client-to-server streaming RPC. + // + // 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. + // + // 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) {} +} + +// 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 { + optional int32 latitude = 1; + optional int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + optional Point lo = 1; + + // The other corner of the rectangle. + optional Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + optional string name = 1; + + // The point where the feature is detected. + optional Point location = 2; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + optional Point location = 1; + + // The message to be sent. + optional string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + optional int32 point_count = 1; + + // The number of known features passed while traversing the route. + optional int32 feature_count = 2; + + // The distance covered in metres. + optional int32 distance = 3; + + // The duration of the traversal in seconds. + optional int32 elapsed_time = 4; +} diff --git a/python/route_guide/route_guide_client.py b/python/route_guide/route_guide_client.py new file mode 100755 index 00000000000..cdb453bb0f0 --- /dev/null +++ b/python/route_guide/route_guide_client.py @@ -0,0 +1,143 @@ +# 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 route guide client.""" + +import route_guide_pb2 + +import json +import random +import time + +_TIMEOUT_SECONDS = 30 + + +def read_route_guide_db(): + """Reads the route guide""" + feature_list = [] + with open("route_guide_db.json") as route_guide_db_file: + for item in json.load(route_guide_db_file): + feature = route_guide_pb2.Feature(name=item["name"]) + feature.location.longitude = item["location"]["longitude"] + feature.location.latitude = item["location"]["latitude"] + feature_list.append(feature) + return feature_list + + +def make_route_note(message, latitude, longitude): + route_note = route_guide_pb2.RouteNote(message=message) + route_note.location.latitude = latitude + route_note.location.longitude = longitude + return route_note + + +def guide_get_one_feature(stub, point): + feature = stub.GetFeature(point, _TIMEOUT_SECONDS) + if not feature.location: + print "Server returned incomplete feature" + return + + if feature.name: + print "Feature called %s at %s" % (feature.name, feature.location) + else: + print "Found no feature at %s" % feature.location + + +def guide_get_feature(stub): + guide_get_one_feature(stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906)) + guide_get_one_feature(stub, route_guide_pb2.Point(latitude=0, longitude=0)) + + +def guide_list_features(stub): + rect = route_guide_pb2.Rectangle() + rect.lo.latitude = 400000000 + rect.lo.longitude = -750000000 + rect.hi.latitude = 420000000 + rect.hi.longitude = -730000000 + print "Looking for features between 40, -75 and 42, -73" + + features = stub.ListFeatures(rect, _TIMEOUT_SECONDS) + + for feature in features: + print "Feature called %s at %s" % (feature.name, feature.location) + + +def generate_route(feature_list): + for index in range(0, 10): + random_feature = feature_list[random.randint(0, len(feature_list) - 1)] + print "Visiting point %s" % random_feature.location + yield random_feature.location + time.sleep(random.uniform(0.5, 1.5)) + + +def guide_record_route(stub): + feature_list = read_route_guide_db() + + route_iter = generate_route(feature_list) + route_summary = stub.RecordRoute(route_iter, _TIMEOUT_SECONDS) + print "Finished trip with %s points " % route_summary.point_count + print "Passed %s features " % route_summary.feature_count + print "Travelled %s meters " % route_summary.distance + print "It took %s seconds " % route_summary.elapsed_time + + +def generate_messages(): + messages = [ + make_route_note("First message", 0, 0), + make_route_note("Second message", 0, 1), + make_route_note("Third message", 1, 0), + make_route_note("Fourth message", 0, 0), + make_route_note("Fifth message", 1, 0), + ] + for msg in messages: + print "Sending %s at %s" % (msg.message, msg.location) + yield msg + time.sleep(random.uniform(0.5, 1.0)) + + +def guide_route_chat(stub): + responses = stub.RouteChat(generate_messages(), _TIMEOUT_SECONDS) + for response in responses: + print "Received message %s at %s" % (response.message, response.location) + + +def run(): + with route_guide_pb2.early_adopter_create_RouteGuide_stub('localhost', 50051) as stub: + print "-------------- GetFeature --------------" + guide_get_feature(stub); + print "-------------- ListFeatures --------------" + guide_list_features(stub); + print "-------------- RecordRoute --------------" + guide_record_route(stub); + print "-------------- RouteChat --------------" + guide_route_chat(stub); + + +if __name__ == '__main__': + run() diff --git a/python/route_guide/route_guide_db.json b/python/route_guide/route_guide_db.json new file mode 100644 index 00000000000..9d6a980ab7d --- /dev/null +++ b/python/route_guide/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/python/route_guide/route_guide_pb2.py b/python/route_guide/route_guide_pb2.py new file mode 100644 index 00000000000..2a4532bb750 --- /dev/null +++ b/python/route_guide/route_guide_pb2.py @@ -0,0 +1,370 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.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='route_guide.proto', + package='', + serialized_pb=_b('\n\x11route_guide.proto\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"3\n\tRectangle\x12\x12\n\x02lo\x18\x01 \x01(\x0b\x32\x06.Point\x12\x12\n\x02hi\x18\x02 \x01(\x0b\x32\x06.Point\"1\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x08location\x18\x02 \x01(\x0b\x32\x06.Point\"6\n\tRouteNote\x12\x18\n\x08location\x18\x01 \x01(\x0b\x32\x06.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\xad\x01\n\nRouteGuide\x12 \n\nGetFeature\x12\x06.Point\x1a\x08.Feature\"\x00\x12(\n\x0cListFeatures\x12\n.Rectangle\x1a\x08.Feature\"\x00\x30\x01\x12(\n\x0bRecordRoute\x12\x06.Point\x1a\r.RouteSummary\"\x00(\x01\x12)\n\tRouteChat\x12\n.RouteNote\x1a\n.RouteNote\"\x00(\x01\x30\x01') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_POINT = _descriptor.Descriptor( + name='Point', + full_name='Point', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='latitude', full_name='Point.latitude', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='longitude', full_name='Point.longitude', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + 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, + extension_ranges=[], + oneofs=[ + ], + serialized_start=21, + serialized_end=65, +) + + +_RECTANGLE = _descriptor.Descriptor( + name='Rectangle', + full_name='Rectangle', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='lo', full_name='Rectangle.lo', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='hi', full_name='Rectangle.hi', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + 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, + extension_ranges=[], + oneofs=[ + ], + serialized_start=67, + serialized_end=118, +) + + +_FEATURE = _descriptor.Descriptor( + name='Feature', + full_name='Feature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='Feature.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), + _descriptor.FieldDescriptor( + name='location', full_name='Feature.location', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + 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, + extension_ranges=[], + oneofs=[ + ], + serialized_start=120, + serialized_end=169, +) + + +_ROUTENOTE = _descriptor.Descriptor( + name='RouteNote', + full_name='RouteNote', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='location', full_name='RouteNote.location', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='message', full_name='RouteNote.message', index=1, + number=2, 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, + extension_ranges=[], + oneofs=[ + ], + serialized_start=171, + serialized_end=225, +) + + +_ROUTESUMMARY = _descriptor.Descriptor( + name='RouteSummary', + full_name='RouteSummary', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='point_count', full_name='RouteSummary.point_count', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='feature_count', full_name='RouteSummary.feature_count', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='distance', full_name='RouteSummary.distance', index=2, + number=3, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='elapsed_time', full_name='RouteSummary.elapsed_time', index=3, + number=4, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + 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, + extension_ranges=[], + oneofs=[ + ], + serialized_start=227, + serialized_end=325, +) + +_RECTANGLE.fields_by_name['lo'].message_type = _POINT +_RECTANGLE.fields_by_name['hi'].message_type = _POINT +_FEATURE.fields_by_name['location'].message_type = _POINT +_ROUTENOTE.fields_by_name['location'].message_type = _POINT +DESCRIPTOR.message_types_by_name['Point'] = _POINT +DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE +DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE +DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE +DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY + +Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict( + DESCRIPTOR = _POINT, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Point) + )) +_sym_db.RegisterMessage(Point) + +Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict( + DESCRIPTOR = _RECTANGLE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Rectangle) + )) +_sym_db.RegisterMessage(Rectangle) + +Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict( + DESCRIPTOR = _FEATURE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:Feature) + )) +_sym_db.RegisterMessage(Feature) + +RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict( + DESCRIPTOR = _ROUTENOTE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:RouteNote) + )) +_sym_db.RegisterMessage(RouteNote) + +RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict( + DESCRIPTOR = _ROUTESUMMARY, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:RouteSummary) + )) +_sym_db.RegisterMessage(RouteSummary) + + +import abc +from grpc._adapter import fore +from grpc._adapter import rear +from grpc.framework.assembly import implementations +from grpc.framework.assembly import utilities +class EarlyAdopterRouteGuideServicer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def GetFeature(self, request): + raise NotImplementedError() + @abc.abstractmethod + def ListFeatures(self, request): + raise NotImplementedError() + @abc.abstractmethod + def RecordRoute(self, request_iterator): + raise NotImplementedError() + @abc.abstractmethod + def RouteChat(self, request_iterator): + raise NotImplementedError() +class EarlyAdopterRouteGuideServer(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def start(self): + raise NotImplementedError() + @abc.abstractmethod + def stop(self): + raise NotImplementedError() +class EarlyAdopterRouteGuideStub(object): + """""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def GetFeature(self, request): + raise NotImplementedError() + GetFeature.async = None + @abc.abstractmethod + def ListFeatures(self, request): + raise NotImplementedError() + ListFeatures.async = None + @abc.abstractmethod + def RecordRoute(self, request_iterator): + raise NotImplementedError() + RecordRoute.async = None + @abc.abstractmethod + def RouteChat(self, request_iterator): + raise NotImplementedError() + RouteChat.async = None +def early_adopter_create_RouteGuide_server(servicer, port, root_certificates, key_chain_pairs): + method_implementations = { + "GetFeature": utilities.unary_unary_inline(servicer.GetFeature), + "ListFeatures": utilities.unary_stream_inline(servicer.ListFeatures), + "RecordRoute": utilities.stream_unary_inline(servicer.RecordRoute), + "RouteChat": utilities.stream_stream_inline(servicer.RouteChat), + } + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + request_deserializers = { + "GetFeature": route_guide_pb2.Point.FromString, + "ListFeatures": route_guide_pb2.Rectangle.FromString, + "RecordRoute": route_guide_pb2.Point.FromString, + "RouteChat": route_guide_pb2.RouteNote.FromString, + } + response_serializers = { + "GetFeature": lambda x: x.SerializeToString(), + "ListFeatures": lambda x: x.SerializeToString(), + "RecordRoute": lambda x: x.SerializeToString(), + "RouteChat": lambda x: x.SerializeToString(), + } + link = fore.activated_fore_link(port, request_deserializers, response_serializers, root_certificates, key_chain_pairs) + return implementations.assemble_service(method_implementations, link) +def early_adopter_create_RouteGuide_stub(host, port): + method_implementations = { + "GetFeature": utilities.unary_unary_inline(None), + "ListFeatures": utilities.unary_stream_inline(None), + "RecordRoute": utilities.stream_unary_inline(None), + "RouteChat": utilities.stream_stream_inline(None), + } + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + import route_guide_pb2 + response_deserializers = { + "GetFeature": route_guide_pb2.Feature.FromString, + "ListFeatures": route_guide_pb2.Feature.FromString, + "RecordRoute": route_guide_pb2.RouteSummary.FromString, + "RouteChat": route_guide_pb2.RouteNote.FromString, + } + request_serializers = { + "GetFeature": lambda x: x.SerializeToString(), + "ListFeatures": lambda x: x.SerializeToString(), + "RecordRoute": lambda x: x.SerializeToString(), + "RouteChat": lambda x: x.SerializeToString(), + } + link = rear.activated_rear_link(host, port, request_serializers, response_deserializers) + return implementations.assemble_dynamic_inline_stub(method_implementations, link) +# @@protoc_insertion_point(module_scope) diff --git a/python/route_guide/route_guide_server.py b/python/route_guide/route_guide_server.py new file mode 100644 index 00000000000..51cbd0dc846 --- /dev/null +++ b/python/route_guide/route_guide_server.py @@ -0,0 +1,147 @@ +# 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 route guide server.""" + +import json +import time +import math + +import route_guide_pb2 + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def read_route_guide_db(): + """Reads the route guide""" + feature_list = [] + with open("route_guide_db.json") as route_guide_db_file: + for item in json.load(route_guide_db_file): + feature = route_guide_pb2.Feature(name=item["name"]) + feature.location.longitude = item["location"]["longitude"] + feature.location.latitude = item["location"]["latitude"] + feature_list.append(feature) + return feature_list + + +def get_feature(feature_db, point): + """Returns feature at given location or None""" + for feature in feature_db: + if feature.location == point: + return feature + return None + + +def get_distance(start, end): + """Distance between two points""" + coord_factor = 10000000.0 + lat_1 = start.latitude / coord_factor + lat_2 = end.latitude / coord_factor + lon_1 = start.latitude / coord_factor + lon_2 = end.longitude / coord_factor + lat_rad_1 = math.radians(lat_1) + lat_rad_2 = math.radians(lat_2) + delta_lat_rad = math.radians(lat_2 - lat_1) + delta_lon_rad = math.radians(lon_2 - lon_1) + + a = pow(math.sin(delta_lat_rad / 2), 2) + math.cos(lat_rad_1) * math.cos(lat_rad_2) * pow(math.sin(delta_lon_rad / 2), 2) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) + R = 6371000; # metres + return R * c; + +class RouteGuideServicer(route_guide_pb2.EarlyAdopterRouteGuideServicer): + """Provides methods that implement functionality of route guide server.""" + + def __init__(self): + self.db = read_route_guide_db() + + def GetFeature(self, request, context): + feature = get_feature(self.db, request) + if not feature: + feature = route_guide_pb2.Feature(name="") + feature.location.longitude = request.longitude + feature.location.latitude = request.latitude + return feature + + def ListFeatures(self, request, context): + lo = request.lo + hi = request.hi + left = min(lo.longitude, hi.longitude) + right = max(lo.longitude, hi.longitude) + top = max(lo.latitude, hi.latitude) + bottom = min(lo.latitude, 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 + + 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)) + + 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) + + +def serve(): + server = route_guide_pb2.early_adopter_create_RouteGuide_server( + RouteGuideServicer(), 50051, None, None) + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop() + +if __name__ == '__main__': + serve() diff --git a/python/route_guide/run_client.sh b/python/route_guide/run_client.sh new file mode 100755 index 00000000000..d2552c2858c --- /dev/null +++ b/python/route_guide/run_client.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_client.py diff --git a/python/route_guide/run_codegen.sh b/python/route_guide/run_codegen.sh new file mode 100755 index 00000000000..689e0978de6 --- /dev/null +++ b/python/route_guide/run_codegen.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. +protoc -I . --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_python_plugin` route_guide.proto diff --git a/python/route_guide/run_server.sh b/python/route_guide/run_server.sh new file mode 100755 index 00000000000..8f759250c85 --- /dev/null +++ b/python/route_guide/run_server.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is where you have cloned out the https://github.com/grpc/grpc repository +# And built gRPC Python. +# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS +GRPC_ROOT=~/github/grpc + +$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_server.py