server.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # Copyright 2019 The gRPC Authors
  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. """This example sends out rich error status from server-side."""
  15. from concurrent import futures
  16. import logging
  17. import threading
  18. from google.protobuf import any_pb2
  19. from google.rpc import code_pb2
  20. from google.rpc import error_details_pb2
  21. from google.rpc import status_pb2
  22. import grpc
  23. from grpc_status import rpc_status
  24. from examples.protos import helloworld_pb2
  25. from examples.protos import helloworld_pb2_grpc
  26. def create_greet_limit_exceed_error_status(name):
  27. detail = any_pb2.Any()
  28. detail.Pack(
  29. error_details_pb2.QuotaFailure(violations=[
  30. error_details_pb2.QuotaFailure.Violation(
  31. subject="name: %s" % name,
  32. description="Limit one greeting per person",
  33. )
  34. ],))
  35. return status_pb2.Status(
  36. code=code_pb2.RESOURCE_EXHAUSTED,
  37. message='Request limit exceeded.',
  38. details=[detail],
  39. )
  40. class LimitedGreeter(helloworld_pb2_grpc.GreeterServicer):
  41. def __init__(self):
  42. self._lock = threading.RLock()
  43. self._greeted = set()
  44. def SayHello(self, request, context):
  45. with self._lock:
  46. if request.name in self._greeted:
  47. rich_status = create_greet_limit_exceed_error_status(
  48. request.name)
  49. context.abort_with_status(rpc_status.to_status(rich_status))
  50. else:
  51. self._greeted.add(request.name)
  52. return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
  53. def create_server(server_address):
  54. server = grpc.server(futures.ThreadPoolExecutor())
  55. helloworld_pb2_grpc.add_GreeterServicer_to_server(LimitedGreeter(), server)
  56. port = server.add_insecure_port(server_address)
  57. return server, port
  58. def serve(server):
  59. server.start()
  60. server.wait_for_termination()
  61. def main():
  62. server, unused_port = create_server('[::]:50051')
  63. serve(server)
  64. if __name__ == '__main__':
  65. logging.basicConfig()
  66. main()