1
1
from datetime import datetime
2
- from typing import Optional , List , Union
2
+ from typing import Optional , List , Union , Dict
3
3
from hiero_sdk_python .hapi .mirror import consensus_service_pb2 as mirror_proto
4
4
5
5
def _to_datetime (ts_proto ) -> datetime :
@@ -30,16 +30,26 @@ class TopicMessage:
30
30
def __init__ (
31
31
self ,
32
32
consensus_timestamp : datetime ,
33
- contents : bytes ,
34
- running_hash : bytes ,
35
- sequence_number : int ,
33
+ message_data : Dict [str , Union [bytes , int ]],
36
34
chunks : List [TopicMessageChunk ],
37
35
transaction_id : Optional [str ] = None ,
38
36
):
37
+ """
38
+ Args:
39
+ consensus_timestamp: The final consensus timestamp.
40
+ message_data: Dict with required fields:
41
+ {
42
+ "contents": bytes,
43
+ "running_hash": bytes,
44
+ "sequence_number": int
45
+ }
46
+ chunks: All individual chunks that form this message.
47
+ transaction_id: The transaction ID string if available.
48
+ """
39
49
self .consensus_timestamp = consensus_timestamp
40
- self .contents = contents
41
- self .running_hash = running_hash
42
- self .sequence_number = sequence_number
50
+ self .contents = message_data [ " contents" ]
51
+ self .running_hash = message_data [ " running_hash" ]
52
+ self .sequence_number = message_data [ " sequence_number" ]
43
53
self .chunks = chunks
44
54
self .transaction_id = transaction_id
45
55
@@ -52,7 +62,7 @@ def of_single(cls, response: mirror_proto.ConsensusTopicResponse) -> "TopicMessa
52
62
consensus_timestamp = chunk .consensus_timestamp
53
63
contents = response .message
54
64
running_hash = response .runningHash
55
- sequence_number = response .sequence_number
65
+ sequence_number = chunk .sequence_number
56
66
57
67
transaction_id = None
58
68
if response .HasField ("chunkInfo" ) and response .chunkInfo .HasField ("initialTransactionID" ):
@@ -64,9 +74,11 @@ def of_single(cls, response: mirror_proto.ConsensusTopicResponse) -> "TopicMessa
64
74
65
75
return cls (
66
76
consensus_timestamp ,
67
- contents ,
68
- running_hash ,
69
- sequence_number ,
77
+ {
78
+ "contents" : contents ,
79
+ "running_hash" : running_hash ,
80
+ "sequence_number" : sequence_number ,
81
+ },
70
82
[chunk ],
71
83
transaction_id
72
84
)
@@ -87,9 +99,11 @@ def of_many(cls, responses: List[mirror_proto.ConsensusTopicResponse]) -> "Topic
87
99
chunks .append (c )
88
100
total_size += len (r .message )
89
101
90
- if (transaction_id is None
102
+ if (
103
+ transaction_id is None
91
104
and r .HasField ("chunkInfo" )
92
- and r .chunkInfo .HasField ("initialTransactionID" )):
105
+ and r .chunkInfo .HasField ("initialTransactionID" )
106
+ ):
93
107
tx_id = r .chunkInfo .initialTransactionID
94
108
transaction_id = (
95
109
f"{ tx_id .shardNum } .{ tx_id .realmNum } .{ tx_id .accountNum } -"
@@ -110,9 +124,11 @@ def of_many(cls, responses: List[mirror_proto.ConsensusTopicResponse]) -> "Topic
110
124
111
125
return cls (
112
126
consensus_timestamp ,
113
- bytes (contents ),
114
- running_hash ,
115
- sequence_number ,
127
+ {
128
+ "contents" : bytes (contents ),
129
+ "running_hash" : running_hash ,
130
+ "sequence_number" : sequence_number ,
131
+ },
116
132
chunks ,
117
133
transaction_id
118
134
)
@@ -131,14 +147,7 @@ def from_proto(
131
147
If chunking is enabled and multiple chunks are detected, they are reassembled
132
148
into one combined TopicMessage. Otherwise, a single chunk is returned as-is.
133
149
"""
134
- if isinstance (response_or_responses , mirror_proto .ConsensusTopicResponse ):
135
- response = response_or_responses
136
- if chunking_enabled and response .HasField ("chunkInfo" ) and response .chunkInfo .total > 1 :
137
- raise ValueError (
138
- "Cannot handle multi-chunk in a single response. Pass all chunk responses in a list."
139
- )
140
- return cls .of_single (response )
141
- else :
150
+ if not isinstance (response_or_responses , mirror_proto .ConsensusTopicResponse ):
142
151
if not response_or_responses :
143
152
raise ValueError ("Empty response list provided to from_proto()." )
144
153
@@ -147,6 +156,13 @@ def from_proto(
147
156
148
157
return cls .of_many (response_or_responses )
149
158
159
+ response = response_or_responses
160
+ if chunking_enabled and response .HasField ("chunkInfo" ) and response .chunkInfo .total > 1 :
161
+ raise ValueError (
162
+ "Cannot handle multi-chunk in a single response. Pass all chunk responses in a list."
163
+ )
164
+ return cls .of_single (response )
165
+
150
166
def __str__ (self ):
151
167
contents_str = self .contents .decode ("utf-8" , errors = "replace" )
152
168
return (
0 commit comments