Skip to content

Introduce SubtensorApi interface for SDK #2862

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8000b16
initial
basfroman May 2, 2025
16caf75
Merge branch 'refs/heads/staging' into feat/roman/subtensor-api
basfroman May 2, 2025
8621ede
add sub-package
basfroman May 2, 2025
36c447f
add sub-classes
basfroman May 2, 2025
0068f2a
add `utils.add_classic_fields`
basfroman May 2, 2025
66ccb7d
ruff
basfroman May 2, 2025
f46a249
to be consistent
basfroman May 2, 2025
745a126
to be consistent + setter
basfroman May 2, 2025
6595299
initialize for async instance
basfroman May 2, 2025
62ebe3a
add compatability tests
basfroman May 2, 2025
23a862f
one more compatability test
basfroman May 2, 2025
8f9623e
fix async instance `initialize`
basfroman May 2, 2025
ff0ddf5
rename argument
basfroman May 2, 2025
68c3472
rename argument legacy_methods
basfroman May 5, 2025
e85e269
improve subtensors
basfroman May 6, 2025
b3c7159
Update SubtensorApi
basfroman May 6, 2025
329ce85
fix tests
basfroman May 6, 2025
b470d78
update docstrings, fix bug
basfroman May 6, 2025
04d4c42
move add_args
basfroman May 6, 2025
58a8700
Merge branch 'staging' into feat/roman/subtensor-api
basfroman May 6, 2025
2093abf
fix docstrings
basfroman May 6, 2025
bc9ec3e
Merge remote-tracking branch 'origin/feat/roman/subtensor-api' into f…
basfroman May 6, 2025
5b05f4d
Update bittensor/core/subtensor.py
basfroman May 7, 2025
d0243e4
Update bittensor/core/subtensor_api/__init__.py
basfroman May 7, 2025
6a255d7
Update bittensor/core/async_subtensor.py
basfroman May 7, 2025
0e1ccbf
fix
basfroman May 7, 2025
afb5f3d
bumping version
basfroman May 7, 2025
ff9c533
checker
basfroman May 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions bittensor/core/async_subtensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import numpy as np
import scalecodec
from async_substrate_interface import AsyncSubstrateInterface
from async_substrate_interface.substrate_addons import RetryAsyncSubstrate
from bittensor_drand import get_encrypted_commitment
from bittensor_wallet.utils import SS58_FORMAT
from numpy.typing import NDArray
Expand Down Expand Up @@ -114,17 +115,21 @@ def __init__(
self,
network: Optional[str] = None,
config: Optional["Config"] = None,
_mock: bool = False,
log_verbose: bool = False,
fallback_chains: Optional[list[str]] = None,
retry_forever: bool = False,
_mock: bool = False,
):
"""
Initializes an instance of the AsyncSubtensor class.

Arguments:
network (str): The network name or type to connect to.
config (Optional[Config]): Configuration object for the AsyncSubtensor instance.
_mock: Whether this is a mock instance. Mainly just for use in testing.
log_verbose (bool): Enables or disables verbose logging.
fallback_chains (list): List of fallback chains endpoints to use if no network is specified. Defaults to `None`.
retry_forever (bool): Whether to retry forever on connection errors. Defaults to `False`.
_mock: Whether this is a mock instance. Mainly just for use in testing.

Raises:
Any exceptions raised during the setup, configuration, or connection process.
Expand All @@ -143,13 +148,8 @@ def __init__(
f"Connecting to network: [blue]{self.network}[/blue], "
f"chain_endpoint: [blue]{self.chain_endpoint}[/blue]..."
)
self.substrate = AsyncSubstrateInterface(
url=self.chain_endpoint,
ss58_format=SS58_FORMAT,
type_registry=TYPE_REGISTRY,
use_remote_preset=True,
chain_name="Bittensor",
_mock=_mock,
self.substrate = self._get_substrate(
fallback_chains=fallback_chains, retry_forever=retry_forever, _mock=_mock
)
if self.log_verbose:
logging.info(
Expand Down Expand Up @@ -283,6 +283,42 @@ async def get_hyperparameter(

return getattr(result, "value", result)

def _get_substrate(
self,
fallback_chains: Optional[list[str]] = None,
retry_forever: bool = False,
_mock: bool = False,
) -> Union[AsyncSubstrateInterface, RetryAsyncSubstrate]:
"""Creates the Substrate instance based on provided arguments.

Arguments:
fallback_chains (list): List of fallback chains endpoints to use if no network is specified. Defaults to `None`.
retry_forever (bool): Whether to retry forever on connection errors. Defaults to `False`.
_mock: Whether this is a mock instance. Mainly just for use in testing.

Returns:
the instance of the SubstrateInterface or RetrySyncSubstrate class.
"""
if fallback_chains or retry_forever:
return RetryAsyncSubstrate(
url=self.chain_endpoint,
fallback_chains=fallback_chains,
ss58_format=SS58_FORMAT,
type_registry=TYPE_REGISTRY,
retry_forever=retry_forever,
use_remote_preset=True,
chain_name="Bittensor",
_mock=_mock,
)
return AsyncSubstrateInterface(
url=self.chain_endpoint,
ss58_format=SS58_FORMAT,
type_registry=TYPE_REGISTRY,
use_remote_preset=True,
chain_name="Bittensor",
_mock=_mock,
)

# Subtensor queries ===========================================================================================

async def query_constant(
Expand Down
58 changes: 46 additions & 12 deletions bittensor/core/subtensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import numpy as np
import scalecodec
from async_substrate_interface.errors import SubstrateRequestException
from async_substrate_interface.substrate_addons import RetrySyncSubstrate
from async_substrate_interface.sync_substrate import SubstrateInterface
from async_substrate_interface.types import ScaleObj
from bittensor_drand import get_encrypted_commitment
Expand Down Expand Up @@ -116,17 +117,21 @@ def __init__(
self,
network: Optional[str] = None,
config: Optional["Config"] = None,
_mock: bool = False,
log_verbose: bool = False,
fallback_chains: Optional[list[str]] = None,
retry_forever: bool = False,
_mock: bool = False,
):
"""
Initializes an instance of the Subtensor class.

Arguments:
network (str): The network name or type to connect to.
config (Optional[Config]): Configuration object for the AsyncSubtensor instance.
_mock: Whether this is a mock instance. Mainly just for use in testing.
log_verbose (bool): Enables or disables verbose logging.
fallback_chains (list): List of fallback chains endpoints to use if no network is specified. Defaults to `None`.
retry_forever (bool): Whether to retry forever on connection errors. Defaults to `False`.
_mock: Whether this is a mock instance. Mainly just for use in testing.

Raises:
Any exceptions raised during the setup, configuration, or connection process.
Expand All @@ -143,13 +148,8 @@ def __init__(
f"Connecting to network: [blue]{self.network}[/blue], "
f"chain_endpoint: [blue]{self.chain_endpoint}[/blue]> ..."
)
self.substrate = SubstrateInterface(
url=self.chain_endpoint,
ss58_format=SS58_FORMAT,
type_registry=TYPE_REGISTRY,
use_remote_preset=True,
chain_name="Bittensor",
_mock=_mock,
self.substrate = self._get_substrate(
fallback_chains=fallback_chains, retry_forever=retry_forever, _mock=_mock
)
if self.log_verbose:
logging.info(
Expand All @@ -163,11 +163,45 @@ def __exit__(self, exc_type, exc_val, exc_tb):
self.close()

def close(self):
"""
Closes the websocket connection
"""
"""Closes the websocket connection."""
self.substrate.close()

def _get_substrate(
self,
fallback_chains: Optional[list[str]] = None,
retry_forever: bool = False,
_mock: bool = False,
) -> Union[SubstrateInterface, RetrySyncSubstrate]:
"""Creates the Substrate instance based on provided arguments.

Arguments:
fallback_chains (list): List of fallback chains endpoints to use if no network is specified. Defaults to `None`.
retry_forever (bool): Whether to retry forever on connection errors. Defaults to `False`.
_mock: Whether this is a mock instance. Mainly just for use in testing.

Returns:
the instance of the SubstrateInterface or RetrySyncSubstrate class.
"""
if fallback_chains or retry_forever:
return RetrySyncSubstrate(
url=self.chain_endpoint,
ss58_format=SS58_FORMAT,
type_registry=TYPE_REGISTRY,
use_remote_preset=True,
chain_name="Bittensor",
fallback_chains=fallback_chains,
retry_forever=retry_forever,
_mock=_mock,
)
return SubstrateInterface(
url=self.chain_endpoint,
ss58_format=SS58_FORMAT,
type_registry=TYPE_REGISTRY,
use_remote_preset=True,
chain_name="Bittensor",
_mock=_mock,
)

# Subtensor queries ===========================================================================================

def query_constant(
Expand Down
Loading