mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-16 01:07:29 +00:00
[gRPC] Update the code generator for Python to produce typed handlers (#8326)
* Move `namer.h` and `idl_namer.h` to `include/codegen` so they can be reused from `grpc` dirqectory. * [gRPC] Update the Python generator to produce typed handlers and Python stubs if requested. * [gRPC] Document the newly added compiler flags.
This commit is contained in:
@@ -27,6 +27,7 @@ ${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs --g
|
||||
${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_extra.fbs --gen-object-api --python-typing --gen-compare
|
||||
${test_dir}/../flatc -p -o ${gen_code_path} -I include_test arrays_test.fbs --gen-object-api --python-typing
|
||||
${test_dir}/../flatc -p -o ${gen_code_path} -I include_test nested_union_test.fbs --gen-object-api --python-typing
|
||||
${test_dir}/../flatc -p -o ${gen_code_path} -I include_test service_test.fbs --grpc --grpc-python-typed-handlers --python-typing --no-python-gen-numpy --gen-onefile
|
||||
|
||||
# Syntax: run_tests <interpreter> <benchmark vtable dedupes>
|
||||
# <benchmark read count> <benchmark build count>
|
||||
|
||||
11
tests/service_test.fbs
Normal file
11
tests/service_test.fbs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace example;
|
||||
|
||||
table HelloRequest {}
|
||||
table HelloResponse {}
|
||||
|
||||
rpc_service HelloService {
|
||||
Hello(HelloRequest):HelloResponse;
|
||||
StreamClient(HelloRequest):HelloResponse (streaming: "client");
|
||||
StreamServer(HelloRequest):HelloResponse (streaming: "server");
|
||||
Stream(HelloRequest):HelloResponse (streaming: "bidi");
|
||||
}
|
||||
58
tests/service_test_generated.py
Normal file
58
tests/service_test_generated.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: example
|
||||
|
||||
import flatbuffers
|
||||
from typing import Any
|
||||
class HelloRequest(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf, offset: int = 0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
||||
x = HelloRequest()
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def GetRootAsHelloRequest(cls, buf, offset=0):
|
||||
"""This method is deprecated. Please switch to GetRootAs."""
|
||||
return cls.GetRootAs(buf, offset)
|
||||
# HelloRequest
|
||||
def Init(self, buf: bytes, pos: int):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
def HelloRequestStart(builder: flatbuffers.Builder):
|
||||
builder.StartObject(0)
|
||||
|
||||
def HelloRequestEnd(builder: flatbuffers.Builder) -> int:
|
||||
return builder.EndObject()
|
||||
|
||||
|
||||
|
||||
class HelloResponse(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf, offset: int = 0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
||||
x = HelloResponse()
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def GetRootAsHelloResponse(cls, buf, offset=0):
|
||||
"""This method is deprecated. Please switch to GetRootAs."""
|
||||
return cls.GetRootAs(buf, offset)
|
||||
# HelloResponse
|
||||
def Init(self, buf: bytes, pos: int):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
def HelloResponseStart(builder: flatbuffers.Builder):
|
||||
builder.StartObject(0)
|
||||
|
||||
def HelloResponseEnd(builder: flatbuffers.Builder) -> int:
|
||||
return builder.EndObject()
|
||||
|
||||
|
||||
|
||||
26
tests/service_test_generated.pyi
Normal file
26
tests/service_test_generated.pyi
Normal file
@@ -0,0 +1,26 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import flatbuffers
|
||||
|
||||
import flatbuffers
|
||||
import typing
|
||||
|
||||
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||
|
||||
class HelloRequest(object):
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf: bytes, offset: int) -> HelloRequest: ...
|
||||
@classmethod
|
||||
def GetRootAsHelloRequest(cls, buf: bytes, offset: int) -> HelloRequest: ...
|
||||
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||
def HelloRequestStart(builder: flatbuffers.Builder) -> None: ...
|
||||
def HelloRequestEnd(builder: flatbuffers.Builder) -> uoffset: ...
|
||||
class HelloResponse(object):
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf: bytes, offset: int) -> HelloResponse: ...
|
||||
@classmethod
|
||||
def GetRootAsHelloResponse(cls, buf: bytes, offset: int) -> HelloResponse: ...
|
||||
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||
def HelloResponseStart(builder: flatbuffers.Builder) -> None: ...
|
||||
def HelloResponseEnd(builder: flatbuffers.Builder) -> uoffset: ...
|
||||
|
||||
97
tests/service_test_grpc.fb.py
Normal file
97
tests/service_test_grpc.fb.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!
|
||||
|
||||
import flatbuffers
|
||||
import grpc
|
||||
|
||||
from service_test_generated import HelloRequest, HelloResponse
|
||||
|
||||
|
||||
def _serialize_to_bytes(table):
|
||||
buf = table._tab.Bytes
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0)
|
||||
if table._tab.Pos != n:
|
||||
raise ValueError('must be a top-level table')
|
||||
return bytes(buf)
|
||||
|
||||
|
||||
class HelloServiceStub(object):
|
||||
'''Interface exported by the server.'''
|
||||
|
||||
def __init__(self, channel):
|
||||
'''Constructor.
|
||||
|
||||
Args:
|
||||
channel: A grpc.Channel.
|
||||
'''
|
||||
|
||||
self.Hello = channel.unary_unary(
|
||||
method='/example.HelloService/Hello',
|
||||
request_serializer=_serialize_to_bytes,
|
||||
response_deserializer=HelloResponse.GetRootAs)
|
||||
|
||||
self.StreamClient = channel.stream_unary(
|
||||
method='/example.HelloService/StreamClient',
|
||||
request_serializer=_serialize_to_bytes,
|
||||
response_deserializer=HelloResponse.GetRootAs)
|
||||
|
||||
self.StreamServer = channel.unary_stream(
|
||||
method='/example.HelloService/StreamServer',
|
||||
request_serializer=_serialize_to_bytes,
|
||||
response_deserializer=HelloResponse.GetRootAs)
|
||||
|
||||
self.Stream = channel.stream_stream(
|
||||
method='/example.HelloService/Stream',
|
||||
request_serializer=_serialize_to_bytes,
|
||||
response_deserializer=HelloResponse.GetRootAs)
|
||||
|
||||
|
||||
class HelloServiceServicer(object):
|
||||
'''Interface exported by the server.'''
|
||||
|
||||
def Hello(self, request, context):
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def StreamClient(self, request_iterator, context):
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def StreamServer(self, request, context):
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def Stream(self, request_iterator, context):
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
|
||||
def add_HelloServiceServicer_to_server(servicer, server):
|
||||
rpc_method_handlers = {
|
||||
'Hello': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.Hello,
|
||||
request_deserializer=HelloRequest.GetRootAs,
|
||||
response_serializer=_serialize_to_bytes),
|
||||
'StreamClient': grpc.stream_unary_rpc_method_handler(
|
||||
servicer.StreamClient,
|
||||
request_deserializer=HelloRequest.GetRootAs,
|
||||
response_serializer=_serialize_to_bytes),
|
||||
'StreamServer': grpc.unary_stream_rpc_method_handler(
|
||||
servicer.StreamServer,
|
||||
request_deserializer=HelloRequest.GetRootAs,
|
||||
response_serializer=_serialize_to_bytes),
|
||||
'Stream': grpc.stream_stream_rpc_method_handler(
|
||||
servicer.Stream,
|
||||
request_deserializer=HelloRequest.GetRootAs,
|
||||
response_serializer=_serialize_to_bytes),
|
||||
}
|
||||
|
||||
generic_handler = grpc.method_handlers_generic_handler(
|
||||
'example.HelloService', rpc_method_handlers)
|
||||
|
||||
server.add_generic_rpc_handlers((generic_handler,))
|
||||
|
||||
|
||||
27
tests/service_test_grpc.fb.pyi
Normal file
27
tests/service_test_grpc.fb.pyi
Normal file
@@ -0,0 +1,27 @@
|
||||
# Generated by the gRPC FlatBuffers compiler. DO NOT EDIT!
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import grpc
|
||||
import typing
|
||||
|
||||
from service_test_generated import HelloRequest, HelloResponse
|
||||
|
||||
|
||||
class HelloServiceStub(object):
|
||||
def __init__(self, channel: grpc.Channel) -> None: ...
|
||||
def Hello(self, request: HelloRequest) -> HelloResponse: ...
|
||||
def StreamClient(self, request_iterator: typing.Iterator[HelloRequest]) -> HelloResponse: ...
|
||||
def StreamServer(self, request: HelloRequest) -> typing.Iterator[HelloResponse]: ...
|
||||
def Stream(self, request_iterator: typing.Iterator[HelloRequest]) -> typing.Iterator[HelloResponse]: ...
|
||||
|
||||
|
||||
class HelloServiceServicer(object):
|
||||
def Hello(self, request: HelloRequest, context: grpc.ServicerContext) -> HelloResponse: ...
|
||||
def StreamClient(self, request_iterator: typing.Iterator[HelloRequest], context: grpc.ServicerContext) -> HelloResponse: ...
|
||||
def StreamServer(self, request: HelloRequest, context: grpc.ServicerContext) -> typing.Iterator[HelloResponse]: ...
|
||||
def Stream(self, request_iterator: typing.Iterator[HelloRequest], context: grpc.ServicerContext) -> typing.Iterator[HelloResponse]: ...
|
||||
|
||||
|
||||
def add_HelloServiceServicer_to_server(servicer: HelloServiceServicer, server: grpc.Server) -> None: ...
|
||||
|
||||
Reference in New Issue
Block a user