【问题标题】:How can I use a gRPC "oneof" proto structure in python?如何在 python 中使用 gRPC“oneof”原型结构?
【发布时间】:2019-11-07 00:09:49
【问题描述】:

我正在构建一个文件存储客户端/服务器,使用 python 作为客户端,使用服务器以及 gRPC。我已经成功地在 go 中构建了客户端并且它可以工作!我现在正在尝试在 python 中做同样的事情。今天一整天都在努力,但我取得了0进展-_-。从 gRPC 库中吐出的错误消息来看,我发送到我的服务器的请求可能在某种程度上是错误的:

  File "/Users/xxxxx/Desktop/clients/uploadClient.py", line 60, in upload_file
    for res in stream:
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/grpc/_channel.py", line 367, in __next__
    return self._next()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/grpc/_channel.py", line 361, in _next
    raise self
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
        status = StatusCode.INTERNAL
        details = "Exception serializing request!"
        debug_error_string = "None"
>

不太有用。我还没有找到任何有用的文档,而且阅读和搜索的时间还没有得到回报。到目前为止,我唯一可以排除的是问题与服务器相关,因为 go 客户端一直运行良好。

这是我的原型(注意:我确实提炼了一点并重命名了一些东西):

syntax = "proto3";

import "google/protobuf/timestamp.proto";

package upload;

message Chunk {
  message Index {
    uint64 as_uint64 = 1;  
  }

  Index index  = 1;
  bytes sha512 = 2; 
  bytes data   = 3;
}

message Descriptor {
  string author   = 1;  // author
  string label   = 2;  // label
  Format format = 3; //format
}  

enum Format {
    FORMAT_UNKNOWN   = 0; 
    FORMAT_CSV       = 1;
    FORMAT_XML       = 2;
    FORMAT_JSON      = 3;
    FORMAT_PDF       = 4;
}

message UploadFile {
  message ToClient {
    oneof details {
      Finished finished = 1;
    }
  }

  message ToService {
    oneof details {
      Descriptor descriptor = 1;
      Chunk chunk           = 2;
    }
  }
}

.
service FileService {
  rpc Upload(stream UploadFile.ToService) returns (stream UploadFile.ToClient);
}

这里是代码(注意:我确实提炼了一点并重命名了一些东西):

import s_pb2 as s
import s_pb2_grpc as s_grpc

token = 'xxxx'
url = 'xxxx:433'
requestMetadata = [('authorization', 'Bearer ' + token)]

def create_stub():
    creds = grpc.ssl_channel_credentials()
    channel = grpc.secure_channel(url, creds)
    return s_grpc.UploadManagerStub(channel)

def upload_file(src, label, fileFormat):
    stub = create_stub()

    stream = stub.Upload(
        request_iterator=__upload_file_iterator(src, label, fileFormat),
        metadata=requestMetadata
    )

    for res in stream:
        print(res)

    return stream

def __upload_file_iterator(src, name, fileFormat, chunk_size = 1024):

    def descriptor():
        to_service = s.UploadFile.ToService

        to_service.descriptor = s.Descriptor(
            label=label,
            format=fileFormat
        )

        return to_service

    yield descriptor()

是的,我知道我的迭代器只返回 1 个东西,我删除了一些代码以尝试隔离问题。

gRPC 不是我最强的技能,我想相信我的豌豆大脑只是缺少一些明显的东西。

感谢所有帮助!

【问题讨论】:

    标签: python protocol-buffers grpc proto


    【解决方案1】:

    在构造函数中包装“oneof”细节解决了这个问题:

    def chunk(data, index):
        return s.UploadFile.ToService(
            chunk=s.Chunk(
                index=s.Chunk.Index(as_uint64=index),
                data=data,
                sha512=hashlib.sha512(data).digest()
            )
        )
    
    def descriptor(name, fileFormat):
        return s.UploadFile.ToService(
            descriptor=s.Descriptor(
                name=name,
                format=fileFormat
            )
        )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      • 2018-12-04
      • 1970-01-01
      相关资源
      最近更新 更多