Muffin-GRPC is a plugin for the Muffin framework that brings gRPC support to your application.
Contents
- 📦 Automatically compiles .proto files to Python
- ⚙️ Simplified gRPC server and client integration
- 🔁 CLI commands to manage proto compilation and server lifecycle
- 🧩 Automatically handles proto dependencies and import fixes
- 🧪 Designed with asyncio and modern Python standards
- Python >= 3.10
- grpcio
- grpcio-tools
- protobuf
- muffin
Note
This plugin supports only the asyncio event loop (Trio is not supported).
Install via pip:
pip install muffin-grpcSet up the plugin and attach it to your Muffin application:
from muffin import Application
from muffin_grpc import Plugin as GRPC
app = Application("example")
grpc = GRPC(default_channel="localhost:50051")
grpc.setup(app)Create a helloworld.proto:
syntax = "proto3";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}Register the file:
grpc.add_proto("project_name/proto/helloworld.proto")Compile proto files:
muffin project_name grpc_buildThis generates:
- helloworld_pb2.py — messages
- helloworld_pb2_grpc.py — gRPC services
- helloworld.py — bundled import helper
- __init__.py — so the folder is importable
Note
Muffin-GRPC automatically fixes Python imports.
Now implement the Greeter service:
from .proto.helloworld import GreeterServicer, HelloReply, HelloRequest
import grpc.aio as grpc_aio
@grpc.add_to_server
class Greeter(GreeterServicer):
async def SayHello(
self, request: HelloRequest, context: grpc_aio.ServicerContext
) -> HelloReply:
return HelloReply(message=f"Hello, {request.name}!")Run the gRPC server:
muffin project_name grpc_serverClient example:
from .proto.helloworld import GreeterStub, HelloRequest
from aiohttp.web import Application, Response
@app.route("/")
async def index(request):
name = request.url.query.get("name", "anonymous")
try:
async with grpc.get_channel() as channel:
stub = GreeterStub(channel)
response = await stub.SayHello(HelloRequest(name=name), timeout=10)
return Response(text=response.message)
except grpc_aio.AioRpcError as exc:
return Response(text=exc.details())You can configure the plugin either via setup() or using GRPC_ prefixed settings in the Muffin app config.
Available options:
| Name | Default value | Description |
|---|---|---|
| build_dir | None | Directory to store compiled files |
| server_listen | "[::]:50051" | gRPC server address |
| ssl_server | False | Enable SSL for server |
| ssl_server_params | None | Tuple of credentials for SSL server |
| ssl_client | False | Enable SSL for client |
| ssl_client_params | None | Tuple of credentials for SSL client |
| default_channel | "localhost:50051" | Default gRPC client target |
| default_channel_options | {} | Additional gRPC options |
Via setup():
grpc.setup(app, server_listen="localhost:40000")Or from config:
GRPC_SERVER_LISTEN = "localhost:40000"Build registered proto files:
muffin project_name grpc_buildStart the gRPC server:
muffin project_name grpc_serverFound a bug or have a suggestion? Submit an issue here: https://github.com/klen/muffin-grpc/issues
Want to contribute? Pull requests are welcome! Development happens at: https://github.com/klen/muffin-grpc
Licensed under the MIT license.