python-2.7datetimeprotocol-buffersprotobuf-python

Python Dict -> Protobuf Message Parse Error: Timestamp


I have a protobuf timestamp message that I'm trying to parse from a Python dictionary.

The target Protobuf message looks like this:

message LogStatusSnapshot {
    google.protobuf.Timestamp time = 1;
    LogStatus.LogStatusEnum status = 2;
    LogStatusLevel.LogStatusLevelEnum level = 3;
    string hostname = 4;
}

and a Python dictionary looks like this:

tl_snapshot = {u'status': u'FAILED', u'level': u'TEST_COMPUTER', u'hostname': u'mfg-line12', u'time': u'2022-10-26T13:14:07.831052'}

I'm parsing like so:

from google.protobuf.json_format import ParseDict
ParseDict(tl_snapshot, log_pb2.LogStatusSnapshot())

When I remove the time field, all other fields parse. I get an error from the ParseDict internal library saying:

ParseError: Failed to parse time field: time data '2022-10' does not match format '%Y-%m-%dT%H:%M:%S'.

I printed the tl_snapshot["time"] and verified that it is an acceptable RFC 3339 date string of length 26 characters. Unless I'm misusing the API, it seems Google's Protobuf ParseDict functionality is cutting off most of the characters of the date string I pass.

Software versions:
-Python 2.7
-Protobuf 3.6.1


Solution

  • Your dict's time value is not an RFC3339 compliant value because it does not include a timezone offset.

    RFC3339 is required by Timestamp.

    If you append Z (for Zulu i.e UTC+0) to the time value i.e. 2022-10-26T13:14:07.831052Z, it will work.

    You'll want to ensure that the values you generate for time are RFC3339 compliant. The Python 3.x libraries support this.