Skip to content

Commit 9566d0e

Browse files
committed
Also removed PyWry from price.py
1 parent 6a20862 commit 9566d0e

File tree

6 files changed

+271
-340
lines changed

6 files changed

+271
-340
lines changed

bittensor_cli/cli.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@
6767
prompt_for_identity,
6868
validate_uri,
6969
prompt_for_subnet_identity,
70-
print_linux_dependency_message,
71-
is_linux,
7270
validate_rate_tolerance,
7371
)
7472

@@ -4875,9 +4873,6 @@ def subnets_price(
48754873
if all_netuids and not json_output:
48764874
html_output = True
48774875

4878-
if html_output and is_linux():
4879-
print_linux_dependency_message()
4880-
48814876
return self._run_command(
48824877
price.price(
48834878
self.initialize_chain(network),
@@ -5655,7 +5650,7 @@ def view_dashboard(
56555650
help="Coldkey SS58 address to view dashboard for",
56565651
),
56575652
use_wry: bool = typer.Option(
5658-
False, "--use-wry", help="Use PyWry instead of browser window"
5653+
False, "--use-wry", "--html", help="Display output in browser window."
56595654
),
56605655
save_file: bool = typer.Option(
56615656
False, "--save-file", "--save", help="Save the dashboard HTML file"
@@ -5668,12 +5663,10 @@ def view_dashboard(
56685663
Display html dashboard with subnets list, stake, and neuron information.
56695664
"""
56705665
self.verbosity_handler(quiet, verbose)
5671-
if use_wry and is_linux():
5672-
print_linux_dependency_message()
56735666

56745667
if use_wry and save_file:
5675-
print_error("Cannot save file when using PyWry.")
5676-
raise typer.Exit()
5668+
print_error("Cannot save file when using browser output.")
5669+
return
56775670

56785671
if save_file:
56795672
if not dashboard_path:
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>{{ title }}</title>
5+
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
6+
<style>
7+
body {
8+
background-color: #000;
9+
color: #fff;
10+
font-family: Arial, sans-serif;
11+
margin: 0;
12+
padding: 20px;
13+
}
14+
.container {
15+
display: flex;
16+
flex-direction: column;
17+
gap: 60px;
18+
}
19+
#multi-subnet-chart {
20+
width: 90vw;
21+
height: 70vh;
22+
margin-bottom: 40px;
23+
}
24+
.subnet-buttons {
25+
display: grid;
26+
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
27+
gap: 8px;
28+
max-height: 120px;
29+
overflow-y: auto;
30+
padding-right: 10px;
31+
margin-top: 50px;
32+
border-top: 1px solid rgba(255,255,255,0.1);
33+
padding-top: 50px;
34+
position: relative;
35+
bottom: 0;
36+
}
37+
.subnet-buttons::-webkit-scrollbar {
38+
width: 8px;
39+
}
40+
.subnet-buttons::-webkit-scrollbar-track {
41+
background: rgba(50,50,50,0.3);
42+
border-radius: 4px;
43+
}
44+
.subnet-buttons::-webkit-scrollbar-thumb {
45+
background: rgba(100,100,100,0.8);
46+
border-radius: 4px;
47+
}
48+
.subnet-button {
49+
background-color: rgba(50,50,50,0.8);
50+
border: 1px solid rgba(70,70,70,0.9);
51+
color: white;
52+
padding: 8px 16px;
53+
cursor: pointer;
54+
border-radius: 4px;
55+
font-size: 14px;
56+
transition: background-color 0.2s;
57+
white-space: nowrap;
58+
overflow: hidden;
59+
text-overflow: ellipsis;
60+
}
61+
.subnet-button:hover {
62+
background-color: rgba(70,70,70,0.9);
63+
}
64+
.subnet-button.active {
65+
background-color: rgba(100,100,100,0.9);
66+
border-color: rgba(120,120,120,1);
67+
}
68+
</style>
69+
</head>
70+
<body>
71+
<div class="container">
72+
<div id="multi-subnet-chart"></div>
73+
<div class="subnet-buttons">
74+
<button class="subnet-button active" onclick="setAll()">All</button>
75+
{% for netuid in sorted_subnet_keys %}
76+
<button class="subnet-button" onclick="setSubnet({{ netuid }})">S{{ netuid }}</button>
77+
{% endfor %}
78+
</div>
79+
</div>
80+
<script>
81+
const figData = {{ fig_json|safe }};
82+
const allVisibility = {{ all_visibility|tojson|safe }};
83+
const allAnnotations = {{ all_annotations|tojson|safe }};
84+
85+
const subnetModes = {{ subnet_modes|tojson|safe }};
86+
87+
Plotly.newPlot('multi-subnet-chart', figData.data, figData.layout);
88+
89+
function clearActiveButtons() {
90+
document.querySelectorAll('.subnet-button').forEach(btn => btn.classList.remove('active'));
91+
}
92+
93+
function setAll() {
94+
clearActiveButtons();
95+
event.currentTarget.classList.add('active');
96+
Plotly.update('multi-subnet-chart',
97+
{visible: allVisibility},
98+
{annotations: allAnnotations}
99+
);
100+
}
101+
102+
function setSubnet(netuid) {
103+
clearActiveButtons();
104+
event.currentTarget.classList.add('active');
105+
const mode = subnetModes[netuid];
106+
Plotly.update('multi-subnet-chart',
107+
{visible: mode.visible},
108+
{annotations: mode.annotations}
109+
);
110+
}
111+
</script>
112+
</body>
113+
</html>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>{{ title }}</title>
6+
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
7+
<style>
8+
body {
9+
background-color: #000;
10+
color: #fff;
11+
font-family: Arial, sans-serif;
12+
margin: 0;
13+
padding: 20px;
14+
}
15+
.header-container {
16+
display: flex;
17+
align-items: flex-start;
18+
justify-content: space-between;
19+
margin-bottom: 20px;
20+
}
21+
.price-info {
22+
max-width: 60%;
23+
}
24+
.main-price {
25+
font-size: 36px;
26+
font-weight: 600;
27+
margin-bottom: 5px;
28+
}
29+
.price-change {
30+
font-size: 18px;
31+
margin-left: 8px;
32+
font-weight: 500;
33+
}
34+
.text-green { color: #00FF00; }
35+
.text-red { color: #FF5555; }
36+
.text-blue { color: #87CEEB; }
37+
.text-steel { color: #4682B4; }
38+
.text-purple{ color: #DDA0DD; }
39+
.text-gold { color: #FFD700; }
40+
41+
.sub-stats-row {
42+
display: flex;
43+
flex-wrap: wrap;
44+
margin-top: 10px;
45+
}
46+
.stat-item {
47+
margin-right: 20px;
48+
margin-bottom: 6px;
49+
font-size: 14px;
50+
}
51+
.side-stats {
52+
min-width: 220px;
53+
display: flex;
54+
flex-direction: column;
55+
align-items: flex-start;
56+
}
57+
.side-stats div {
58+
margin-bottom: 6px;
59+
font-size: 14px;
60+
}
61+
#chart-container {
62+
margin-top: 20px;
63+
width: 100%;
64+
height: 600px;
65+
}
66+
</style>
67+
</head>
68+
<body>
69+
<div class="header-container">
70+
<div class="price-info">
71+
<div class="main-price">
72+
{{ "%.6f"|format(stats.current_price) }} {{ stats.symbol }}
73+
<span class="price-change {{ "text-green" if stats.change_pct > 0 else "text-red" }}">
74+
{{ "▲" if stats.change_pct > 0 else "▼" }} {{ "%.2f"|format(change_pct) }}%
75+
</span>
76+
</div>
77+
<div class="sub-stats-row">
78+
<div class="stat-item">
79+
{{ interval_hours }}h High: <span class="text-green">{{ "%.6f"|format(stats.high) }} {{ stats.symbol }}</span>
80+
</div>
81+
<div class="stat-item">
82+
{{ interval_hours }}h Low: <span class="text-red">{{ "%.6f"|format(stats.low) }} {{ stats.symbol }}</span>
83+
</div>
84+
</div>
85+
</div>
86+
<div class="side-stats">
87+
<div>Supply: <span class="text-blue">{{ "%.2f"|format(stats.supply) }} {{ stats.symbol }}</span></div>
88+
<div>Market Cap: <span class="text-steel">{{ "%.2f"|format(stats.market_cap) }} τ</span></div>
89+
<div>Emission: <span class="text-purple">{{ "%.2f"|format(stats.emission) }} {{ stats.symbol }}</span></div>
90+
<div>Stake: <span class="text-gold">{{ "%.2f"|format(stats.stake) }} {{ stats.symbol }}</span></div>
91+
</div>
92+
</div>
93+
<div id="chart-container"></div>
94+
<script>
95+
var figData = {{ fig_json|safe }};
96+
Plotly.newPlot('chart-container', figData.data, figData.layout);
97+
</script>
98+
</body>
99+
</html>

bittensor_cli/src/bittensor/utils.py

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from bittensor_wallet.utils import SS58_FORMAT
1616
from bittensor_wallet.errors import KeyFileError, PasswordError
1717
from bittensor_wallet import utils
18-
from jinja2 import Template
18+
from jinja2 import Template, Environment, PackageLoader, select_autoescape
1919
from markupsafe import Markup
2020
import numpy as np
2121
from numpy.typing import NDArray
@@ -38,6 +38,11 @@
3838
err_console = Console(stderr=True)
3939
verbose_console = Console(quiet=True)
4040

41+
jinja_env = Environment(
42+
loader=PackageLoader("bittensor_cli", "src/bittensor/templates"),
43+
autoescape=select_autoescape(),
44+
)
45+
4146
UnlockStatus = namedtuple("UnlockStatus", ["success", "message"])
4247

4348

@@ -1295,37 +1300,6 @@ def get_subnet_name(subnet_info, max_length: int = 20) -> str:
12951300
return name
12961301

12971302

1298-
def print_linux_dependency_message():
1299-
"""Prints the WebKit dependency message for Linux systems."""
1300-
console.print("[red]This command requires WebKit dependencies on Linux.[/red]")
1301-
console.print(
1302-
"\nPlease make sure these packages are installed on your system for PyWry to work:"
1303-
)
1304-
console.print("\nArch Linux / Manjaro:")
1305-
console.print("[green]sudo pacman -S webkit2gtk[/green]")
1306-
console.print("\nDebian / Ubuntu:")
1307-
console.print("[green]sudo apt install libwebkit2gtk-4.0-dev[/green]")
1308-
console.print("\nNote for Ubuntu 24.04+ & Debian 13+:")
1309-
console.print("You may need these additional steps to install libwebkit2gtk:")
1310-
console.print(
1311-
"\tCreate a new source file with: [green]sudo vim /etc/apt/sources.list.d/jammy-temp.list[/green]"
1312-
)
1313-
console.print(
1314-
"\tAdd this into the file and save: [green]deb http://archive.ubuntu.com/ubuntu jammy main universe[/green]"
1315-
)
1316-
console.print(
1317-
"\tUpdate the repository and install the webkit dependency: [green]sudo apt update && sudo apt install "
1318-
"libwebkit2gtk-4.0-dev[/green]"
1319-
)
1320-
console.print("\nFedora / CentOS / AlmaLinux:")
1321-
console.print("[green]sudo dnf install gtk3-devel webkit2gtk3-devel[/green]\n\n")
1322-
1323-
1324-
def is_linux():
1325-
"""Returns True if the operating system is Linux."""
1326-
return platform.system().lower() == "linux"
1327-
1328-
13291303
def validate_rate_tolerance(value: Optional[float]) -> Optional[float]:
13301304
"""Validates rate tolerance input"""
13311305
if value is not None:

0 commit comments

Comments
 (0)