0

I am using pb3 for serialization:

syntax = "proto3";

package marshalling;

import "google/protobuf/timestamp.proto";

message PrimitiveType {
  oneof primitive_value {
    bool boolean_value = 1;
    int64 int_value = 2;
    double double_value = 3;
    google.protobuf.Timestamp timestamp_value = 4;
  }
}

I generated a x_pb2.py file but do not know how to use it.

For example, if I would like to Marshall a timestamp to bytes, how could I do it?

Azeem
  • 11,148
  • 4
  • 27
  • 40
Sidi Chang
  • 25
  • 6
  • Here's the Python Tutorial: https://developers.google.com/protocol-buffers/docs/pythontutorial – Azeem May 27 '20 at 10:36
  • Hi, I already read through this doc. One question I can't resolve is if I would like parse in `currentTime` to this message, how could I do it? if I do `PrimitiveType(). timestamp_value = xxx`, I do not think it is working. – Sidi Chang May 27 '20 at 10:50
  • the `x_pb2.py` file is a Descriptor, if you have any tutorials for that, it would be great. – Sidi Chang May 27 '20 at 10:51
  • Please refer to the [Python API Refernece](https://googleapis.dev/python/protobuf/latest/). Also, add your code that is not working in your question. It would be helpful to understand your problem. – Azeem May 27 '20 at 11:16

1 Answers1

0

With reference to The Protocol Buffer API section:

Unlike when you generate Java and C++ protocol buffer code, the Python protocol buffer compiler doesn't generate your data access code for you directly. Instead, it generates special descriptors for all your messages, enums, and fields, and some mysteriously empty classes, one for each message type...

and,

At load time, the GeneratedProtocolMessageType metaclass uses the specified descriptors to create all the Python methods you need to work with each message type and adds them to the relevant classes. You can then use the fully-populated classes in your code.

So, you can use the generated class(s) to create the object(s) and their fields like this:

p1 = primitive_types_pb2.PrimitiveType()
p1.int_value = 1234

For your use-case, you can use timestamp_pb2.Timestamp.GetCurrentTime().

Alternatively, you can refer to Timestamp along with timestamp_pb2.Timestamp.CopyFrom():

now = time.time()
seconds = int(now)
nanos = int((now - seconds) * 10**9)
timestamp = Timestamp(seconds=seconds, nanos=nanos)

p1 = primitive_types_pb2.PrimitiveType()
p1.timestamp_value.CopyFrom( timestamp )

There are other google.protobuf.timestamp_pb2 APIs that you might be interested in for your other use-cases.


Here's a complete working example (primitive_types.proto):

import time  # For Timestamp.CopyFrom(). See commented code below
import primitive_types_pb2
from google.protobuf import timestamp_pb2

# serialization

p1 = primitive_types_pb2.PrimitiveType()

# Alternative to GetCurrentTime()
# now = time.time()
# seconds = int( now )
# nanos = int( (now - seconds) * 10**9 )
# timestamp = timestamp_pb2.Timestamp( seconds=seconds, nanos=nanos )
# p1.timestamp_value.CopyFrom( timestamp )

p1.timestamp_value.GetCurrentTime()

serialized = p1.SerializeToString()

# deserialization

p2 = primitive_types_pb2.PrimitiveType()
p2.ParseFromString( serialized )

print( p2.timestamp_value )

Output:

seconds: 1590581054
nanos: 648958000

References:

Azeem
  • 11,148
  • 4
  • 27
  • 40
  • Hi, this is super helpful! Really really appreciate it. I am wondering would you be able to see code suggestions? For any Protobuf related code, I am not able to observe code suggestions in PyCharm. – Sidi Chang May 27 '20 at 21:00
  • @SidiChang: Glad it helped! Please refer to [The Protocol Buffer API](https://developers.google.com/protocol-buffers/docs/pythontutorial#the-protocol-buffer-api) section where it discusses the actual code generation at runtime. I wrote this in VSCode and there's no code intellisense for this. I'm not sure if an IDE or editor would be able to provide code intellisense for runtime code. Contrary to Python, I see the suggestions for C++ code as it is already generated and available. – Azeem May 27 '20 at 23:07