pythonstunnel

cTrader decode protobuf message from Report API Events (tunnel)


i am dealing with cTrader Trading platform. My project is written in python 3 on tornado.

And have issue in decoding the prtobuf message from report API Events.

Below will list everything what i achieved and where have the problem.

  1. First cTrader have Rest API for Report
    • so i got the .proto file and generated it for python 3
    • proto file is called : cTraderReportingMessages5_9_pb2
    • from rest Report API getting the protobuf message and able to decode in the following way because i know which descriptor to pass for decoding
    from models import cTraderReportingMessages5_9_pb2
    from protobuf_to_dict import protobuf_to_dict

    raw_response = yield async_client.fetch(base_url, method=method, body=form_data, headers=headers)
    decoded_response = cTraderReportingMessages5_9_pb2._reflection.ParseMessage(descriptors[endpoint]['decode'], raw_response.body)

descriptors[endpoint]['decode'] = is my descriptor know exactly which descriptor to pass to decode my message

my content from cTraderReportingMessages5_9_pb2

# here is .proto file generated for python 3 is too big cant paste content here

https://ufile.io/2p2d6

So until here using rest api and know exactly which descriptor to pass, i am able to decode protobuf message and go forward.

2. Now the issue i face

Connecting with python 3 to the tunnel on 127.0.0.:5672

i am listening for events and receiving this kind of data back

b'\x08\x00\x12\x88\x01\x08\xda\xc9\x06\x10\xb6\xc9\x03\x18\xa1\x8b\xb8\x01 \x00*\x00:\x00B\x00J\x00R\x00Z\x00b\x00j\x00r\x00z\x00\x80\x01\xe9\x9b\x8c\xb5\x99-\x90\x01d\x98\x01\xea\x9b\x8c\xb5\x99-\xa2\x01\x00\xaa\x01\x00\xb0\x01\x00\xb8\x01\x01\xc0\x0
1\x00\xd1\x01\x00\x00\x00\x00\x00\x00\x00\x00\xd9\x01\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x01\x00\x00\x00\x00\x00\x00\x00\x00\xea\x01\x00\xf0\x01\x01\xf8\x01\x00\x80\x02\x00\x88\x02\x00\x90\x02\x00\x98\x02\x00\xa8\x02\x00\xb0\x02\x00\xb8\x02\x90N\xc0\x02\x00\xc8\x0
2\x00

as recommendation i got, i need to use same .proto file generated for python that i did in step 1 and decode the message but without any success because i don't know the descriptor need to be passed.

so in 1 step was doing and working perfect this way

decoded_response = cTraderReportingMessages5_9_pb2._reflection.ParseMessage(descriptors[endpoint]['decode'], raw_response.body)

but in second step can not decode the message using in the same way, what i am missing or how to decode the message using same .proto file?


Solution

  • Finally found a workaround by my self, maybe is a primitive way but only this worked for me.

    By the answer got from providers need to use same .proto file for both situations

    SOLUTION:

    1. Did list with all the descriptors from .proto file

        here is .proto file generated for python 3 is too big cant paste content here
    
        https://ufile.io/2p2d6
    
        descriptors = [cTraderReportingMessages5_9_pb2.descriptor_1, cTraderReportingMessages5_9_pb2.descriptor_2]
    

    2. Loop throw list and pass one by one

    for d in descriptors:
        decoded_response = cTraderReportingMessages5_9_pb2._reflection.ParseMessage(d, raw_response.body)
    

    3. Check if decoded_response is not blank

       if decoded_response:
           # descriptor was found
           # response is decoded
       else:
           # no descriptor
    

    4. After decoded response we go parse it into dict:

    from protobuf_to_dict import protobuf_to_dict
    
    decoded_response_to_dict = protobuf_to_dict(decoded_response)
    

    This solution that spent weeks on it finally worked.