bittensor 6.7.2__tar.gz → 6.7.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. {bittensor-6.7.2/bittensor.egg-info → bittensor-6.7.3}/PKG-INFO +2 -45
  2. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/__init__.py +1 -1
  3. {bittensor-6.7.2 → bittensor-6.7.3/bittensor.egg-info}/PKG-INFO +2 -45
  4. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor.egg-info/SOURCES.txt +0 -5
  5. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor.egg-info/requires.txt +3 -3
  6. bittensor-6.7.2/bittensor/subnets/api.py +0 -297
  7. bittensor-6.7.2/bittensor/subnets/cache.py +0 -230
  8. bittensor-6.7.2/bittensor/subnets/registry.py +0 -53
  9. bittensor-6.7.2/bittensor/subnets/request.py +0 -143
  10. bittensor-6.7.2/bittensor/subnets/utils.py +0 -68
  11. {bittensor-6.7.2 → bittensor-6.7.3}/LICENSE +0 -0
  12. {bittensor-6.7.2 → bittensor-6.7.3}/README.md +0 -0
  13. {bittensor-6.7.2 → bittensor-6.7.3}/bin/btcli +0 -0
  14. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/axon.py +0 -0
  15. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/btlogging.py +0 -0
  16. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/chain_data.py +0 -0
  17. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/cli.py +0 -0
  18. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/__init__.py +0 -0
  19. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/delegates.py +0 -0
  20. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/identity.py +0 -0
  21. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/inspect.py +0 -0
  22. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/list.py +0 -0
  23. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/metagraph.py +0 -0
  24. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/misc.py +0 -0
  25. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/network.py +0 -0
  26. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/overview.py +0 -0
  27. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/register.py +0 -0
  28. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/root.py +0 -0
  29. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/senate.py +0 -0
  30. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/stake.py +0 -0
  31. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/transfer.py +0 -0
  32. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/unstake.py +0 -0
  33. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/utils.py +0 -0
  34. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/commands/wallets.py +0 -0
  35. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/config.py +0 -0
  36. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/dendrite.py +0 -0
  37. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/errors.py +0 -0
  38. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/__init__.py +0 -0
  39. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/delegation.py +0 -0
  40. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/network.py +0 -0
  41. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/prometheus.py +0 -0
  42. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/registration.py +0 -0
  43. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/root.py +0 -0
  44. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/senate.py +0 -0
  45. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/serving.py +0 -0
  46. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/set_weights.py +0 -0
  47. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/staking.py +0 -0
  48. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/transfer.py +0 -0
  49. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/extrinsics/unstaking.py +0 -0
  50. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/keyfile.py +0 -0
  51. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/metagraph.py +0 -0
  52. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/mock/__init__.py +0 -0
  53. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/mock/keyfile_mock.py +0 -0
  54. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/mock/subtensor_mock.py +0 -0
  55. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/mock/wallet_mock.py +0 -0
  56. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/stream.py +0 -0
  57. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/subtensor.py +0 -0
  58. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/synapse.py +0 -0
  59. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/tensor.py +0 -0
  60. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/threadpool.py +0 -0
  61. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/types.py +0 -0
  62. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/__init__.py +0 -0
  63. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/_register_cuda.py +0 -0
  64. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/balance.py +0 -0
  65. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/formatting.py +0 -0
  66. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/networking.py +0 -0
  67. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/registration.py +0 -0
  68. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/test_utils.py +0 -0
  69. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/wallet_utils.py +0 -0
  70. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/utils/weight_utils.py +0 -0
  71. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor/wallet.py +0 -0
  72. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor.egg-info/dependency_links.txt +0 -0
  73. {bittensor-6.7.2 → bittensor-6.7.3}/bittensor.egg-info/top_level.txt +0 -0
  74. {bittensor-6.7.2 → bittensor-6.7.3}/setup.cfg +0 -0
  75. {bittensor-6.7.2 → bittensor-6.7.3}/setup.py +0 -0
  76. {bittensor-6.7.2 → bittensor-6.7.3}/tests/__init__.py +0 -0
  77. {bittensor-6.7.2 → bittensor-6.7.3}/tests/helpers/__init__.py +0 -0
  78. {bittensor-6.7.2 → bittensor-6.7.3}/tests/helpers/helpers.py +0 -0
  79. {bittensor-6.7.2 → bittensor-6.7.3}/tests/integration_tests/__init__.py +0 -0
  80. {bittensor-6.7.2 → bittensor-6.7.3}/tests/integration_tests/test_cli.py +0 -0
  81. {bittensor-6.7.2 → bittensor-6.7.3}/tests/integration_tests/test_cli_no_network.py +0 -0
  82. {bittensor-6.7.2 → bittensor-6.7.3}/tests/integration_tests/test_metagraph_integration.py +0 -0
  83. {bittensor-6.7.2 → bittensor-6.7.3}/tests/integration_tests/test_subtensor_integration.py +0 -0
  84. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/__init__.py +0 -0
  85. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_axon.py +0 -0
  86. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_chain_data.py +0 -0
  87. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_dendrite.py +0 -0
  88. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_keyfile.py +0 -0
  89. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_metagraph.py +0 -0
  90. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_subtensor.py +0 -0
  91. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_synapse.py +0 -0
  92. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_tensor.py +0 -0
  93. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/test_wallet.py +0 -0
  94. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/utils/__init__.py +0 -0
  95. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/utils/test_balance.py +0 -0
  96. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/utils/test_networking.py +0 -0
  97. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/utils/test_utils.py +0 -0
  98. {bittensor-6.7.2 → bittensor-6.7.3}/tests/unit_tests/utils/test_weight_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bittensor
3
- Version: 6.7.2
3
+ Version: 6.7.3
4
4
  Summary: bittensor
5
5
  Home-page: https://github.com/opentensor/bittensor
6
6
  Author: bittensor.com
@@ -22,51 +22,8 @@ Classifier: Topic :: Software Development :: Libraries
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Python: >=3.8
24
24
  Description-Content-Type: text/markdown
25
- License-File: LICENSE
26
- Requires-Dist: aiohttp==3.9.0b0
27
- Requires-Dist: ansible==6.7.0
28
- Requires-Dist: ansible_vault==2.1.0
29
- Requires-Dist: backoff
30
- Requires-Dist: black==23.7.0
31
- Requires-Dist: cryptography==41.0.3
32
- Requires-Dist: ddt==1.6.0
33
- Requires-Dist: fuzzywuzzy>=0.18.0
34
- Requires-Dist: fastapi==0.99.1
35
- Requires-Dist: loguru==0.7.0
36
- Requires-Dist: munch==2.5.0
37
- Requires-Dist: netaddr
38
- Requires-Dist: numpy
39
- Requires-Dist: msgpack-numpy-opentensor==0.5.0
40
- Requires-Dist: nest_asyncio
41
- Requires-Dist: pycryptodome<4.0.0,>=3.18.0
42
- Requires-Dist: pyyaml
43
- Requires-Dist: password_strength
44
- Requires-Dist: pydantic!=1.8,!=1.8.1,<2.0.0,>=1.7.4
45
- Requires-Dist: PyNaCl<=1.5.0,>=1.3.0
46
- Requires-Dist: pytest-asyncio
47
- Requires-Dist: python-Levenshtein
48
- Requires-Dist: pytest
49
- Requires-Dist: retry
50
- Requires-Dist: requests
51
- Requires-Dist: rich
52
- Requires-Dist: scalecodec==1.2.7
53
- Requires-Dist: shtab==1.6.5
54
- Requires-Dist: substrate-interface==1.7.5
55
- Requires-Dist: termcolor
56
- Requires-Dist: torch>=1.13.1
57
- Requires-Dist: tqdm
58
- Requires-Dist: uvicorn==0.22.0
59
- Requires-Dist: wheel
60
25
  Provides-Extra: dev
61
- Requires-Dist: pytest==7.2.0; extra == "dev"
62
- Requires-Dist: pytest-mock==3.12.0; extra == "dev"
63
- Requires-Dist: pytest-split==0.8.0; extra == "dev"
64
- Requires-Dist: pytest-xdist==3.0.2; extra == "dev"
65
- Requires-Dist: pytest-rerunfailures==10.2; extra == "dev"
66
- Requires-Dist: coveralls==3.3.1; extra == "dev"
67
- Requires-Dist: pytest-cov==4.0.0; extra == "dev"
68
- Requires-Dist: ddt==1.6.0; extra == "dev"
69
- Requires-Dist: hypothesis==6.81.1; extra == "dev"
26
+ License-File: LICENSE
70
27
 
71
28
  <div align="center">
72
29
 
@@ -27,7 +27,7 @@ import nest_asyncio
27
27
  nest_asyncio.apply()
28
28
 
29
29
  # Bittensor code and protocol version.
30
- __version__ = "6.7.2"
30
+ __version__ = "6.7.3"
31
31
 
32
32
  version_split = __version__.split(".")
33
33
  __version_as_int__ = (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bittensor
3
- Version: 6.7.2
3
+ Version: 6.7.3
4
4
  Summary: bittensor
5
5
  Home-page: https://github.com/opentensor/bittensor
6
6
  Author: bittensor.com
@@ -22,51 +22,8 @@ Classifier: Topic :: Software Development :: Libraries
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Python: >=3.8
24
24
  Description-Content-Type: text/markdown
25
- License-File: LICENSE
26
- Requires-Dist: aiohttp==3.9.0b0
27
- Requires-Dist: ansible==6.7.0
28
- Requires-Dist: ansible_vault==2.1.0
29
- Requires-Dist: backoff
30
- Requires-Dist: black==23.7.0
31
- Requires-Dist: cryptography==41.0.3
32
- Requires-Dist: ddt==1.6.0
33
- Requires-Dist: fuzzywuzzy>=0.18.0
34
- Requires-Dist: fastapi==0.99.1
35
- Requires-Dist: loguru==0.7.0
36
- Requires-Dist: munch==2.5.0
37
- Requires-Dist: netaddr
38
- Requires-Dist: numpy
39
- Requires-Dist: msgpack-numpy-opentensor==0.5.0
40
- Requires-Dist: nest_asyncio
41
- Requires-Dist: pycryptodome<4.0.0,>=3.18.0
42
- Requires-Dist: pyyaml
43
- Requires-Dist: password_strength
44
- Requires-Dist: pydantic!=1.8,!=1.8.1,<2.0.0,>=1.7.4
45
- Requires-Dist: PyNaCl<=1.5.0,>=1.3.0
46
- Requires-Dist: pytest-asyncio
47
- Requires-Dist: python-Levenshtein
48
- Requires-Dist: pytest
49
- Requires-Dist: retry
50
- Requires-Dist: requests
51
- Requires-Dist: rich
52
- Requires-Dist: scalecodec==1.2.7
53
- Requires-Dist: shtab==1.6.5
54
- Requires-Dist: substrate-interface==1.7.5
55
- Requires-Dist: termcolor
56
- Requires-Dist: torch>=1.13.1
57
- Requires-Dist: tqdm
58
- Requires-Dist: uvicorn==0.22.0
59
- Requires-Dist: wheel
60
25
  Provides-Extra: dev
61
- Requires-Dist: pytest==7.2.0; extra == "dev"
62
- Requires-Dist: pytest-mock==3.12.0; extra == "dev"
63
- Requires-Dist: pytest-split==0.8.0; extra == "dev"
64
- Requires-Dist: pytest-xdist==3.0.2; extra == "dev"
65
- Requires-Dist: pytest-rerunfailures==10.2; extra == "dev"
66
- Requires-Dist: coveralls==3.3.1; extra == "dev"
67
- Requires-Dist: pytest-cov==4.0.0; extra == "dev"
68
- Requires-Dist: ddt==1.6.0; extra == "dev"
69
- Requires-Dist: hypothesis==6.81.1; extra == "dev"
26
+ License-File: LICENSE
70
27
 
71
28
  <div align="center">
72
29
 
@@ -57,11 +57,6 @@ bittensor/mock/__init__.py
57
57
  bittensor/mock/keyfile_mock.py
58
58
  bittensor/mock/subtensor_mock.py
59
59
  bittensor/mock/wallet_mock.py
60
- bittensor/subnets/api.py
61
- bittensor/subnets/cache.py
62
- bittensor/subnets/registry.py
63
- bittensor/subnets/request.py
64
- bittensor/subnets/utils.py
65
60
  bittensor/utils/__init__.py
66
61
  bittensor/utils/_register_cuda.py
67
62
  bittensor/utils/balance.py
@@ -24,9 +24,9 @@ pytest
24
24
  retry
25
25
  requests
26
26
  rich
27
- scalecodec==1.2.7
28
- shtab==1.6.5
29
- substrate-interface==1.7.5
27
+ scalecodec==1.2.11
28
+ shtab~=1.6.5
29
+ substrate-interface~=1.7.9
30
30
  termcolor
31
31
  torch>=1.13.1
32
32
  tqdm
@@ -1,297 +0,0 @@
1
- # The MIT License (MIT)
2
- # Copyright © 2021 Yuma Rao
3
- # Copyright © 2023 Opentensor Foundation
4
- # Copyright © 2023 Opentensor Technologies Inc
5
-
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7
- # documentation files (the “Software”), to deal in the Software without restriction, including without limitation
8
- # the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9
- # and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
-
11
- # The above copyright notice and this permission notice shall be included in all copies or substantial portions of
12
- # the Software.
13
-
14
- # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
15
- # THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
- # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
- # DEALINGS IN THE SOFTWARE.
19
-
20
- import time
21
- import redis
22
- import random
23
- import bittensor as bt
24
-
25
- from abc import ABC, abstractmethod
26
- from typing import Any, List, Union, Optional, Tuple, Dict
27
- from .utils import serialize_metagraph, deserialize_metagraph
28
- from .registry import APIRegistry, register_handler
29
-
30
-
31
- class SubnetsAPI(ABC):
32
- def __init__(
33
- self, wallet: "bt.wallet", network: str, netuids: List[int] = None, interval=60
34
- ):
35
- self.wallet = wallet
36
- self.dendrite = bittensor.dendrite(wallet=wallet)
37
- self.subtensor = bittensor.subtensor(network)
38
-
39
- host = getenv("REDIS_HOST") or "localhost"
40
- port = getenv("REDIS_PORT") or 6379
41
- db = getenv("REDIS_DB") or 10
42
- self.database = redis.StrictRedis(host=host, port=port, db=db)
43
-
44
- stored_netuids = self.get_available_redis_metagraph_netuids()
45
- if netuids is not None:
46
- if not all([netuid in stored_netuids for netuid in netuids]):
47
- bt.logging.debug(
48
- f"Not all passed netuids in stored metagraphs. Fetching: {netuids}"
49
- )
50
- self.init_redis_global_metagraph(netuids)
51
- else:
52
- bt.logging.debug(
53
- f"All passed netuids in stored metagraphs... skipping fetch"
54
- )
55
- else:
56
- netuids = self.subtensor.get_all_subnet_netuids()
57
- bt.logging.info(f"Initializing global metagraph for all netuids...")
58
- self.init_global_redis_metagraph(netuids)
59
-
60
- self.sync_thread = None
61
- self.sync_running = False
62
- self.update_interval = interval
63
- self.run_sync_in_background_thread()
64
-
65
- @abstractmethod
66
- def prepare_synapse(self, *args, **kwargs) -> Any:
67
- """
68
- Prepare the synapse-specific payload.
69
- """
70
- ...
71
-
72
- @abstractmethod
73
- def process_responses(self, responses: List[Union["bt.Synapse", Any]]) -> Any:
74
- """
75
- Process the responses from the network.
76
- """
77
- ...
78
-
79
- def __call__(self, *args, **kwargs):
80
- return self.query_api(*args, **kwargs)
81
-
82
- def fetch_metagraphs(self, netuids=None):
83
- for netuid in netuids:
84
- bt.logging.debug(f"Fetching metagraph for netuid: {netuid}")
85
- yield netuid, self.subtensor.metagraph(netuid)
86
-
87
- def store_metagraph_in_redis(self, metagraph: "bt.metagraph"):
88
- serialized_data = serialize_metagraph(metagraph)
89
-
90
- for attr, value in serialized_data.items():
91
- self.database.hset(f"metagraph:{metagraph.netuid}", attr, json.dumps(value))
92
-
93
- self.database.set(f"metagraph:{metagraph.netuid}:updated", time.time())
94
-
95
- def retrieve_metagraph_from_redis(self, netuid: int):
96
- redis_key = f"metagraph:{netuid}"
97
- data = {
98
- attr.decode(): json.loads(self.database.hget(redis_key, attr))
99
- for attr in self.database.hkeys(redis_key)
100
- }
101
- return deserialize_metagraph(data)
102
-
103
- def get_available_redis_metagraph_netuids(self):
104
- keys = self.database.keys("metagraph:*")
105
- return [int(key.decode().split(":")[1]) for key in keys]
106
-
107
- def retrieve_all_metagraphs_from_redis(self, netuids: Optional[List[int]] = None):
108
- if netuids is None:
109
- netuids = self.get_available_redis_metagraph_netuids()
110
- return {
111
- netuid: self.retrieve_metagraph_from_redis(netuid) for netuid in netuids
112
- }
113
-
114
- def init_redis_global_metagraph(self, netuids=None):
115
- metagraphs = self.fetch_metagraphs(netuids)
116
- for _, metagraph in metagraphs:
117
- self.store_metagraph_in_redis(metagraph)
118
-
119
- def update_metagraphs(self):
120
- metagraphs = self.retrieve_all_metagraphs_from_redis()
121
- for netuid, metagraph in metagraphs.items():
122
- bt.logging.debug(
123
- f"syncing {metagraph.netuid} | {self.subtensor.network}..."
124
- )
125
- if self.database.get(f"metagraph:{metagraph.netuid}:updated") is not None:
126
- last_update = float(
127
- self.database.get(f"metagraph:{metagraph.netuid}:updated")
128
- )
129
- if last_update + self.update_interval > time.time():
130
- bt.logging.debug(f"Skipping sync for {metagraph.netuid}...")
131
- continue
132
- if self.subtensor.network == metagraph.network:
133
- metagraph.sync(subtensor=self.subtensor, lite=True)
134
- else:
135
- metagraph = self.subtensor.metagraph(netuid)
136
- bt.logging.debug(f"storing {metagraph.netuid} in redis...")
137
- self.store_metagraph_in_redis(metagraph)
138
-
139
- def periodic_sync_metagraphs(self):
140
- while self.sync_thread is not None and self.sync_running:
141
- bt.logging.trace(f"Sleeping sync for {interval} seconds...")
142
- time.sleep(self.update_interval)
143
- self.update_metagraphs()
144
-
145
- def run_sync_in_background_thread(self):
146
- """
147
- Starts the API's operations in a separate background thread.
148
- This is useful for non-blocking operations.
149
- """
150
- bt.logging.debug("Starting API background service in separate thread.")
151
- self.sync_thread = threading.Thread(
152
- target=periodic_sync_metagraphs, daemon=True
153
- )
154
- self.sync_thread.start()
155
- bt.logging.debug("Started")
156
-
157
- def stop_sync_thread(self):
158
- """
159
- Stops the API's operations that are running in the background thread.
160
- """
161
- bt.logging.debug("Stopping API in background thread.")
162
- self.sync_thread.join(5)
163
- self.sync_running = False
164
- self.sync_thread = None
165
- bt.logging.debug("Stopped")
166
-
167
- async def ping_uids(self, uids, netuid, timeout=3):
168
- """
169
- Pings a list of UIDs to check their availability on the Bittensor network.
170
-
171
- Args:
172
- uids (list): A list of UIDs (unique identifiers) to ping.
173
- netuid (int): The unique identifier of the subnet to ping.
174
- timeout (int, optional): The timeout in seconds for each ping. Defaults to 3.
175
-
176
- Returns:
177
- tuple: A tuple containing two lists:
178
- - The first list contains UIDs that were successfully pinged.
179
- - The second list contains UIDs that failed to respond.
180
- """
181
- # Fetch from redis
182
- metagraph = retrieve_metagraph_from_redis(netuid)
183
-
184
- axons = [metagraph.axons[uid] for uid in uids]
185
- try:
186
- responses = await self.dendrite(
187
- axons,
188
- bt.Synapse(),
189
- deserialize=False,
190
- timeout=timeout,
191
- )
192
- successful_uids = [
193
- uid
194
- for uid, response in zip(uids, responses)
195
- if response.dendrite.status_code == 200
196
- ]
197
- failed_uids = [
198
- uid
199
- for uid, response in zip(uids, responses)
200
- if response.dendrite.status_code != 200
201
- ]
202
- except Exception as e:
203
- bt.logging.error(f"Dendrite ping failed: {e}")
204
- successful_uids = []
205
- failed_uids = uids
206
- bt.logging.debug("ping() successful uids:", successful_uids)
207
- bt.logging.debug("ping() failed uids :", failed_uids)
208
- return successful_uids, failed_uids
209
-
210
- async def get_query_api_nodes(self, netuid, n=0.1, timeout=3):
211
- """
212
- Fetches the available API nodes to query for the particular subnet.
213
-
214
- Args:
215
- dendrite (bittensor.dendrite): The dendrite instance to use for querying.
216
- metagraph (bittensor.metagraph): The metagraph instance containing network information.
217
- n (float, optional): The fraction of top nodes to consider based on stake. Defaults to 0.1.
218
- timeout (int, optional): The timeout in seconds for pinging nodes. Defaults to 3.
219
-
220
- Returns:
221
- list: A list of UIDs representing the available API nodes.
222
- """
223
- metagraph = retrieve_metagraph_from_redis(netuid)
224
-
225
- bt.logging.debug(f"Fetching available API nodes for subnet {metagraph.netuid}")
226
- vtrust_uids = [
227
- uid.item() for uid in metagraph.uids if metagraph.validator_trust[uid] > 0
228
- ]
229
- top_uids = torch.where(metagraph.S > torch.quantile(metagraph.S, 1 - n))
230
- top_uids = top_uids[0].tolist()
231
- init_query_uids = set(top_uids).intersection(set(vtrust_uids))
232
- query_uids, _ = await self.ping_uids(init_query_uids, netuid, timeout=timeout)
233
- bt.logging.debug(
234
- f"Available API node UIDs for subnet {metagraph.netuid}: {query_uids}"
235
- )
236
- if len(query_uids) > 3:
237
- query_uids = random.sample(query_uids, 3)
238
- return query_uids
239
-
240
- async def get_query_api_axons(self, netuid, n=0.1, timeout=3, uid=None):
241
- """
242
- Retrieves the axons of query API nodes based on their availability and stake.
243
-
244
- Args:
245
- netuid (int): The unique identifier of the subnet to query.
246
- n (float, optional): The fraction of top nodes to consider based on stake. Defaults to 0.1.
247
- timeout (int, optional): The timeout in seconds for pinging nodes. Defaults to 3.
248
- uid (int, optional): The specific UID of the API node to query. Defaults to None.
249
-
250
- Returns:
251
- list: A list of axon objects for the available API nodes.
252
- """
253
- metagraph = retrieve_metagraph_from_redis(netuid)
254
-
255
- if uid is not None:
256
- query_uids = [uid]
257
- else:
258
- query_uids = await self.get_query_api_nodes(netuid, n=n, timeout=timeout)
259
- return [metagraph.axons[uid] for uid in query_uids]
260
-
261
- async def query_api(
262
- self,
263
- netuid: int,
264
- deserialize: bool = False,
265
- timeout: int = 12,
266
- n: float = 0.1,
267
- uid: int = None,
268
- **kwargs: Any,
269
- ) -> Any:
270
- """
271
- Queries the API nodes of a subnet using the given synapse and bespoke query function.
272
-
273
- Args:
274
- dendrite (bittensor.dendrite): The dendrite instance to use for querying.
275
- deserialize (bool, optional): Whether to deserialize the responses. Defaults to False.
276
- timeout (int, optional): The timeout in seconds for the query. Defaults to 12.
277
- n (float, optional): The fraction of top nodes to consider based on stake. Defaults to 0.1.
278
- uid (int, optional): The specific UID of the API node to query. Defaults to None.
279
- **kwargs: Keyword arguments for the prepare_synapse_fn.
280
-
281
- Returns:
282
- Any: The result of the process_responses_fn.
283
- """
284
- synapse = self.prepare_synapse(**kwargs)
285
- axons = await self.get_query_api_axons(
286
- netuid=netuid, n=n, timeout=timeout, uid=uid
287
- )
288
- bt.logging.debug(
289
- f"Quering valdidator axons with synapse {synapse.name} for subnet {netuid}..."
290
- )
291
- responses = await self.dendrite(
292
- axons=axons,
293
- synapse=synapse,
294
- deserialize=deserialize,
295
- timeout=timeout,
296
- )
297
- return self.process_responses(responses)
@@ -1,230 +0,0 @@
1
- import json
2
- import torch
3
- import time
4
- import functools
5
- import threading
6
- from os import getenv
7
- from redis import StrictRedis
8
- from datetime import datetime
9
-
10
- import bittensor as bt
11
- from bittensor import __ss58_format__ as ss58_format, __type_registry__ as type_registry
12
- from bittensor import (
13
- __finney_entrypoint__,
14
- __local_entrypoint__,
15
- __finney_test_entrypoint__,
16
- )
17
-
18
- from typing import List, Dict, Any, Optional, Union
19
-
20
- bt.trace()
21
-
22
- redis_db = None
23
- subtensor = None
24
- sync_thread = None
25
-
26
- METAGRAPH_ATTRIBUTES = [
27
- "n",
28
- "block",
29
- "uids",
30
- "stake",
31
- "total_stake",
32
- "ranks",
33
- "trust",
34
- "consensus",
35
- "validator_trust",
36
- "incentive",
37
- "emission",
38
- "dividends",
39
- "active",
40
- "last_update",
41
- "validator_permit",
42
- "weights",
43
- "bonds",
44
- ]
45
-
46
-
47
- def get_subtensor(network: str = "local"):
48
- return bt.subtensor(network)
49
-
50
-
51
- def get_database() -> StrictRedis:
52
- host = getenv("REDIS_HOST") or "localhost"
53
- port = getenv("REDIS_PORT") or 6379
54
- db = getenv("REDIS_DB") or 10
55
- return StrictRedis(host=host, port=port, db=db) if redis_db == None else redis_db
56
-
57
-
58
- def startup(network: str = "local"):
59
- global redis_db
60
- global subtensor
61
-
62
- if subtensor is not None:
63
- subtensor.close()
64
-
65
- redis_db = get_database()
66
- subtensor = get_subtensor(network)
67
-
68
-
69
- def store_metagraph_in_redis(metagraph):
70
- db = get_database()
71
- serialized_data = serialize_metagraph(metagraph)
72
-
73
- for attr, value in serialized_data.items():
74
- db.hset(f"metagraph:{metagraph.netuid}", attr, json.dumps(value))
75
-
76
- db.set(f"metagraph:{metagraph.netuid}:updated", time.time())
77
-
78
-
79
- def retrieve_metagraph_from_redis(netuid: int):
80
- db = get_database()
81
- redis_key = f"metagraph:{netuid}"
82
- data = {
83
- attr.decode(): json.loads(db.hget(redis_key, attr))
84
- for attr in db.hkeys(redis_key)
85
- }
86
- return deserialize_metagraph(data)
87
-
88
-
89
- def get_metagraph(netuid: int) -> "bt.metagraph":
90
- key = f"metagraph:{netuid}"
91
- if redis_db.exists(key):
92
- return retrieve_metagraph_from_redis(netuid)
93
- return subtensor.metagraph(netuid)
94
-
95
-
96
- def get_available_redis_metagraphs():
97
- keys = redis_db.keys("metagraph:*")
98
- return [int(key.decode().split(":")[1]) for key in keys]
99
-
100
-
101
- def retrieve_all_metagraphs_from_redis(netuids=None):
102
- if netuids is None:
103
- netuids = get_available_redis_metagraphs()
104
- return {netuid: retrieve_metagraph_from_redis(netuid) for netuid in netuids}
105
-
106
-
107
- def serialize_metagraph(metagraph_obj, dump=False):
108
- serialized_data = {}
109
- for attr in METAGRAPH_ATTRIBUTES:
110
- tensor = getattr(metagraph_obj, attr, None)
111
- if tensor is not None:
112
- serialized_data[attr] = tensor.cpu().numpy().tolist()
113
-
114
- serialized_data["netuid"] = metagraph_obj.netuid
115
- serialized_data["network"] = metagraph_obj.network
116
- serialized_data["version"] = metagraph_obj.version.item()
117
- serialized_data["axons"] = [axon.to_string() for axon in metagraph_obj.axons]
118
- serialized_data["netuid"] = metagraph_obj.netuid
119
-
120
- return json.dumps(serialized_data) if dump else serialized_data
121
-
122
-
123
- def deserialize_metagraph(serialized_str):
124
- if isinstance(serialized_str, str):
125
- data = json.loads(serialized_str)
126
- else:
127
- data = serialized_str
128
- metagraph_obj = bt.metagraph(
129
- netuid=data["netuid"], network=data["network"], lite=False, sync=False
130
- )
131
- metagraph_obj.version = torch.nn.Parameter(
132
- torch.tensor([data["version"]], dtype=torch.int64), requires_grad=False
133
- )
134
-
135
- for attr in METAGRAPH_ATTRIBUTES:
136
- if attr in data:
137
- setattr(
138
- metagraph_obj,
139
- attr,
140
- torch.nn.Parameter(torch.tensor(data[attr]), requires_grad=False),
141
- )
142
-
143
- metagraph_obj.axons = [
144
- bt.chain_data.AxonInfo.from_string(axon_data) for axon_data in data["axons"]
145
- ]
146
-
147
- return metagraph_obj
148
-
149
-
150
- def fetch_metagraphs(netuids=None):
151
- for netuid in netuids:
152
- bt.logging.debug(f"Fetching metagraph for netuid: {netuid}")
153
- yield netuid, subtensor.metagraph(netuid)
154
-
155
-
156
- def init_redis_global_metagraph(netuids=None):
157
- metagraphs = fetch_metagraphs(netuids)
158
- for netuid, metagraph in metagraphs:
159
- store_metagraph_in_redis(metagraph)
160
-
161
-
162
- def update_metagraphs():
163
- metagraphs = retrieve_all_metagraphs_from_redis()
164
- for netuid, metagraph in metagraphs.items():
165
- bt.logging.debug(f"syncing {metagraph.netuid} | {subtensor.network}...")
166
- if redis_db.get(f"metagraph:{metagraph.netuid}:updated") is not None:
167
- last_update = float(redis_db.get(f"metagraph:{metagraph.netuid}:updated"))
168
- if last_update + 60 * 60 * 24 > time.time():
169
- bt.logging.debug(f"Skipping sync for {metagraph.netuid}...")
170
- continue
171
- if subtensor.network == metagraph.network:
172
- metagraph.sync(subtensor=subtensor, lite=True)
173
- else:
174
- metagraph = subtensor.metagraph(netuid)
175
- bt.logging.debug(f"storing {metagraph.netuid} in redis...")
176
- store_metagraph_in_redis(metagraph)
177
-
178
-
179
- def periodic_sync_metagraphs(interval: int = 30):
180
- global sync_thread
181
- while sync_thread is not None:
182
- bt.logging.trace(f"Sleeping sync for {interval} seconds...")
183
- time.sleep(interval)
184
- update_metagraphs()
185
-
186
-
187
- def run_sync_in_background_thread(interval: int = 60 * 60 * 2):
188
- """
189
- Starts the API's operations in a separate background thread.
190
- This is useful for non-blocking operations.
191
- """
192
- global sync_thread
193
- bt.logging.debug("Starting API background service in separate thread.")
194
- wrapped_sync = functools.partial(periodic_sync_metagraphs, interval=interval)
195
- sync_thread = threading.Thread(target=wrapped_sync, daemon=True)
196
- sync_thread.start()
197
- bt.logging.debug("Started")
198
-
199
-
200
- def stop_sync_thread():
201
- """
202
- Stops the API's operations that are running in the background thread.
203
- """
204
- global sync_thread
205
- bt.logging.debug("Stopping API in background thread.")
206
- sync_thread.join(5)
207
- sync_thread = None
208
- bt.logging.debug("Stopped")
209
-
210
-
211
- def start(network: str = "local", netuids: List[int] = None, interval: int = 180):
212
- startup(network)
213
-
214
- stored_netuids = get_available_redis_metagraphs()
215
- if netuids is not None:
216
- if not all([netuid in stored_netuids for netuid in netuids]):
217
- bt.logging.debug(
218
- f"Not all passed netuids in stored metagraphs. Fetching: {netuids}"
219
- )
220
- init_redis_global_metagraph(netuids)
221
- else:
222
- bt.logging.debug(
223
- f"All passed netuids in stored metagraphs... skipping fetch"
224
- )
225
- else:
226
- netuids = subtensor.get_all_subnet_netuids()
227
- bt.logging.info(f"Initializing global metagraph for all netuids...")
228
- init_global_redis_metagraph(netuids)
229
-
230
- run_sync_in_background_thread(interval)