使 gRPC 消息 JSON 可序列化
Make gRPC messages JSON serializable
我有一个包含重复标量值的 gRPC 定义。
例如
message Request {
bool dryrun = 1;
bool verbose = 2;
bool enabled = 3;
float ratio = 4;
int32 count = 5;
string somevar = 6;
bool withcondition = 7;
bool nocondition = 8;
float portion = 9;
int32 population = 10;
string xvars = 11;
string singleoption = 12;
repeated int32 multioptions = 13;
}
我注意到当这个请求被发送到 Python 服务器时,mylist
被转换为 RepeatedScalarContainer
,这不是 JSON 可序列化的。 Some SO questions建议我使用
from google.protobuf.json_format import MessageToJson
serialized = MessageToJson(original)
将 protobuf 消息转换为有效的 JSON 对象。
但就我而言,对接收到的 Python 对象执行上述操作会得到一个截断的
{
"enabled": true,
"ratio": 0.5,
"count": 100,
"somevar": "/input",
"withcondition": true,
"singleoption": "option1",
"multioptions": [
1,
3
]
}
可以看到少了一堆消息属性
作为一种解决方法,我仍然可以提取接收到的对象的属性来恢复数据并将它们转换为 JSON 可通过暴力序列化,但这看起来很丑陋和不稳定。这是我的方式
def handle_request(request):
all_attrs = dir(request)
i_last_private_attr = next((a for a, attr in enumerate(reversed(all_attrs)) if attr.startswith('_')), None)
if not i_last_private_attr:
_logger.error('Failed to find any request')
return
i_first_arg_attr = len(all_attrs) - i_last_private_attr
req_dict = {attr: getattr(request, attr) for attr in all_attrs[i_first_arg_attr:]}
for k, v in req_dict.items():
if isinstance(v, Iterable) and not isinstance(v, (dict, list, tuple, str)):
req_dict[k] = list(req_dict[k])
我应该如何使接收到的原始 gRPC 请求像 Python 只包含内置原始值类型的对象一样工作?
自己解决了。
有一个选项 including_default_value_fields
和 json_format.MessageToJson()
。当设置为 False
时,所有默认字段都不会打印到 JSON,尽管它们实际上是通过线路发送的。
不幸的是,默认情况下该选项是关闭的。
设置为True
后,问题解决
我有一个包含重复标量值的 gRPC 定义。
例如
message Request {
bool dryrun = 1;
bool verbose = 2;
bool enabled = 3;
float ratio = 4;
int32 count = 5;
string somevar = 6;
bool withcondition = 7;
bool nocondition = 8;
float portion = 9;
int32 population = 10;
string xvars = 11;
string singleoption = 12;
repeated int32 multioptions = 13;
}
我注意到当这个请求被发送到 Python 服务器时,mylist
被转换为 RepeatedScalarContainer
,这不是 JSON 可序列化的。 Some SO questions建议我使用
from google.protobuf.json_format import MessageToJson
serialized = MessageToJson(original)
将 protobuf 消息转换为有效的 JSON 对象。 但就我而言,对接收到的 Python 对象执行上述操作会得到一个截断的
{
"enabled": true,
"ratio": 0.5,
"count": 100,
"somevar": "/input",
"withcondition": true,
"singleoption": "option1",
"multioptions": [
1,
3
]
}
可以看到少了一堆消息属性
作为一种解决方法,我仍然可以提取接收到的对象的属性来恢复数据并将它们转换为 JSON 可通过暴力序列化,但这看起来很丑陋和不稳定。这是我的方式
def handle_request(request):
all_attrs = dir(request)
i_last_private_attr = next((a for a, attr in enumerate(reversed(all_attrs)) if attr.startswith('_')), None)
if not i_last_private_attr:
_logger.error('Failed to find any request')
return
i_first_arg_attr = len(all_attrs) - i_last_private_attr
req_dict = {attr: getattr(request, attr) for attr in all_attrs[i_first_arg_attr:]}
for k, v in req_dict.items():
if isinstance(v, Iterable) and not isinstance(v, (dict, list, tuple, str)):
req_dict[k] = list(req_dict[k])
我应该如何使接收到的原始 gRPC 请求像 Python 只包含内置原始值类型的对象一样工作?
自己解决了。
有一个选项 including_default_value_fields
和 json_format.MessageToJson()
。当设置为 False
时,所有默认字段都不会打印到 JSON,尽管它们实际上是通过线路发送的。
不幸的是,默认情况下该选项是关闭的。
设置为True
后,问题解决