11from typing import Optional , Any , Union , List
2- from hiero_sdk_python .hapi .services import query_header_pb2 , transaction_get_record_pb2 , query_pb2
2+ from hiero_sdk_python .hapi .services import (
3+ query_header_pb2 ,
4+ transaction_get_record_pb2 ,
5+ query_pb2 ,
6+ )
37from hiero_sdk_python .query .query import Query
48from hiero_sdk_python .response_code import ResponseCode
59from hiero_sdk_python .transaction .transaction_id import TransactionId
@@ -16,34 +20,38 @@ class TransactionRecordQuery(Query):
1620 Represents a query for a transaction record on the Hedera network.
1721 """
1822
19- def __init__ (self , transaction_id : Optional [TransactionId ] = None , include_children : bool = False ):
23+ def __init__ (
24+ self ,
25+ transaction_id : Optional [TransactionId ] = None ,
26+ include_children : bool = False ,
27+ ):
2028 """
2129 Initializes the TransactionRecordQuery with the provided transaction ID.
2230 """
2331 super ().__init__ ()
24- self .transaction_id : Optional [TransactionId ] = transaction_id
32+ self .transaction_id : Optional [TransactionId ] = transaction_id
2533 self .include_children = include_children
26-
27-
34+
2835 def set_transaction_id (self , transaction_id : TransactionId ):
2936 """
3037 Sets the transaction ID for the query.
31-
38+
3239 Args:
3340 transaction_id (TransactionId): The ID of the transaction to query.
3441 Returns:
3542 TransactionRecordQuery: This query instance.
3643 """
3744 self .transaction_id = transaction_id
3845 return self
39-
46+
4047 def set_include_children (self , include_children ):
4148 self .include_children = include_children
49+ return self
4250
4351 def _make_request (self ):
4452 """
4553 Constructs the protobuf request for the transaction record query.
46-
54+
4755 Builds a TransactionGetRecordQuery protobuf message with the
4856 appropriate header and transaction ID.
4957
@@ -57,19 +65,27 @@ def _make_request(self):
5765 """
5866 try :
5967 if not self .transaction_id :
60- raise ValueError ("Transaction ID must be set before making the request." )
68+ raise ValueError (
69+ "Transaction ID must be set before making the request."
70+ )
6171
6272 query_header = self ._make_request_header ()
63- transaction_get_record = transaction_get_record_pb2 .TransactionGetRecordQuery ()
73+ transaction_get_record = (
74+ transaction_get_record_pb2 .TransactionGetRecordQuery ()
75+ )
6476 transaction_get_record .header .CopyFrom (query_header )
77+
78+ transaction_get_record .transactionID .CopyFrom (
79+ self .transaction_id ._to_proto ()
80+ )
6581 transaction_get_record .include_child_records = self .include_children
66- transaction_get_record .transactionID .CopyFrom (self .transaction_id ._to_proto ())
67-
6882 query = query_pb2 .Query ()
69- if not hasattr (query , 'transactionGetRecord' ):
70- raise AttributeError ("Query object has no attribute 'transactionGetRecord'" )
83+ if not hasattr (query , "transactionGetRecord" ):
84+ raise AttributeError (
85+ "Query object has no attribute 'transactionGetRecord'"
86+ )
7187 query .transactionGetRecord .CopyFrom (transaction_get_record )
72-
88+
7389 return query
7490 except Exception as e :
7591 print (f"Exception in _make_request: { e } " )
@@ -78,7 +94,7 @@ def _make_request(self):
7894 def _get_method (self , channel : _Channel ) -> _Method :
7995 """
8096 Returns the appropriate gRPC method for the transaction receipt query.
81-
97+
8298 Implements the abstract method from Query to provide the specific
8399 gRPC method for getting transaction receipts.
84100
@@ -89,14 +105,13 @@ def _get_method(self, channel: _Channel) -> _Method:
89105 _Method: The method wrapper containing the query function
90106 """
91107 return _Method (
92- transaction_func = None ,
93- query_func = channel .crypto .getTxRecordByTxID
108+ transaction_func = None , query_func = channel .crypto .getTxRecordByTxID
94109 )
95110
96111 def _should_retry (self , response : Any ) -> _ExecutionState :
97112 """
98113 Determines whether the query should be retried based on the response.
99-
114+
100115 Implements the abstract method from Query to decide whether to retry
101116 the query based on the response status code. First checks the header status,
102117 then the receipt status.
@@ -108,37 +123,45 @@ def _should_retry(self, response: Any) -> _ExecutionState:
108123 _ExecutionState: The execution state indicating what to do next
109124 """
110125 status = response .transactionGetRecord .header .nodeTransactionPrecheckCode
111-
126+
112127 retryable_statuses = {
113128 ResponseCode .UNKNOWN ,
114129 ResponseCode .BUSY ,
115130 ResponseCode .RECEIPT_NOT_FOUND ,
116131 ResponseCode .RECORD_NOT_FOUND ,
117- ResponseCode .PLATFORM_NOT_ACTIVE
132+ ResponseCode .PLATFORM_NOT_ACTIVE ,
118133 }
119-
134+
120135 if status == ResponseCode .OK :
121- if response .transactionGetRecord .header .responseType == query_header_pb2 .ResponseType .COST_ANSWER :
136+ if (
137+ response .transactionGetRecord .header .responseType
138+ == query_header_pb2 .ResponseType .COST_ANSWER
139+ ):
122140 return _ExecutionState .FINISHED
123141 pass
124- elif status in retryable_statuses or status == ResponseCode .PLATFORM_TRANSACTION_NOT_CREATED :
142+ elif (
143+ status in retryable_statuses
144+ or status == ResponseCode .PLATFORM_TRANSACTION_NOT_CREATED
145+ ):
125146 return _ExecutionState .RETRY
126147 else :
127148 return _ExecutionState .ERROR
128-
149+
129150 status = response .transactionGetRecord .transactionRecord .receipt .status
130-
151+
131152 if status in retryable_statuses or status == ResponseCode .OK :
132153 return _ExecutionState .RETRY
133154 elif status == ResponseCode .SUCCESS :
134155 return _ExecutionState .FINISHED
135156 else :
136157 return _ExecutionState .ERROR
137-
138- def _map_status_error (self , response : Any ) -> Union [PrecheckError ,ReceiptStatusError ]:
158+
159+ def _map_status_error (
160+ self , response : Any
161+ ) -> Union [PrecheckError , ReceiptStatusError ]:
139162 """
140163 Maps a response status code to an appropriate error object.
141-
164+
142165 Implements the abstract method from Executable to create error objects
143166 from response status codes. Checks both the header status and receipt status.
144167
@@ -156,23 +179,37 @@ def _map_status_error(self, response: Any) -> Union[PrecheckError,ReceiptStatusE
156179 ResponseCode .UNKNOWN ,
157180 ResponseCode .RECEIPT_NOT_FOUND ,
158181 ResponseCode .RECORD_NOT_FOUND ,
159- ResponseCode .OK
182+ ResponseCode .OK ,
160183 }
161-
184+
162185 if status not in retryable_statuses :
163186 return PrecheckError (status )
164-
187+
165188 receipt = response .transactionGetRecord .transactionRecord .receipt
166-
167- return ReceiptStatusError (status , self .transaction_id , TransactionReceipt ._from_proto (receipt , self .transaction_id ))
168-
189+
190+ return ReceiptStatusError (
191+ status ,
192+ self .transaction_id ,
193+ TransactionReceipt ._from_proto (receipt , self .transaction_id ),
194+ )
195+
196+ def _map_record_list (
197+ self ,
198+ proto_records : List [transaction_get_record_pb2 .TransactionGetRecordResponse ],
199+ ) -> List [TransactionRecord ]:
200+ records : List [TransactionRecord ] = []
201+ for record in proto_records :
202+ records .append (TransactionRecord ._from_proto (record , self .transaction_id ))
203+
204+ return records
205+
169206 def execute (self , client ):
170207 """
171208 Executes the transaction record query.
172-
209+
173210 Sends the query to the Hedera network and processes the response
174211 to return a TransactionRecord object.
175-
212+
176213 This function delegates the core logic to `_execute()`, and may propagate exceptions raised by it.
177214
178215 Args:
@@ -188,27 +225,27 @@ def execute(self, client):
188225 """
189226 self ._before_execute (client )
190227 response = self ._execute (client )
191- #childrens = self._map_record_list(response.child_transaction_records)
192- return TransactionRecord ._from_proto (response .transactionGetRecord .transactionRecord , self .transaction_id )
228+ if not response .HasField ("transactionGetRecord" ):
229+ raise AttributeError ("Response does not contain 'transactionGetRecord'" )
230+ record_response = response .transactionGetRecord
231+ children = self ._map_record_list (record_response .child_transaction_records )
232+ return TransactionRecord ._from_proto (
233+ response .transactionGetRecord .transactionRecord ,
234+ self .transaction_id ,
235+ children = children ,
236+ )
193237
194238 def _get_query_response (self , response : Any ):
195239 """
196240 Extracts the transaction record response from the full response.
197-
241+
198242 Implements the abstract method from Query to extract the
199243 specific transaction record response object.
200-
244+
201245 Args:
202246 response: The full response from the network
203-
247+
204248 Returns:
205249 The transaction get record response object
206250 """
207251 return response .transactionGetRecord
208-
209- def _map_record_list (self , proto_records : List [transaction_get_record_pb2 .TransactionGetRecordResponse ]) -> List [TransactionRecord ]:
210- records : List [TransactionRecord ] = []
211- for record in proto_records :
212- records .append (TransactionRecord ._from_proto (record , self .transaction_id ))
213-
214- return records
0 commit comments