Commit 6beb9f49 authored by Malar Kannan's avatar Malar Kannan Committed by Wouter van Oortmerssen

Support for python grpc - continuing the work from the pull request #4270 #4705 (#5613)

* Support for python grpc

* add few fixes

* Fixes build

* Fix python generator

* Add tests

* Fix grpc python test

* Fix tests and add incomplete python generator

* Fix python generator

* Add python generator methods

* Fix Appveyor build

* grpc python support v0.1

* Update tests

* update grpctest

* Remove duplicated code and fix a brace

* tests for flatbuffers grpc python

* Updated tests + removed SerializeToString, From String

* remove pickle import

* include missing files in ci - BUILD and generated test result
parent 80988ea8
...@@ -80,6 +80,9 @@ cc_binary( ...@@ -80,6 +80,9 @@ cc_binary(
"grpc/src/compiler/cpp_generator.h", "grpc/src/compiler/cpp_generator.h",
"grpc/src/compiler/go_generator.cc", "grpc/src/compiler/go_generator.cc",
"grpc/src/compiler/go_generator.h", "grpc/src/compiler/go_generator.h",
"grpc/src/compiler/python_generator.cc",
"grpc/src/compiler/python_generator.h",
"grpc/src/compiler/python_private_generator.h",
"grpc/src/compiler/java_generator.cc", "grpc/src/compiler/java_generator.cc",
"grpc/src/compiler/java_generator.h", "grpc/src/compiler/java_generator.h",
"grpc/src/compiler/schema_interface.h", "grpc/src/compiler/schema_interface.h",
......
...@@ -104,6 +104,9 @@ set(FlatBuffers_Compiler_SRCS ...@@ -104,6 +104,9 @@ set(FlatBuffers_Compiler_SRCS
grpc/src/compiler/go_generator.cc grpc/src/compiler/go_generator.cc
grpc/src/compiler/java_generator.h grpc/src/compiler/java_generator.h
grpc/src/compiler/java_generator.cc grpc/src/compiler/java_generator.cc
grpc/src/compiler/python_generator.h
grpc/src/compiler/python_private_generator.h
grpc/src/compiler/python_generator.cc
) )
set(FlatHash_SRCS set(FlatHash_SRCS
......
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <sstream>
#include <tuple>
#include <vector>
#include "flatbuffers/util.h"
#include "src/compiler/python_generator.h"
#include "src/compiler/python_private_generator.h"
using std::make_pair;
using std::map;
using std::pair;
using std::replace;
using std::tuple;
using std::vector;
using std::set;
namespace grpc_python_generator {
grpc::string generator_file_name;
typedef map<grpc::string, grpc::string> StringMap;
typedef vector<grpc::string> StringVector;
typedef tuple<grpc::string, grpc::string> StringPair;
typedef set<StringPair> StringPairSet;
// Provides RAII indentation handling. Use as:
// {
// IndentScope raii_my_indent_var_name_here(my_py_printer);
// // constructor indented my_py_printer
// ...
// // destructor called at end of scope, un-indenting my_py_printer
// }
class IndentScope {
public:
explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
printer_->Indent();
}
~IndentScope() { printer_->Outdent(); }
private:
grpc_generator::Printer* printer_;
};
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
const grpc::string& to, bool replace_all) {
size_t pos = 0;
do {
pos = str.find(from, pos);
if (pos == grpc::string::npos) {
break;
}
str.replace(pos, from.length(), to);
pos += to.length();
} while (replace_all);
return str;
}
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
const grpc::string& to) {
return StringReplace(str, from, to, true);
}
grpc::string ModuleName(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string basename = flatbuffers::StripExtension(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return import_prefix + basename + "_fb";
}
grpc::string ModuleAlias(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string module_name = ModuleName(filename, import_prefix);
// We can't have dots in the module name, so we replace each with _dot_.
// But that could lead to a collision between a.b and a_dot_b, so we also
// duplicate each underscore.
module_name = StringReplace(module_name, "_", "__");
module_name = StringReplace(module_name, ".", "_dot_");
return module_name;
}
PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config_,
const grpc_generator::File* file_)
: config(config_), file(file_) {}
void PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This class was "
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
}
}
}
}
void PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class Beta$Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This class was "
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print(method_dict,
"def $Method$(self, $ArgName$, timeout, metadata=None, "
"with_call=False, protocol_options=None):\n");
{
IndentScope raii_method_indent(out);
out->Print("raise NotImplementedError()\n");
}
if (!method->ServerStreaming()) {
out->Print(method_dict, "$Method$.future = None\n");
}
}
}
}
void PrivateGenerator::PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict,
"def beta_create_$Service$_server(servicer, pool=None, "
"pool_size=None, default_timeout=None, maximum_timeout=None):\n");
{
IndentScope raii_create_server_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This function was\n"
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
"\"\"\"\n");
StringMap method_implementation_constructors;
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
const grpc::string method_implementation_constructor =
grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
"inline";
grpc::string input_message_module_and_class = method->get_fb_builder();
grpc::string output_message_module_and_class = method->get_fb_builder();
method_implementation_constructors.insert(
make_pair(method->name(), method_implementation_constructor));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
// out->Print("request_deserializers = {\n");
// for (StringMap::iterator name_and_input_module_class_pair =
// input_message_modules_and_classes.begin();
// name_and_input_module_class_pair !=
// input_message_modules_and_classes.end();
// name_and_input_module_class_pair++) {
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
// method_dict["InputTypeModuleAndClass"] =
// name_and_input_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$InputTypeModuleAndClass$.FromString,\n");
// }
// out->Print("}\n");
// out->Print("response_serializers = {\n");
// for (StringMap::iterator name_and_output_module_class_pair =
// output_message_modules_and_classes.begin();
// name_and_output_module_class_pair !=
// output_message_modules_and_classes.end();
// name_and_output_module_class_pair++) {
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
// method_dict["OutputTypeModuleAndClass"] =
// name_and_output_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$OutputTypeModuleAndClass$.SerializeToString,\n");
// }
// out->Print("}\n");
out->Print("method_implementations = {\n");
for (StringMap::iterator name_and_implementation_constructor =
method_implementation_constructors.begin();
name_and_implementation_constructor !=
method_implementation_constructors.end();
name_and_implementation_constructor++) {
method_dict["Method"] = name_and_implementation_constructor->first;
method_dict["Constructor"] = name_and_implementation_constructor->second;
IndentScope raii_descriptions_indent(out);
const grpc::string method_name =
name_and_implementation_constructor->first;
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
"face_utilities.$Constructor$(servicer.$Method$),\n");
}
out->Print("}\n");
out->Print(
"server_options = beta_implementations.server_options("
"thread_pool=pool, thread_pool_size=pool_size, "
"default_timeout=default_timeout, "
"maximum_timeout=maximum_timeout)\n");
out->Print(
"return beta_implementations.server(method_implementations, "
"options=server_options)\n");
//"request_deserializers=request_deserializers, "
//"response_serializers=response_serializers, "
}
}
void PrivateGenerator::PrintBetaStubFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
out->Print(dict,
"def beta_create_$Service$_stub(channel, host=None,"
" metadata_transformer=None, pool=None, pool_size=None):\n");
{
IndentScope raii_create_server_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This function was\n"
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
"\"\"\"\n");
StringMap method_cardinalities;
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
const grpc::string method_cardinality =
grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") +
"_" +
grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
grpc::string input_message_module_and_class = method->get_fb_builder();
grpc::string output_message_module_and_class = method->get_fb_builder();
method_cardinalities.insert(
make_pair(method->name(), method_cardinality));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
// out->Print("request_serializers = {\n");
// for (StringMap::iterator name_and_input_module_class_pair =
// input_message_modules_and_classes.begin();
// name_and_input_module_class_pair !=
// input_message_modules_and_classes.end();
// name_and_input_module_class_pair++) {
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
// method_dict["InputTypeModuleAndClass"] =
// name_and_input_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$InputTypeModuleAndClass$.SerializeToString,\n");
// }
// out->Print("}\n");
// out->Print("response_deserializers = {\n");
// for (StringMap::iterator name_and_output_module_class_pair =
// output_message_modules_and_classes.begin();
// name_and_output_module_class_pair !=
// output_message_modules_and_classes.end();
// name_and_output_module_class_pair++) {
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
// method_dict["OutputTypeModuleAndClass"] =
// name_and_output_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$OutputTypeModuleAndClass$.FromString,\n");
// }
// out->Print("}\n");
out->Print("cardinalities = {\n");
for (StringMap::iterator name_and_cardinality =
method_cardinalities.begin();
name_and_cardinality != method_cardinalities.end();
name_and_cardinality++) {
method_dict["Method"] = name_and_cardinality->first;
method_dict["Cardinality"] = name_and_cardinality->second;
IndentScope raii_descriptions_indent(out);
out->Print(method_dict,
"\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
}
out->Print("}\n");
out->Print(
"stub_options = beta_implementations.stub_options("
"host=host, metadata_transformer=metadata_transformer, "
"thread_pool=pool, thread_pool_size=pool_size)\n");
out->Print(method_dict,
"return beta_implementations.dynamic_stub(channel, "
"\'$PackageQualifiedServiceName$\', "
"cardinalities, options=stub_options)\n");
// "request_serializers=request_serializers, "
//"response_deserializers=response_deserializers, "
}
}
void PrivateGenerator::PrintStub(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
out->Print(dict, "class $Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print("\n");
out->Print("def __init__(self, channel):\n");
{
IndentScope raii_init_indent(out);
out->Print("\"\"\"Constructor.\n");
out->Print("\n");
out->Print("Args:\n");
{
IndentScope raii_args_indent(out);
out->Print("channel: A grpc.Channel.\n");
}
out->Print("\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string multi_callable_constructor =
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
"_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary");
grpc::string request_module_and_class = method->get_fb_builder();
grpc::string response_module_and_class = method->get_fb_builder();
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MultiCallableConstructor"] = multi_callable_constructor;
out->Print(method_dict,
"self.$Method$ = channel.$MultiCallableConstructor$(\n");
{
method_dict["PackageQualifiedService"] =
package_qualified_service_name;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
IndentScope raii_first_attribute_indent(out);
IndentScope raii_second_attribute_indent(out);
out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
out->Print(method_dict,"\n");
out->Print(
method_dict,"\n");
out->Print(")\n");
}
}
}
}
}
void PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class $Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print("\n");
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
out->Print("context.set_details('Method not implemented!')\n");
out->Print("raise NotImplementedError('Method not implemented!')\n");
}
}
}
}
void PrivateGenerator::PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict,
"def add_$Service$Servicer_to_server(servicer, server):\n");
{
IndentScope raii_class_indent(out);
out->Print("rpc_method_handlers = {\n");
{
IndentScope raii_dict_first_indent(out);
IndentScope raii_dict_second_indent(out);
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string method_handler_constructor =
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
"_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary") +
"_rpc_method_handler";
grpc::string request_module_and_class = method->get_fb_builder();
grpc::string response_module_and_class = method->get_fb_builder();
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MethodHandlerConstructor"] = method_handler_constructor;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
out->Print(method_dict,
"'$Method$': grpc.$MethodHandlerConstructor$(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print(method_dict, "servicer.$Method$,\n");
out->Print(
method_dict,"\n");
out->Print(
method_dict,
"\n");
}
out->Print("),\n");
}
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
out->Print("}\n");
out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print(method_dict,
"'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
}
out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
}
}
void PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.beta_package_root;
out->Print(var,
"from $Package$ import implementations as beta_implementations\n");
out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
out->Print("from grpc.framework.common import cardinality\n");
out->Print(
"from grpc.framework.interfaces.face import utilities as "
"face_utilities\n");
}
void PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.grpc_package_root;
out->Print(var, "import $Package$\n");
out->Print("\n");
StringPairSet imports_set;
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
for (int j = 0; j < service->method_count(); ++j) {
auto method = service.get()->method(j);
grpc::string input_type_file_name = method->get_fb_builder();
grpc::string input_module_name =
ModuleName(input_type_file_name, config.import_prefix);
grpc::string input_module_alias =
ModuleAlias(input_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(input_module_name, input_module_alias));
grpc::string output_type_file_name = method->get_fb_builder();
grpc::string output_module_name =
ModuleName(output_type_file_name, config.import_prefix);
grpc::string output_module_alias =
ModuleAlias(output_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(output_module_name, output_module_alias));
}
}
for (StringPairSet::iterator it = imports_set.begin();
it != imports_set.end(); ++it) {
var["ModuleName"] = std::get<0>(*it);
var["ModuleAlias"] = std::get<1>(*it);
out->Print(var, "import $ModuleName$ as $ModuleAlias$\n");
}
}
void PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
out->Print(file->additional_headers().c_str());
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
PrintStub(package_qualified_service_name, service.get(), out);
PrintServicer(service.get(), out);
PrintAddServicerToServer(package_qualified_service_name, service.get(),
out);
}
}
void PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
PrintBetaServicer(service.get(), out);
PrintBetaStub(service.get(), out);
PrintBetaServerFactory(package_qualified_service_name, service.get(), out);
PrintBetaStubFactory(package_qualified_service_name, service.get(), out);
}
}
grpc::string PrivateGenerator::GetGrpcServices() {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
auto out = file->CreatePrinter(&output);
out->Print(
"# Generated by the gRPC Python protocol compiler plugin. "
"DO NOT EDIT!\n");
StringMap var;
var["Package"] = config.grpc_package_root;
out->Print(var, "import $Package$\n");
PrintGAServices(out.get());
out->Print("try:\n");
{
IndentScope raii_dict_try_indent(out.get());
out->Print(
"# THESE ELEMENTS WILL BE DEPRECATED.\n"
"# Please use the generated *_pb2_grpc.py files instead.\n");
out->Print(var, "import $Package$\n");
PrintBetaPreamble(out.get());
PrintGAServices(out.get());
PrintBetaServices(out.get());
}
out->Print("except ImportError:\n");
{
IndentScope raii_dict_except_indent(out.get());
out->Print("pass");
}
}
return output;
}
} // namespace grpc_python_generator
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#include <utility>
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {
// Data pertaining to configuration of the generator with respect to anything
// that may be used internally at Google.
struct GeneratorConfiguration {
grpc::string grpc_package_root;
// TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
grpc::string beta_package_root;
// TODO(https://github.com/google/protobuf/issues/888): Drop this.
grpc::string import_prefix;
};
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#include <iostream>
#include <vector>
#include "src/compiler/python_generator.h"
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {
// Tucks all generator state in an anonymous namespace away from
// PythonGrpcGenerator and the header file, mostly to encourage future changes
// to not require updates to the grpcio-tools C++ code part. Assumes that it is
// only ever used from a single thread.
struct PrivateGenerator {
const GeneratorConfiguration& config;
const grpc_generator::File* file;
PrivateGenerator(const GeneratorConfiguration& config,
const grpc_generator::File* file);
grpc::string GetGrpcServices();
private:
void PrintPreamble(grpc_generator::Printer* out);
void PrintBetaPreamble(grpc_generator::Printer* out);
void PrintGAServices(grpc_generator::Printer* out);
void PrintBetaServices(grpc_generator::Printer* out);
void PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
void PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintStub(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
void PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
};
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
...@@ -79,6 +79,9 @@ struct Method : public CommentHolder { ...@@ -79,6 +79,9 @@ struct Method : public CommentHolder {
virtual grpc::string get_input_type_name() const = 0; virtual grpc::string get_input_type_name() const = 0;
virtual grpc::string get_output_type_name() const = 0; virtual grpc::string get_output_type_name() const = 0;
virtual grpc::string get_fb_builder() const = 0;
virtual bool NoStreaming() const = 0; virtual bool NoStreaming() const = 0;
virtual bool ClientStreaming() const = 0; virtual bool ClientStreaming() const = 0;
virtual bool ServerStreaming() const = 0; virtual bool ServerStreaming() const = 0;
......
from __future__ import print_function
import os
import sys
import grpc
import flatbuffers
from concurrent import futures
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'tests'))
import MyGame.Example.Monster as Monster
import MyGame.Example.Stat as Stat
import MyGame.Example.Vec3 as Vec3
import MyGame.Example.Test as Test
import MyGame.Example.monster_test_grpc_fb as monster_grpc_fb
test_stat_id = "test_stat_id"
test_stat_val = 8
test_stat_count = 1
test_monster_name1 = "test_monster_name1"
test_monster_name2 = "test_monster_name2"
test_string = "test_string"
test_color = 2
test_X = 3.0
test_Y = 2.0
test_Z = 6.0
test_test1 = 4.0
test_a = 8
test_b = 5
test_hp = 67
test_inventory = [1, 1, 2, 3, 5, 8]
test_testtype = 4
test_monsters_name_retrieve = ["big_monster", "small_monster"]
test_no_of_monsters = 2
class MonsterStorage(monster_grpc_fb.MonsterStorageServicer):
def Store(self, request, context):
m = Monster.Monster().GetRootAsMonster(request, 0)
assert m.Name().decode("utf-8") == test_monster_name1
assert m.Pos().X() == test_X
assert m.Pos().Y() == test_Y
assert m.Pos().Z() == test_Z
assert m.Pos().Test1() == test_test1
assert m.Pos().Test2() == test_color
test3 = Test.Test()
assert m.Pos().Test3(test3).A() == test_a
assert m.Pos().Test3(test3).B() == test_b
assert m.Hp() == test_hp
assert m.Color() == test_color
assert m.InventoryLength() == len(test_inventory)
for i in range(0, len(test_inventory)):
assert m.Inventory(i) == test_inventory[len(test_inventory)-i -1]
assert m.TestType() == test_testtype
assert m.Test() is not None
table = m.Test()
m2 = Monster.Monster()
m2.Init(table.Bytes, table.Pos)
assert m2.Name().decode("utf-8") == test_monster_name2
m3 = m.Enemy()
assert m3.Name().decode("utf-8") == test_monster_name2
assert m.Testarrayofstring(0).decode("utf-8") == test_string
b = flatbuffers.Builder(0)
i = b.CreateString(test_stat_id)
Stat.StatStart(b)
Stat.StatAddId(b, i)
Stat.StatAddVal(b, test_stat_val)
Stat.StatAddCount(b, test_stat_count)
b.Finish(Stat.StatEnd(b))
return bytes(b.Output())
def Retrieve(self, request, context):
s = Stat.Stat().GetRootAsStat(request, 0)
no_of_monsters = test_no_of_monsters
for i in range(0, no_of_monsters):
b = flatbuffers.Builder(0)
i = b.CreateString(test_monsters_name_retrieve[i])
Monster.MonsterStart(b)
Monster.MonsterAddName(b, i)
b.Finish(Monster.MonsterEnd(b))
yield bytes(b.Output())
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
monster_grpc_fb.add_MonsterStorageServicer_to_server(MonsterStorage(), server)
server.add_insecure_port('[::]:50051')
server.start()
run()
def run():
channel = grpc.insecure_channel('127.0.0.1:50051')
stub = monster_grpc_fb.MonsterStorageStub(channel)
b = flatbuffers.Builder(0)
name2 = b.CreateString(test_monster_name2)
name1 = b.CreateString(test_monster_name1)
Monster.MonsterStart(b)
Monster.MonsterAddName(b, name2)
monster2 = Monster.MonsterEnd(b)
test1 = b.CreateString(test_string)
Monster.MonsterStartInventoryVector(b, len(test_inventory))
for i in range(0, len(test_inventory)):
b.PrependByte(test_inventory[i])
inv = b.EndVector(len(test_inventory))
Monster.MonsterStartTest4Vector(b, 2)
Test.CreateTest(b, 10, 20)
Test.CreateTest(b, 30, 40)
test4 = b.EndVector(2)
Monster.MonsterStartTestarrayofstringVector(b, 1)
b.PrependUOffsetTRelative(test1)
test_array_of_string = b.EndVector(1)
Monster.MonsterStart(b)
Monster.MonsterAddHp(b, test_hp)
Monster.MonsterAddName(b, name1)
Monster.MonsterAddColor(b, test_color)
pos = Vec3.CreateVec3(b, test_X, test_Y, test_Z, test_test1, test_color, test_a, test_b)
Monster.MonsterAddPos(b, pos)
Monster.MonsterAddInventory(b, inv)
Monster.MonsterAddTestType(b, test_testtype)
Monster.MonsterAddTest(b, monster2)
Monster.MonsterAddTest4(b, test4)
Monster.MonsterAddEnemy(b, monster2)
Monster.MonsterAddTestarrayofstring(b, test_array_of_string)
monster = Monster.MonsterEnd(b)
b.Finish(monster)
stat_response = stub.Store(bytes(b.Output()))
s = Stat.Stat().GetRootAsStat(stat_response, 0)
assert s.Id().decode("utf-8") == test_stat_id
assert s.Val() == test_stat_val
assert s.Count() == test_stat_count
monster_reponses = stub.Retrieve(stat_response)
count = 0
for monster_reponse in monster_reponses:
m = Monster.Monster().GetRootAsMonster(monster_reponse, 0)
assert m.Name().decode("utf-8") == test_monsters_name_retrieve[count]
count = count + 1
if __name__ == '__main__':
serve()
...@@ -1090,6 +1090,12 @@ bool GenerateGoGRPC(const Parser &parser, const std::string &path, ...@@ -1090,6 +1090,12 @@ bool GenerateGoGRPC(const Parser &parser, const std::string &path,
bool GenerateJavaGRPC(const Parser &parser, const std::string &path, bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Python interfaces.
// See idl_gen_grpc.cpp.
bool GeneratePythonGRPC(const Parser &parser,
const std::string &path,
const std::string &file_name);
} // namespace flatbuffers } // namespace flatbuffers
#endif // FLATBUFFERS_IDL_H_ #endif // FLATBUFFERS_IDL_H_
...@@ -74,8 +74,8 @@ int main(int argc, const char *argv[]) { ...@@ -74,8 +74,8 @@ int main(int argc, const char *argv[]) {
flatbuffers::IDLOptions::kCSharp, flatbuffers::IDLOptions::kCSharp,
"Generate C# classes for tables/structs", "Generate C# classes for tables/structs",
flatbuffers::JavaCSharpMakeRule }, flatbuffers::JavaCSharpMakeRule },
{ flatbuffers::GeneratePython, "-p", "--python", "Python", true, nullptr, { flatbuffers::GeneratePython, "-p", "--python", "Python", true,
flatbuffers::IDLOptions::kPython, flatbuffers::GeneratePythonGRPC, flatbuffers::IDLOptions::kPython,
"Generate Python files for tables/structs", nullptr }, "Generate Python files for tables/structs", nullptr },
{ flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true,
nullptr, flatbuffers::IDLOptions::kLobster, nullptr, flatbuffers::IDLOptions::kLobster,
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "src/compiler/cpp_generator.h" #include "src/compiler/cpp_generator.h"
#include "src/compiler/go_generator.h" #include "src/compiler/go_generator.h"
#include "src/compiler/java_generator.h" #include "src/compiler/java_generator.h"
#include "src/compiler/python_generator.h"
#include "src/compiler/python_private_generator.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
...@@ -77,6 +79,10 @@ class FlatBufMethod : public grpc_generator::Method { ...@@ -77,6 +79,10 @@ class FlatBufMethod : public grpc_generator::Method {
return true; return true;
} }
std::string get_fb_builder() const {
return "builder";
}
std::string input_type_name() const { return GRPCType(*method_->request); } std::string input_type_name() const { return GRPCType(*method_->request); }
std::string output_type_name() const { return GRPCType(*method_->response); } std::string output_type_name() const { return GRPCType(*method_->response); }
...@@ -179,7 +185,9 @@ class FlatBufPrinter : public grpc_generator::Printer { ...@@ -179,7 +185,9 @@ class FlatBufPrinter : public grpc_generator::Printer {
class FlatBufFile : public grpc_generator::File { class FlatBufFile : public grpc_generator::File {
public: public:
enum Language { kLanguageGo, kLanguageCpp, kLanguageJava }; enum Language {
kLanguageGo, kLanguageCpp, kLanguageJava, kLanguagePython
};
FlatBufFile(const Parser &parser, const std::string &file_name, FlatBufFile(const Parser &parser, const std::string &file_name,
Language language) Language language)
...@@ -224,6 +232,9 @@ class FlatBufFile : public grpc_generator::File { ...@@ -224,6 +232,9 @@ class FlatBufFile : public grpc_generator::File {
case kLanguageJava: { case kLanguageJava: {
return "import com.google.flatbuffers.grpc.FlatbuffersUtils;"; return "import com.google.flatbuffers.grpc.FlatbuffersUtils;";
} }
case kLanguagePython: {
return "";
}
} }
return ""; return "";
} }
...@@ -360,6 +371,38 @@ bool GenerateJavaGRPC(const Parser &parser, const std::string &path, ...@@ -360,6 +371,38 @@ bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
return JavaGRPCGenerator(parser, path, file_name).generate(); return JavaGRPCGenerator(parser, path, file_name).generate();
} }
bool GeneratePythonGRPC(const Parser &parser, const std::string & /*path*/,
const std::string &file_name) {
int nservices = 0;
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
++it) {
if (!(*it)->generated) nservices++;
}
if (!nservices) return true;
grpc_python_generator::GeneratorConfiguration config;
config.grpc_package_root = "grpc";
config.beta_package_root = "grpc.beta";
config.import_prefix = "";
FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguagePython);
grpc_python_generator::PrivateGenerator generator(config, &fbfile);
std::string code = generator.GetGrpcServices();
std::string namespace_dir;
auto &namespaces = parser.namespaces_.back()->components;
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
if (it != namespaces.begin()) namespace_dir += kPathSeparator;
namespace_dir += *it;
}
std::string grpc_py_filename =
namespace_dir + kPathSeparator + file_name + "_grpc_fb.py";
return flatbuffers::SaveFile(grpc_py_filename.c_str(), code, false);
}
} // namespace flatbuffers } // namespace flatbuffers
#if defined(_MSC_VER) #if defined(_MSC_VER)
......
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
class MonsterStorageStub(object):
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Store = channel.unary_unary(
'/MyGame.Example.MonsterStorage/Store',
)
self.Retrieve = channel.unary_stream(
'/MyGame.Example.MonsterStorage/Retrieve',
)
self.GetMaxHitPoint = channel.stream_unary(
'/MyGame.Example.MonsterStorage/GetMaxHitPoint',
)
self.GetMinMaxHitPoints = channel.unary_unary(
'/MyGame.Example.MonsterStorage/GetMinMaxHitPoints',
)
class MonsterStorageServicer(object):
def Store(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Retrieve(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMaxHitPoint(self, request_iterator, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMinMaxHitPoints(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_MonsterStorageServicer_to_server(servicer, server):
rpc_method_handlers = {
'Store': grpc.unary_unary_rpc_method_handler(
servicer.Store,
),
'Retrieve': grpc.unary_stream_rpc_method_handler(
servicer.Retrieve,
),
'GetMaxHitPoint': grpc.stream_unary_rpc_method_handler(
servicer.GetMaxHitPoint,
),
'GetMinMaxHitPoints': grpc.unary_unary_rpc_method_handler(
servicer.GetMinMaxHitPoints,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'MyGame.Example.MonsterStorage', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
try:
# THESE ELEMENTS WILL BE DEPRECATED.
# Please use the generated *_pb2_grpc.py files instead.
import grpc
from grpc.beta import implementations as beta_implementations
from grpc.beta import interfaces as beta_interfaces
from grpc.framework.common import cardinality
from grpc.framework.interfaces.face import utilities as face_utilities
class MonsterStorageStub(object):
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Store = channel.unary_unary(
'/MyGame.Example.MonsterStorage/Store',
)
self.Retrieve = channel.unary_stream(
'/MyGame.Example.MonsterStorage/Retrieve',
)
self.GetMaxHitPoint = channel.stream_unary(
'/MyGame.Example.MonsterStorage/GetMaxHitPoint',
)
self.GetMinMaxHitPoints = channel.unary_unary(
'/MyGame.Example.MonsterStorage/GetMinMaxHitPoints',
)
class MonsterStorageServicer(object):
def Store(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Retrieve(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMaxHitPoint(self, request_iterator, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMinMaxHitPoints(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_MonsterStorageServicer_to_server(servicer, server):
rpc_method_handlers = {
'Store': grpc.unary_unary_rpc_method_handler(
servicer.Store,
),
'Retrieve': grpc.unary_stream_rpc_method_handler(
servicer.Retrieve,
),
'GetMaxHitPoint': grpc.stream_unary_rpc_method_handler(
servicer.GetMaxHitPoint,
),
'GetMinMaxHitPoints': grpc.unary_unary_rpc_method_handler(
servicer.GetMinMaxHitPoints,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'MyGame.Example.MonsterStorage', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
class BetaMonsterStorageServicer(object):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This class was generated
only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
def Store(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def Retrieve(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def GetMaxHitPoint(self, request_iterator, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def GetMinMaxHitPoints(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
class BetaMonsterStorageStub(object):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This class was generated
only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
def Store(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
Store.future = None
def Retrieve(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
def GetMaxHitPoint(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
GetMaxHitPoint.future = None
def GetMinMaxHitPoints(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
GetMinMaxHitPoints.future = None
def beta_create_MonsterStorage_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This function was
generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
method_implementations = {
('MyGame.Example.MonsterStorage', 'GetMaxHitPoint'): face_utilities.stream_unary_inline(servicer.GetMaxHitPoint),
('MyGame.Example.MonsterStorage', 'GetMinMaxHitPoints'): face_utilities.unary_unary_inline(servicer.GetMinMaxHitPoints),
('MyGame.Example.MonsterStorage', 'Retrieve'): face_utilities.unary_stream_inline(servicer.Retrieve),
('MyGame.Example.MonsterStorage', 'Store'): face_utilities.unary_unary_inline(servicer.Store),
}
server_options = beta_implementations.server_options(thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
return beta_implementations.server(method_implementations, options=server_options)
def beta_create_MonsterStorage_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This function was
generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
cardinalities = {
'GetMaxHitPoint': cardinality.Cardinality.STREAM_UNARY,
'GetMinMaxHitPoints': cardinality.Cardinality.UNARY_UNARY,
'Retrieve': cardinality.Cardinality.UNARY_STREAM,
'Store': cardinality.Cardinality.UNARY_UNARY,
}
stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, thread_pool=pool, thread_pool_size=pool_size)
return beta_implementations.dynamic_stub(channel, 'MyGame.Example.MonsterStorage', cardinalities, options=stub_options)
except ImportError:
pass
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment