Lay out bones of example

pull/19465/head
Richard Belleville 6 years ago
parent 51d6416691
commit 32944fdeb2
  1. 64
      examples/python/cancellation/BUILD.bazel
  2. 0
      examples/python/cancellation/README.md
  3. 41
      examples/python/cancellation/client.py
  4. 32
      examples/python/cancellation/hash_name.proto
  5. 117
      examples/python/cancellation/server.py
  6. 0
      examples/python/cancellation/test/_cancellation_example_test.py

@ -0,0 +1,64 @@
# gRPC Bazel BUILD file.
#
# Copyright 2019 The gRPC authors.
#
# 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.
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
load("//bazel:python_rules.bzl", "py_proto_library")
proto_library(
name = "hash_name_proto",
srcs = ["hash_name.proto"]
)
py_proto_library(
name = "hash_name_proto_pb2",
deps = [":hash_name_proto"],
well_known_protos = False,
)
py_binary(
name = "client",
testonly = 1,
srcs = ["client.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
":hash_name_proto_pb2",
],
srcs_version = "PY2AND3",
)
py_binary(
name = "server",
testonly = 1,
srcs = ["server.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
":hash_name_proto_pb2"
] + select({
"//conditions:default": [requirement("futures")],
"//:python3": [],
}),
srcs_version = "PY2AND3",
)
py_test(
name = "test/_cancellation_example_test",
srcs = ["test/_cancellation_example_test.py"],
data = [
":client",
":server"
],
size = "small",
)

@ -0,0 +1,41 @@
# Copyright the 2019 gRPC authors.
#
# 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 of cancelling requests in gRPC."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from concurrent import futures
import logging
import time
import grpc
from examples.python.cancellation import hash_name_pb2
from examples.python.cancellation import hash_name_pb2_grpc
_LOGGER = logging.getLogger(__name__)
def main():
# TODO(rbellevi): Fix the connaissance of target.
with grpc.insecure_channel('localhost:50051') as channel:
stub = hash_name_pb2_grpc.HashFinderStub(channel)
response = stub.Find(hash_name_pb2.HashNameRequest(desired_name="doctor",
maximum_hamming_distance=0))
print(response)
if __name__ == "__main__":
logging.basicConfig()
main()

@ -0,0 +1,32 @@
// Copyright 2019 the gRPC authors.
//
// 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.
syntax = "proto3";
package hash_name;
message HashNameRequest {
string desired_name = 1;
int32 maximum_hamming_distance = 2;
}
message HashNameResponse {
string secret = 1;
string hashed_name = 2;
int32 hamming_distance = 3;
}
service HashFinder {
rpc Find (HashNameRequest) returns (HashNameResponse) {}
}

@ -0,0 +1,117 @@
# Copyright the 2019 gRPC authors.
#
# 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 of cancelling requests in gRPC."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from concurrent import futures
from collections import deque
import base64
import logging
import hashlib
import struct
import time
import grpc
from examples.python.cancellation import hash_name_pb2
from examples.python.cancellation import hash_name_pb2_grpc
_LOGGER = logging.getLogger(__name__)
_SERVER_HOST = 'localhost'
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
def _get_hamming_distance(a, b):
"""Calculates hamming distance between strings of equal length."""
assert len(a) == len(b), "'{}', '{}'".format(a, b)
distance = 0
for char_a, char_b in zip(a, b):
if char_a.lower() != char_b.lower():
distance += 1
return distance
def _get_substring_hamming_distance(candidate, target):
"""Calculates the minimum hamming distance between between the target
and any substring of the candidate.
Args:
candidate: The string whose substrings will be tested.
target: The target string.
Returns:
The minimum Hamming distance between candidate and target.
"""
assert len(target) <= len(candidate)
assert len(candidate) != 0
min_distance = None
for i in range(len(candidate) - len(target) + 1):
distance = _get_hamming_distance(candidate[i:i+len(target)], target)
if min_distance is None or distance < min_distance:
min_distance = distance
return min_distance
def _get_hash(secret):
hasher = hashlib.sha256()
hasher.update(secret)
return base64.b64encode(hasher.digest())
class HashFinder(hash_name_pb2_grpc.HashFinderServicer):
# TODO(rbellevi): Make this use less memory.
def Find(self, request, context):
to_check = deque((i,) for i in range(256))
count = 0
while True:
if count % 1000 == 0:
logging.info("Checked {} hashes.".format(count))
current = to_check.popleft()
for i in range(256):
to_check.append(current + (i,))
secret = b''.join(struct.pack('B', i) for i in current)
hash = _get_hash(secret)
distance = _get_substring_hamming_distance(hash, request.desired_name)
if distance <= request.maximum_hamming_distance:
return hash_name_pb2.HashNameResponse(secret=base64.b64encode(secret),
hashed_name=hash,
hamming_distance=distance)
count += 1
def main():
port = 50051
server = grpc.server(futures.ThreadPoolExecutor())
hash_name_pb2_grpc.add_HashFinderServicer_to_server(
HashFinder(), server)
address = '{}:{}'.format(_SERVER_HOST, port)
server.add_insecure_port(address)
server.start()
print("Server listening at '{}'".format(address))
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(None)
pass
if __name__ == "__main__":
logging.basicConfig()
main()
Loading…
Cancel
Save