Skip to content

Commit 1915241

Browse files
committed
Refactor how registering grpcio servicer works
We now have a grpcio module in betterproto that defines the ServicerBase Abstract Base Class and a register_servicers function. Register_servicers takes multiple ServicerBase instances, and registers them to the grpc AIO server. The generated servicers now inherit from ServicerBase.
1 parent ce17577 commit 1915241

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ dataclasses = { version = "^0.7", python = ">=3.6, <3.7" }
1919
grpclib = "^0.4.1"
2020
jinja2 = { version = "^2.11.2", optional = true }
2121
protobuf = { version = "^3.12.2", optional = true }
22+
grpcio = { version = "^1.35.0", optional = true }
2223

2324
[tool.poetry.dev-dependencies]
2425
black = "^20.8b1"
@@ -42,6 +43,7 @@ protoc-gen-python_betterproto = "betterproto.plugin:main"
4243

4344
[tool.poetry.extras]
4445
compiler = ["black", "jinja2", "protobuf"]
46+
grpcio = ["grpcio"]
4547

4648
[tool.poe.tasks]
4749
# Dev workflow tasks

src/betterproto/grpc/grpcio_server.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from typing import Dict, TYPE_CHECKING
2+
from abc import ABC, abstractmethod
3+
4+
if TYPE_CHECKING:
5+
import grpc
6+
7+
class ServicerBase(ABC):
8+
"""
9+
Base class for async grpcio servers.
10+
"""
11+
12+
@property
13+
@abstractmethod
14+
def __rpc_methods__(self) -> Dict[str, "grpc.RpcMethodHandler"]:
15+
...
16+
17+
@property
18+
@abstractmethod
19+
def __proto_path__(self) -> str:
20+
...
21+
22+
23+
def register_servicers(server: "grpc.aio.Server", *servicers: ServicerBase):
24+
from grpc import method_handlers_generic_handler
25+
26+
server.add_generic_rpc_handlers(
27+
tuple(
28+
method_handlers_generic_handler(
29+
servicer.__proto_path__,
30+
servicer.__rpc_handlers__
31+
)
32+
for servicer in servicers
33+
)
34+
)

src/betterproto/templates/template.py.j2

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import grpclib
2323
{% endif %}
2424
{% if output_file.services and output_file.parent_request.options.grpc_kind == "grpcio" %}
2525
import grpc
26+
from betterproto.grpc.grpcio_server import ServicerBase
2627
{% endif %}
2728

2829

@@ -249,7 +250,7 @@ class {{ service.py_name }}Base(ServiceBase):
249250

250251
{% if output_file.parent_request.options.grpc_kind == "grpcio" %}
251252
{% for service in output_file.services %}
252-
class {{ service.py_name }}Base:
253+
class {{ service.py_name }}Base(ServicerBase):
253254
{% if service.comment %}
254255
{{ service.comment }}
255256

@@ -275,8 +276,11 @@ class {{ service.py_name }}Base:
275276

276277
{% endfor %}
277278

278-
def register_to_server(self, server: grpc.aio.Server):
279-
rpc_method_handlers = {
279+
__proto_path__ = "{{ service.proto_path }}"
280+
281+
@property
282+
def __rpc_methods__(self):
283+
return {
280284
{% for method in service.methods %}
281285
"{{ method.proto_name }}":
282286
{% if not method.client_streaming and not method.server_streaming %}
@@ -294,9 +298,6 @@ class {{ service.py_name }}Base:
294298
),
295299
{% endfor %}
296300
}
297-
generic_handler = grpc.method_handlers_generic_handler(
298-
"{{ service.proto_path }}", rpc_method_handlers)
299-
server.add_generic_rpc_handlers((generic_handler,))
300301

301302
{% endfor %}
302303
{% endif %}

0 commit comments

Comments
 (0)