summaryrefslogtreecommitdiff
path: root/grpc/examples
diff options
context:
space:
mode:
authormustiikhalil <mustii@mmk.one>2021-02-26 01:38:12 +0300
committerGitHub <noreply@github.com>2021-02-25 14:38:12 -0800
commit8142fedd196e20d24c48485396821b12034e7eb9 (patch)
treeefc31d19a822e6fa11e69d31c3b16ccce4aa6a18 /grpc/examples
parentc0be1cb7a51f1c50e057469de94f3a3bb7dfcb64 (diff)
downloadflatbuffers-8142fedd196e20d24c48485396821b12034e7eb9.tar.gz
flatbuffers-8142fedd196e20d24c48485396821b12034e7eb9.tar.bz2
flatbuffers-8142fedd196e20d24c48485396821b12034e7eb9.zip
Working on a python example plus fixing python grpc code (#6456)
Refactored python grpc code gen Adds example server & client + fixes ci Fixes generated code Making sure we encode the reply string as utf8 Adds Readme details to clarify issue regarding encoding when python is sending/receiving
Diffstat (limited to 'grpc/examples')
-rw-r--r--grpc/examples/README.md28
-rw-r--r--grpc/examples/generate.sh19
-rw-r--r--grpc/examples/python/greeter/README.md12
-rw-r--r--grpc/examples/python/greeter/client.py40
-rw-r--r--grpc/examples/python/greeter/models/HelloReply.py45
-rw-r--r--grpc/examples/python/greeter/models/HelloRequest.py45
-rw-r--r--grpc/examples/python/greeter/models/__init__.py0
-rw-r--r--grpc/examples/python/greeter/models/greeter_grpc_fb.py52
-rw-r--r--grpc/examples/python/greeter/server.py57
9 files changed, 294 insertions, 4 deletions
diff --git a/grpc/examples/README.md b/grpc/examples/README.md
index f5694a84..c821218b 100644
--- a/grpc/examples/README.md
+++ b/grpc/examples/README.md
@@ -1,5 +1,33 @@
## Languages known issues
+### Python
+
+- Assert the type required in your server/client since python is able to receive `Bytes array` or `utf8 strings`.
+
+```python
+def SayHello(self, request, context):
+ # request might be a byte array or a utf8 string
+
+ r = HelloRequest.HelloRequest().GetRootAs(request, 0)
+ reply = "Unknown"
+ if r.Name():
+ reply = r.Name()
+ # Issues might happen if type checking isnt present.
+ # thus encoding it as a `reply.decode('UTF-8')`
+ return build_reply("welcome " + reply.decode('UTF-8'))
+
+```
+
+This can be prevented by making sure all the requests coming to/from python are `Bytes array`
+
+```python
+def say_hello(stub, builder):
+ hello_request = bytes(builder.Output())
+ reply = stub.SayHello(hello_request)
+ r = HelloReply.HelloReply.GetRootAs(reply)
+ print(r.Message())
+```
+
### Go
- Always requires the `content-type` of the payload to be set to `application/grpc+flatbuffers`
diff --git a/grpc/examples/generate.sh b/grpc/examples/generate.sh
index 0ac2818a..b0740d8a 100644
--- a/grpc/examples/generate.sh
+++ b/grpc/examples/generate.sh
@@ -38,23 +38,34 @@ fi
generator="--grpc $current_dir/greeter.fbs"
# Regenerate Go lang code
-cd go/
+cd go
cd greeter
fbc --go ${generator}
cd ${current_dir}
-cd swift/
+# Regenerate Python code
+cd python
+
+cd greeter
+
+fbc --python ${generator}
+
+cd ${current_dir}
+
+# Regenerate Swift code
+cd swift
cd Greeter/Sources/Model
fbc --swift ${generator}
cd ${current_dir}
-cd ts/
+# Regenerate Typescript code
+cd ts
cd greeter/src
fbc --ts ${generator}
-cd ${current_dir} \ No newline at end of file
+cd ${current_dir}
diff --git a/grpc/examples/python/greeter/README.md b/grpc/examples/python/greeter/README.md
new file mode 100644
index 00000000..fcf310c0
--- /dev/null
+++ b/grpc/examples/python/greeter/README.md
@@ -0,0 +1,12 @@
+# Python Greeter example
+
+## Prerequisite
+
+- You need to have grpc python installed on your device `pip install grpcio`
+## How to run Server:
+
+- `python server.py ${PORT}`
+
+## How to run Client:
+
+- `python client.py ${PORT} ${NAME}` \ No newline at end of file
diff --git a/grpc/examples/python/greeter/client.py b/grpc/examples/python/greeter/client.py
new file mode 100644
index 00000000..d2d71845
--- /dev/null
+++ b/grpc/examples/python/greeter/client.py
@@ -0,0 +1,40 @@
+import sys
+import argparse
+import grpc
+
+sys.path.insert(0, '../../../../../flatbuffers/python')
+
+import flatbuffers
+from models import HelloReply, HelloRequest, greeter_grpc_fb
+
+parser = argparse.ArgumentParser()
+parser.add_argument("port", help="server port to connect to", default=3000)
+parser.add_argument("name", help="name to be sent to server", default="flatbuffers")
+
+def say_hello(stub, hello_request):
+ reply = stub.SayHello(hello_request)
+ r = HelloReply.HelloReply.GetRootAs(reply)
+ print(r.Message())
+
+def say_many_hellos(stub, hello_request):
+ greetings = stub.SayManyHellos(hello_request)
+ for greeting in greetings:
+ r = HelloReply.HelloReply.GetRootAs(greeting)
+ print(r.Message())
+
+def main():
+ args = parser.parse_args()
+
+ with grpc.insecure_channel('localhost:' + args.port) as channel:
+ builder = flatbuffers.Builder()
+ ind = builder.CreateString(args.name)
+ HelloRequest.HelloRequestStart(builder)
+ HelloRequest.HelloRequestAddName(builder, ind)
+ root = HelloRequest.HelloRequestEnd(builder)
+ builder.Finish(root)
+ output = bytes(builder.Output())
+ stub = greeter_grpc_fb.GreeterStub(channel)
+ say_hello(stub, output)
+ say_many_hellos(stub, output)
+
+main() \ No newline at end of file
diff --git a/grpc/examples/python/greeter/models/HelloReply.py b/grpc/examples/python/greeter/models/HelloReply.py
new file mode 100644
index 00000000..95434dcc
--- /dev/null
+++ b/grpc/examples/python/greeter/models/HelloReply.py
@@ -0,0 +1,45 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: models
+
+import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
+
+class HelloReply(object):
+ __slots__ = ['_tab']
+
+ @classmethod
+ def GetRootAs(cls, buf, offset=0):
+ n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+ x = HelloReply()
+ x.Init(buf, n + offset)
+ return x
+
+ @classmethod
+ def GetRootAsHelloReply(cls, buf, offset=0):
+ """This method is deprecated. Please switch to GetRootAs."""
+ return cls.GetRootAs(buf, offset)
+ # HelloReply
+ def Init(self, buf, pos):
+ self._tab = flatbuffers.table.Table(buf, pos)
+
+ # HelloReply
+ def Message(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+ if o != 0:
+ return self._tab.String(o + self._tab.Pos)
+ return None
+
+def Start(builder): builder.StartObject(1)
+def HelloReplyStart(builder):
+ """This method is deprecated. Please switch to Start."""
+ return Start(builder)
+def AddMessage(builder, message): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(message), 0)
+def HelloReplyAddMessage(builder, message):
+ """This method is deprecated. Please switch to AddMessage."""
+ return AddMessage(builder, message)
+def End(builder): return builder.EndObject()
+def HelloReplyEnd(builder):
+ """This method is deprecated. Please switch to End."""
+ return End(builder) \ No newline at end of file
diff --git a/grpc/examples/python/greeter/models/HelloRequest.py b/grpc/examples/python/greeter/models/HelloRequest.py
new file mode 100644
index 00000000..0263095e
--- /dev/null
+++ b/grpc/examples/python/greeter/models/HelloRequest.py
@@ -0,0 +1,45 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: models
+
+import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
+
+class HelloRequest(object):
+ __slots__ = ['_tab']
+
+ @classmethod
+ def GetRootAs(cls, buf, offset=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, pos):
+ self._tab = flatbuffers.table.Table(buf, pos)
+
+ # HelloRequest
+ def Name(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+ if o != 0:
+ return self._tab.String(o + self._tab.Pos)
+ return None
+
+def Start(builder): builder.StartObject(1)
+def HelloRequestStart(builder):
+ """This method is deprecated. Please switch to Start."""
+ return Start(builder)
+def AddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
+def HelloRequestAddName(builder, name):
+ """This method is deprecated. Please switch to AddName."""
+ return AddName(builder, name)
+def End(builder): return builder.EndObject()
+def HelloRequestEnd(builder):
+ """This method is deprecated. Please switch to End."""
+ return End(builder) \ No newline at end of file
diff --git a/grpc/examples/python/greeter/models/__init__.py b/grpc/examples/python/greeter/models/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/grpc/examples/python/greeter/models/__init__.py
diff --git a/grpc/examples/python/greeter/models/greeter_grpc_fb.py b/grpc/examples/python/greeter/models/greeter_grpc_fb.py
new file mode 100644
index 00000000..b9f8a4ed
--- /dev/null
+++ b/grpc/examples/python/greeter/models/greeter_grpc_fb.py
@@ -0,0 +1,52 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+
+import grpc
+
+class GreeterStub(object):
+ """ Interface exported by the server. """
+
+ def __init__(self, channel):
+ """ Constructor.
+
+ Args:
+ channel: A grpc.Channel.
+ """
+
+ self.SayHello = channel.unary_unary(
+ "/models.Greeter/SayHello"
+ )
+
+ self.SayManyHellos = channel.unary_stream(
+ "/models.Greeter/SayManyHellos"
+ )
+
+
+class GreeterServicer(object):
+ """ Interface exported by the server. """
+
+ def SayHello(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+
+ def SayManyHellos(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+
+
+def add_GreeterServicer_to_server(servicer, server):
+ rpc_method_handlers = {
+ 'SayHello': grpc.unary_unary_rpc_method_handler(
+ servicer.SayHello
+ ),
+ 'SayManyHellos': grpc.unary_stream_rpc_method_handler(
+ servicer.SayManyHellos
+ ),
+ }
+ generic_handler = grpc.method_handlers_generic_handler(
+ 'models.Greeter', rpc_method_handlers)
+ server.add_generic_rpc_handlers((generic_handler,))
+
diff --git a/grpc/examples/python/greeter/server.py b/grpc/examples/python/greeter/server.py
new file mode 100644
index 00000000..acca880b
--- /dev/null
+++ b/grpc/examples/python/greeter/server.py
@@ -0,0 +1,57 @@
+from concurrent import futures
+import sys
+import argparse
+import grpc
+
+sys.path.insert(0, '../../../../../flatbuffers/python')
+
+import flatbuffers
+from models import HelloReply, HelloRequest, greeter_grpc_fb
+
+parser = argparse.ArgumentParser()
+parser.add_argument("port", help="server on port", default=3000)
+
+def build_reply(message):
+ builder = flatbuffers.Builder()
+ ind = builder.CreateString(message)
+ HelloReply.HelloReplyStart(builder)
+ HelloReply.HelloReplyAddMessage(builder, ind)
+ root = HelloReply.HelloReplyEnd(builder)
+ builder.Finish(root)
+ return bytes(builder.Output())
+
+class GreeterServicer(greeter_grpc_fb.GreeterServicer):
+
+ def __init__(self):
+ self.greetings = ["Hi", "Hallo", "Ciao"]
+
+ def SayHello(self, request, context):
+ r = HelloRequest.HelloRequest().GetRootAs(request, 0)
+ reply = "Unknown"
+ if r.Name():
+ reply = r.Name()
+ return build_reply("welcome " + reply.decode('UTF-8'))
+
+ def SayManyHellos(self, request, context):
+ r = HelloRequest.HelloRequest().GetRootAs(request, 0)
+ reply = "Unknown"
+ if r.Name():
+ reply = r.Name()
+
+ for greeting in self.greetings:
+ print(type(reply))
+ yield build_reply(greeting + " " + reply.decode('UTF-8'))
+
+
+def serve():
+ args = parser.parse_args()
+ server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+ greeter_grpc_fb.add_GreeterServicer_to_server(
+ GreeterServicer(), server
+ )
+ server.add_insecure_port('[::]:' + args.port)
+ server.start()
+ server.wait_for_termination()
+
+if __name__ == '__main__':
+ serve() \ No newline at end of file