Skip to content

Commit 77d7a41

Browse files
committed
Added flag for current only
1 parent 158acb5 commit 77d7a41

File tree

2 files changed

+139
-29
lines changed

2 files changed

+139
-29
lines changed

bittensor_cli/cli.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5026,6 +5026,11 @@ def subnets_price(
50265026
"--log",
50275027
help="Show the price in log scale.",
50285028
),
5029+
current_only: bool = typer.Option(
5030+
False,
5031+
"--current",
5032+
help="Show only the current data, and no historical data.",
5033+
),
50295034
html_output: bool = Options.html_output,
50305035
quiet: bool = Options.quiet,
50315036
verbose: bool = Options.verbose,
@@ -5050,6 +5055,17 @@ def subnets_price(
50505055
if json_output and html_output:
50515056
print_error("Cannot specify both `--json-output` and `--html`")
50525057
return
5058+
non_archives = ["finney", "latent-lite", "subvortex"]
5059+
if not current_only and self._determine_network(network) in non_archives + [
5060+
Constants.network_map[x] for x in non_archives
5061+
]:
5062+
err_console.print(
5063+
f"[red]Error[/red] Running this command without [{COLORS.G.ARG}]--current[/{COLORS.G.ARG}] requires "
5064+
"use of an archive node. "
5065+
f"Try running again with the [{COLORS.G.ARG}]--network archive[/{COLORS.G.ARG}] flag."
5066+
)
5067+
return False
5068+
50535069
self.verbosity_handler(quiet=quiet, verbose=verbose, json_output=json_output)
50545070
if netuids:
50555071
netuids = parse_to_list(
@@ -5084,6 +5100,7 @@ def subnets_price(
50845100
netuids,
50855101
all_netuids,
50865102
interval_hours,
5103+
current_only,
50875104
html_output,
50885105
log_scale,
50895106
json_output,

bittensor_cli/src/commands/subnets/price.py

Lines changed: 122 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import plotly.graph_objects as go
1111

1212
from bittensor_cli.src import COLOR_PALETTE
13+
from bittensor_cli.src.bittensor.chain_data import DynamicInfo
1314
from bittensor_cli.src.bittensor.utils import (
1415
console,
1516
err_console,
@@ -28,6 +29,7 @@ async def price(
2829
netuids: list[int],
2930
all_netuids: bool = False,
3031
interval_hours: int = 4,
32+
current_only: bool = False,
3133
html_output: bool = False,
3234
log_scale: bool = False,
3335
json_output: bool = False,
@@ -41,45 +43,93 @@ async def price(
4143
blocks_per_hour = int(3600 / 12) # ~300 blocks per hour
4244
total_blocks = blocks_per_hour * interval_hours
4345

44-
with console.status(":chart_increasing: Fetching historical price data..."):
45-
current_block_hash = await subtensor.substrate.get_chain_head()
46-
current_block = await subtensor.substrate.get_block_number(current_block_hash)
46+
if not current_only:
47+
with console.status(":chart_increasing: Fetching historical price data..."):
48+
current_block_hash = await subtensor.substrate.get_chain_head()
49+
current_block = await subtensor.substrate.get_block_number(
50+
current_block_hash
51+
)
4752

48-
step = 300
49-
start_block = max(0, current_block - total_blocks)
50-
block_numbers = list(range(start_block, current_block + 1, step))
53+
step = 300
54+
start_block = max(0, current_block - total_blocks)
55+
block_numbers = list(range(start_block, current_block + 1, step))
5156

52-
# Block hashes
53-
block_hash_cors = [
54-
subtensor.substrate.get_block_hash(bn) for bn in block_numbers
55-
]
56-
block_hashes = await asyncio.gather(*block_hash_cors)
57+
# Block hashes
58+
block_hash_cors = [
59+
subtensor.substrate.get_block_hash(bn) for bn in block_numbers
60+
]
61+
block_hashes = await asyncio.gather(*block_hash_cors)
5762

58-
# We fetch all subnets when there is more than one netuid
59-
if all_netuids or len(netuids) > 1:
60-
subnet_info_cors = [subtensor.all_subnets(bh) for bh in block_hashes]
61-
else:
62-
# If there is only one netuid, we fetch the subnet info for that netuid
63-
netuid = netuids[0]
64-
subnet_info_cors = [subtensor.subnet(netuid, bh) for bh in block_hashes]
65-
all_subnet_infos = await asyncio.gather(*subnet_info_cors)
63+
# We fetch all subnets when there is more than one netuid
64+
if all_netuids or len(netuids) > 1:
65+
subnet_info_cors = [subtensor.all_subnets(bh) for bh in block_hashes]
66+
else:
67+
# If there is only one netuid, we fetch the subnet info for that netuid
68+
netuid = netuids[0]
69+
subnet_info_cors = [subtensor.subnet(netuid, bh) for bh in block_hashes]
70+
all_subnet_infos = await asyncio.gather(*subnet_info_cors)
6671

6772
subnet_data = _process_subnet_data(
6873
block_numbers, all_subnet_infos, netuids, all_netuids
6974
)
75+
if not subnet_data:
76+
err_console.print("[red]No valid price data found for any subnet[/red]")
77+
return
7078

71-
if not subnet_data:
72-
err_console.print("[red]No valid price data found for any subnet[/red]")
73-
return
74-
75-
if html_output:
76-
await _generate_html_output(
77-
subnet_data, block_numbers, interval_hours, log_scale
79+
if html_output:
80+
await _generate_html_output(
81+
subnet_data, block_numbers, interval_hours, log_scale
82+
)
83+
elif json_output:
84+
json_console.print(json.dumps(_generate_json_output(subnet_data)))
85+
else:
86+
_generate_cli_output(subnet_data, block_numbers, interval_hours, log_scale)
87+
else:
88+
with console.status("Fetching current price data..."):
89+
if all_netuids or len(netuids) > 1:
90+
all_subnet_info = await subtensor.all_subnets()
91+
else:
92+
all_subnet_info = [await subtensor.subnet(netuid=netuids[0])]
93+
subnet_data = _process_current_subnet_data(
94+
all_subnet_info, netuids, all_netuids
7895
)
79-
elif json_output:
80-
json_console.print(json.dumps(_generate_json_output(subnet_data)))
96+
_generate_cli_output_current(subnet_data)
97+
98+
99+
def _process_current_subnet_data(subnet_infos: list[DynamicInfo], netuids, all_netuids):
100+
subnet_data = {}
101+
if all_netuids or len(netuids) > 1:
102+
# Most recent data for statistics
103+
for subnet_info in subnet_infos:
104+
stats = {
105+
"current_price": subnet_info.price,
106+
"supply": subnet_info.alpha_in.tao + subnet_info.alpha_out.tao,
107+
"market_cap": subnet_info.price.tao
108+
* (subnet_info.alpha_in.tao + subnet_info.alpha_out.tao),
109+
"emission": subnet_info.emission.tao,
110+
"stake": subnet_info.alpha_out.tao,
111+
"symbol": subnet_info.symbol,
112+
"name": get_subnet_name(subnet_info),
113+
}
114+
subnet_data[subnet_info.netuid] = {
115+
"stats": stats,
116+
}
81117
else:
82-
_generate_cli_output(subnet_data, block_numbers, interval_hours, log_scale)
118+
subnet_info = subnet_infos[0]
119+
stats = {
120+
"current_price": subnet_info.price,
121+
"supply": subnet_info.alpha_in.tao + subnet_info.alpha_out.tao,
122+
"market_cap": subnet_info.price.tao
123+
* (subnet_info.alpha_in.tao + subnet_info.alpha_out.tao),
124+
"emission": subnet_info.emission.tao,
125+
"stake": subnet_info.alpha_out.tao,
126+
"symbol": subnet_info.symbol,
127+
"name": get_subnet_name(subnet_info),
128+
}
129+
subnet_data[subnet_info.netuid] = {
130+
"stats": stats,
131+
}
132+
return subnet_data
83133

84134

85135
def _process_subnet_data(block_numbers, all_subnet_infos, netuids, all_netuids):
@@ -626,3 +676,46 @@ def color_label(text):
626676
)
627677

628678
console.print(stats_text)
679+
680+
681+
def _generate_cli_output_current(subnet_data):
682+
for netuid, data in subnet_data.items():
683+
stats = data["stats"]
684+
685+
if netuid != 0:
686+
console.print(
687+
f"\n[{COLOR_PALETTE.G.SYM}]Subnet {netuid} - {stats['symbol']} "
688+
f"[cyan]{stats['name']}[/cyan][/{COLOR_PALETTE.G.SYM}]\n"
689+
f"Current: [blue]{stats['current_price'].tao:.6f}{stats['symbol']}[/blue]\n"
690+
)
691+
else:
692+
console.print(
693+
f"\n[{COLOR_PALETTE.G.SYM}]Subnet {netuid} - {stats['symbol']} "
694+
f"[cyan]{stats['name']}[/cyan][/{COLOR_PALETTE.G.SYM}]\n"
695+
f"Current: [blue]{stats['symbol']} {stats['current_price'].tao:.6f}[/blue]\n"
696+
)
697+
698+
if netuid != 0:
699+
stats_text = (
700+
"\nLatest stats:\n"
701+
f"Supply: [{COLOR_PALETTE.P.ALPHA_IN}]"
702+
f"{stats['supply']:,.2f} {stats['symbol']}[/{COLOR_PALETTE.P.ALPHA_IN}]\n"
703+
f"Market Cap: [steel_blue3]{stats['market_cap']:,.2f} {stats['symbol']} / 21M[/steel_blue3]\n"
704+
f"Emission: [{COLOR_PALETTE.P.EMISSION}]"
705+
f"{stats['emission']:,.2f} {stats['symbol']}[/{COLOR_PALETTE.P.EMISSION}]\n"
706+
f"Stake: [{COLOR_PALETTE.S.TAO}]"
707+
f"{stats['stake']:,.2f} {stats['symbol']}[/{COLOR_PALETTE.S.TAO}]"
708+
)
709+
else:
710+
stats_text = (
711+
"\nLatest stats:\n"
712+
f"Supply: [{COLOR_PALETTE.P.ALPHA_IN}]"
713+
f"{stats['symbol']} {stats['supply']:,.2f}[/{COLOR_PALETTE.P.ALPHA_IN}]\n"
714+
f"Market Cap: [steel_blue3]{stats['symbol']} {stats['market_cap']:,.2f} / 21M[/steel_blue3]\n"
715+
f"Emission: [{COLOR_PALETTE.P.EMISSION}]"
716+
f"{stats['symbol']} {stats['emission']:,.2f}[/{COLOR_PALETTE.P.EMISSION}]\n"
717+
f"Stake: [{COLOR_PALETTE.S.TAO}]"
718+
f"{stats['symbol']} {stats['stake']:,.2f}[/{COLOR_PALETTE.S.TAO}]"
719+
)
720+
721+
console.print(stats_text)

0 commit comments

Comments
 (0)