-
Notifications
You must be signed in to change notification settings - Fork 143
Description
🧩 Intermediate Contributors
This issue is intended for contributors who already have some familiarity with the
Hiero Python SDK codebase and contribution workflow.
You should feel comfortable:
- navigating existing source code and examples
- understanding SDK concepts without step-by-step guidance
- following the standard PR workflow without additional onboarding
If this is your very first contribution to the project, we recommend starting with a few
Good First Issues before working on this one.
🐞 Problem Description
Query is a child to executable and a parent of queries in the hiero python sdk.
this means all queries use Query, which uses Executable.
Methods from executable are inherited to Query and that is inherited to the query request being done
Query is a really important file but we lack explanation of what it does and offers
We are not looking for perfection, but something better than we currently have.
💡 Expected Solution
create docs/sdk_developers/training/query.md
based from the contents in:
src/hiero_sdk_python/query/query.py
and
examples/query
The assignee will have to study the contents at
src/hiero_sdk_python/query/query.py
and
examples/query
to understand more about how query works and document that.
When writing query.md, you may want to refer to an example in examples/query.md, or, you may even want to create your own example at examples/query/query.md.
🧠 Implementation Notes
The Query class is the base class for all Hedera network queries. Queries allow you to request data from the Hedera network, such as account balances, transaction information, or token info. Unlike transactions, queries do not change the network state, but some may require a payment to execute.
Query inherits from _Executable, meaning it benefits from the unified execution engine, including:
- Automatic retries
- Node selection and rotation
- gRPC network call orchestration
- Logging and error handling
- Child query classes implement query-specific behavior while _Executable handles the underlying execution mechanics.
Key Concepts
- Execution Flow
- When a Query is executed, the following steps happen:
- Pre-execution setup (_before_execute):
- Assigns nodes and operator
- Determines query payment if required
- Request building (_make_request):
- Constructs the Protobuf request for the network
- Includes payment transaction if required
- gRPC call (_get_method + _execute_method):
- Sends the request to a selected node
- Handles retries and backoff on temporary failures
- Response mapping (_map_response):
- Converts raw network response into a usable SDK object
- Retry handling (_should_retry):
- Automatically retries queries with retryable statuses like BUSY or PLATFORM_NOT_ACTIVE
- Error mapping (_map_status_error):
- Converts response errors into Python exceptions like PrecheckError or ReceiptStatusError
- Query Payment
Some queries require a payment. Payment is handled via a small CryptoTransfer transaction attached to the query request.
Use set_query_payment(amount: Hbar) to override the default payment
If no payment is set, the SDK can automatically query the cost using get_cost(client) before executing the query
from hiero_sdk_python.hbar import Hbar
query = AccountBalanceQuery(account_id)
query.set_query_payment(Hbar(1)) # Set custom payment to 1 Hbar
The SDK constructs a signed payment transaction using the operator’s private key.
- Abstract Methods
Subclasses must implement several methods:
| Method | Purpose |
|---|---|
| _get_query_response(response) | Extracts the specific query response from the full network response |
| _make_request() | Builds the Protobuf request for the specific query |
| _get_method(channel) | Returns the gRPC method wrapper (_Method) to call for this query |
| Method | Purpose |
|---|---|
| _map_response(response, node_id, proto_request) | Customize how the response is returned to the user |
| _should_retry(response) | Customize retry logic if needed |
| _map_status_error(response) | Customize error mapping |
- Retry Logic
Queries automatically handle retries for certain network issues:
Retryable statuses:
- BUSY
- PLATFORM_TRANSACTION_NOT_CREATED
- PLATFORM_NOT_ACTIVE
- The base _should_retry implementation handles these, but subclasses can extend it if necessary.
- Cost Queries
If a query requires payment but no amount is set, Query automatically fetches the cost from the network:
cost = query.get_cost(client)
print(f"Query cost: {cost} Hbar")
The SDK performs a COST_ANSWER query, returning the required Hbars to pay for the actual query.
- Building a Child Query
eg
from hiero_sdk_python.query.query import Query
from hiero_sdk_python.hapi.services import query_pb2, crypto_get_account_balance_pb2
class AccountBalanceQuery(Query):
def __init__(self, account_id):
super().__init__()
self.account_id = account_id
def _make_request(self):
header = self._make_request_header()
body = crypto_get_account_balance_pb2.CryptoGetAccountBalanceQuery(
header=header,
accountID=self.account_id._to_proto()
)
return query_pb2.Query(cryptoGetAccountBalance=body)
def _get_query_response(self, response):
return response.cryptoGetAccountBalance
def _get_method(self, channel):
return _Method(query_func=channel.crypto.get_account_balance)query = AccountBalanceQuery(my_account_id)
balance = query.execute(client)
print(f"Account balance: {balance.balance} Hbar")- Key Takeaways
Query handles all network-level logic; subclasses only implement query-specific behavior.
Queries may require payment, which is handled transparently via _build_query_payment_transaction.
Automatic retry and error handling ensures queries are robust against network issues.
Subclasses must implement:
_make_request()
_get_query_response()
_get_method()
You can override retry logic and response mapping if needed.
✅ Acceptance Criteria
To merge this issue, the pull request must:
- Fully address the problem described above
- Follow existing project conventions and patterns
- Include tests or example updates where appropriate
- Pass all CI checks
- Include a valid changelog entry
- Use DCO and GPG-signed commits