Skip to content

Instantly share code, notes, and snippets.

@mattbennett
Last active March 13, 2019 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattbennett/211accdbfbea5fcf3a61276d788651e4 to your computer and use it in GitHub Desktop.
Save mattbennett/211accdbfbea5fcf3a61276d788651e4 to your computer and use it in GitHub Desktop.
Nameko gRPC Example
*_pb2.py
*_pb2_grpc.py
__pycache__

This gist contains the complete example service referenced in the article announcing nameko-grpc.

Use the following steps to demonstrate a running service:

  1. Install requirements:

    pip install -r requirements.txt

    Note that this service also assumes you have a RabbitMQ broker running on localhost:5672.

  2. Generate code from the protocol buffer definitions:

    python -m grpc_tools.protoc --proto_path . --python_out . --grpc_python_out . helloworld.proto

    Or simply make codegen.

  3. Run the service:

    nameko run service --config config.yaml

  4. In another terminal, use the example client to call the service:

    python greeter_client.py ${NAME}

As well as replying to the client, the server will save a new Greeting entry into the SQLite database greetings.db. It will also have dispatched a Nameko Event to the RabbitMQ broker.

GRPC_BIND_PORT: 50051
AMQP_URI: pyamqp://guest:guest@localhost:5672/
SENTRY:
DSN: https://user:pass@localhost/00000
DB_URIS:
'Greeter:greetings': 'sqlite:///greetings.db'
# Copyright 2015 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.
"""The Python implementation of the GRPC helloworld.Greeter client."""
from __future__ import print_function
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
import sys
import getpass
try:
name = sys.argv[1]
except IndexError:
name = getpass.getuser()
def run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
with grpc.insecure_channel('localhost:50051') as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name=name))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
logging.basicConfig()
run()
syntax = "proto3";
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
codegen:
python -m grpc_tools.protoc --proto_path . --python_out . --grpc_python_out . helloworld.proto
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, Integer
DeclarativeBase = declarative_base(name='greetings')
class Greeting(DeclarativeBase):
__tablename__ = 'greetings'
id = Column(Integer, primary_key=True, auto_increment=True)
name = Column(String)
nameko-grpc
nameko-sqlalchemy
nameko-sentry
grpcio-tools
# import some extensions
from nameko.events import EventDispatcher
from nameko_sentry import SentryReporter
from nameko_sqlalchemy import Database
# import models for our app
from models import Greeting, DeclarativeBase
# import definitions generated from protobufs
import helloworld_pb2_grpc
from helloworld_pb2 import HelloReply
# set up the Grpc entrypoint to implement the Greeter stub
from nameko_grpc.entrypoint import Grpc
grpc = Grpc.implementing(helloworld_pb2_grpc.GreeterStub)
class Service:
name = "Greeter"
sentry = SentryReporter()
db = Database(DeclarativeBase)
dispatch_event = EventDispatcher()
@grpc
def SayHello(self, request, context):
# persist the greeting in RDBMS
greeting = Greeting(name=request.name)
self.db.session.add(greeting)
self.db.session.commit()
# dispatch a greeting event for subscribing services
self.dispatch_event("greeting", request.name)
# ... more application logic
return HelloReply(message='Hello, %s!' % request.name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment