#python #protocol-buffers
#python #буферы протокола
Вопрос:
У меня возникла проблема с декодированием ответа Google protobuf без файла .proto, был реализован с помощью файла proto и работает нормально, но в этом случае файл .proto недоступен.
Используя python 3 и из туннеля получая этот ответ
b'x08x00x12x88x01x08xdaxc9x06x10xb6xc9x03x18xa1x8bxb8x01 x00*x00:x00Bx00Jx00Rx00Zx00bx00jx00rx00zx00x80x01xe9x9bx8cxb5x99-x90x01dx98x01xeax9bx8cxb5x99-xa2x01x00xaax01x00xb0x01x00xb8x01x01xc0x0
1x00xd1x01x00x00x00x00x00x00x00x00xd9x01x00x00x00x00x00x00x00x00xe1x01x00x00x00x00x00x00x00x00xeax01x00xf0x01x01xf8x01x00x80x02x00x88x02x00x90x02x00x98x02x00xa8x02x00xb0x02x00xb8x02x90Nxc0x02x00xc8x0
2x00'
Есть способ декодировать Google ptobuf без файла .proto и сделать его dict?
мой код для достижения этого приведен ниже:
import pika
credentials = pika.PlainCredentials('demo', 'demo')
cp = pika.ConnectionParameters(
host='127.0.0.1',
port=5671,
credentials=credentials,
ssl=False,
)
connection = pika.BlockingConnection(cp)
channel = connection.channel()
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
channel.basic_consume(callback, queue='demo_queu', no_ack=True)
print(' [*] Waiting for messages. To exit press CTRL C')
channel.start_consuming()
необходимо достичь:
чтобы получить тело и декодировать его в удобочитаемом для человека виде
любая идея будет оценена
Комментарии:
1. Лучше всего перепроектировать файл .proto; для
protoc
этого есть инструмент, но я обычно использую protogen.marcgravell.com/decode чтобы помочь мне разобраться с полями. Является ли этот подход жизнеспособным для вас? Существуют API для работы с данными proto без .proto, но вам все равно нужно выяснить, что означает каждое поле, поэтому вы можете просто полностью перепроектировать его. Сложная часть обычно заключается в следующем: подписанный или неподписанный для целых чисел2. @MarcGravell это не для меня, есть еще идея?
3. можете ли вы сформулировать, почему нет? формат protobuf во многих отношениях неоднозначен без схемы, поэтому вам вроде как нужно разобраться с макетом с помощью некоторой ручной проверки, используя такие инструменты, как
protoc
(я думаю--decode-raw
?) или по ссылке выше. Без этого… Я не уверен, что вы ожидаете делать с битами4. @MarcGravell я нашел в Google protobuf способ декодирования сообщения без собственного файла ptoro, но с сообщениями Google по умолчанию, не могу найти статью, но пытался много раз и безуспешно, возможно ли использовать сообщение Google protobuf по умолчанию для декодирования, если да, могу ли я привести пример? потратил уже несколько недель на эту проблему и никакого результата
5. (комментарий добавлен там)
Ответ №1:
Наконец-то я сам нашел обходной путь, возможно, это примитивный способ, но только это сработало для меня.
РЕШЕНИЕ:
1. Сделал список со всеми дескрипторами из файла .proto
here is .proto file generated for python 3 is too big cant paste content here
https://ufile.io/2p2d6
descriptors = [proto_file.descriptor_1, proto_file.descriptor_2]
2. Зацикливайте список и передавайте один за другим
for d in descriptors:
decoded_response = proto_file._reflection.ParseMessage(d, raw_response.body)
3. Проверьте, не является ли значение decoded_response пустым
if decoded_response:
# descriptor was found
# response is decoded
else:
# no descriptor
4. После декодированного ответа мы анализируем его в dict:
from protobuf_to_dict import protobuf_to_dict
decoded_response_to_dict = protobuf_to_dict(decoded_response)
Это решение, на которое были потрачены недели, наконец-то сработало.
Комментарии:
1. Только премиум-доступ Срок размещения этого файла истек, загрузить его могут только премиум-пользователи.