Muffin-GRPC -- GRPC support for Muffin framework.
Features:
- Automatically build proto files and python helpers for them;
- Automatically connect to default channel;
- Automatically create and run GRPC server from your services;
Contents
- python >= 3.8
Note
The plugin supports only asyncio evenloop (not trio)
Muffin-GRPC should be installed using pip:
pip install muffin-grpc
Setup the plugin and connect it into your app:
from muffin import Application
from muffin_grpc import Plugin as GRPC
# Create Muffin Application
app = Application('example')
# Initialize the plugin
# As alternative: grpc = GRPC(app, **options)
grpc = GRPC(default_channel='server:50051')
grpc.setup(app)
Lets build a simple helloworld service, with the proto:
syntax = "proto3"; package helloworld; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
Put it somewhere and add the file into the grpc plugin:
grpc.add_proto('project_name/proto/helloworld.proto')
Run the command to build proto files:
$ muffin project_name grpc_build
The command will build the files:
project_name/proto/helloworld_pb2.py
- with the proto's messagesproject_name/proto/helloworld_pb2_grpc.py
- with the proto's GRPC servicesproject_name/proto/helloworld.py
- with the messages and services togetherproject_name/proto/__init__.py
- to make the build directory a package
Note
Muffin-GRPC fixes python imports automatically
Let's implement the Greeter service:
from .proto.helloworld import GreeterServicer, HelloRequest, HelloReply
# Connect the service to GRPC server
@grpc.add_to_server
class Greeter(GreeterServicer):
async def SayHello(self, request: HelloRequest,
context: grpc_aio.ServicerContext) -> HelloReply:
return HelloReply(message='Hello, %s!' % request.name)
Run the server with the command:
$ muffin package_name grpc_server
The server is working and accepts GRPC request, let's start building a client
from .proto.helloworld import GreeterStub, HelloRequest
@app.route('/')
async def index(request):
name = request.url.query.get('name') or 'anonymous'
try:
async with grpc.get_channel() as channel:
stub = GreeterStub(channel)
response = await stub.SayHello(
HelloRequest(name=request.url.query['name']), timeout=10)
message = response.message
except AioRpcError as exc:
message = exc.details()
return message
The /
endpoint will make a request to the GRPC server and return a message
from the server.
Name | Default value | Desctiption |
build_dir | None |
A directory to build proto files |
server_listen | "[::]:50051" |
Server address |
ssl_server | False |
Enable SSL for server |
ssl_server_params | None |
SSL Server Params |
ssl_client | False |
Enable SSL for client |
ssl_client_params | None |
SSL Client Params |
default_channel | localhost:50051 |
Default Client Channel Address |
default_channel_options | {} |
GRPC options for the default channel |
You are able to provide the options when you are initiliazing the plugin:
grpc.setup(app, server_listen='localhost:40000')
Or setup it from Muffin.Application
configuration using the GRPC_
prefix:
GRPC_SERVER_LISTERN = 'locahost:40000'
Muffin.Application
configuration options are case insensitive
$ muffin project_name grpc_build --help usage: muffin grpc_build [-h] Build registered proto files. optional arguments: -h, --help show this help message and exit
$ muffin project_name grpc_server --help usage: muffin grpc_server [-h] Start GRPC server with the registered endpoints. optional arguments: -h, --help show this help message and exit
If you have any suggestions, bug reports or annoyances please report them to the issue tracker at https://github.com/klen/muffin-grpc/issues
Development of Muffin-GRPC happens at: https://github.com/klen/muffin-grpc
- klen (Kirill Klenov)
Licensed under a MIT license.