alex n
first commit
e5457b7
raw
history blame
3.95 kB
import gradio as gr
import bittensor as bt
import requests
import pandas as pd
from apscheduler.schedulers.background import BackgroundScheduler
# Custom CSS for better appearance
custom_css = """
.gradio-container {
max-width: 1200px !important;
margin: auto;
}
.title {
text-align: center;
margin-bottom: 1rem;
}
.status-active { color: green; }
.status-error { color: red; }
"""
# Initialize bittensor objects
subtensor = bt.subtensor()
metagraph = bt.metagraph(netuid=36)
def get_validator_data() -> pd.DataFrame:
validator_ids = [i for i in range(len(metagraph.validator_permit)) if metagraph.validator_permit[i]]
results = []
for uid in validator_ids:
try:
ip = metagraph.axons[uid].ip_str().split('/')[-1]
response = requests.get(f'http://{ip}/step', timeout=5)
response.raise_for_status()
validator_info = {
'UID': uid,
'IP': ip,
'Bits': response.json().get('bits', 0),
'Status': 'βœ… Active'
}
except Exception as e:
validator_info = {
'UID': uid,
'IP': metagraph.axons[uid].ip_str().split('/')[-1],
'Bits': 0,
'Status': f'❌ Error: {str(e)[:50]}...' if len(str(e)) > 50 else str(e)
}
results.append(validator_info)
df = pd.DataFrame(results)
return df.sort_values('Bits', ascending=False)
# Create the Gradio interface
demo = gr.Blocks(css=custom_css)
with demo:
gr.HTML(
"""
<div class="title">
<h1>πŸ† Validator Bits Leaderboard</h1>
<p>Real-time tracking of validator performance and bits</p>
</div>
"""
)
with gr.Tabs() as tabs:
with gr.Tab("πŸ“Š Leaderboard"):
leaderboard = gr.DataFrame(
headers=['UID', 'IP', 'Bits', 'Status'],
datatype=['number', 'str', 'number', 'str'],
interactive=False
)
with gr.Row():
refresh_button = gr.Button("πŸ”„ Refresh Data", variant="primary")
auto_refresh = gr.Checkbox(
label="Auto-refresh (5 min)",
value=True,
interactive=True
)
status_message = gr.Markdown("Last updated: Never")
with gr.Tab("ℹ️ About"):
gr.Markdown(
"""
## About this Leaderboard
This dashboard shows real-time information about validators on the network:
- **UID**: Unique identifier of the validator
- **IP**: Validator's IP address
- **Bits**: Current bits count
- **Status**: Active/Error status of the validator
Data is automatically refreshed every 5 minutes, or you can manually refresh using the button.
"""
)
def update_leaderboard():
df = get_validator_data()
timestamp = pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S UTC")
return df, f"Last updated: {timestamp}"
refresh_button.click(
fn=update_leaderboard,
outputs=[leaderboard, status_message]
)
# Auto-refresh logic
def setup_auto_refresh():
if demo.scheduler:
demo.scheduler.shutdown()
demo.scheduler = BackgroundScheduler()
demo.scheduler.add_job(
lambda: demo.queue(update_leaderboard),
'interval',
minutes=5
)
demo.scheduler.start()
# Initial data load
demo.load(
fn=update_leaderboard,
outputs=[leaderboard, status_message]
)
setup_auto_refresh()
# Launch the interface
demo.queue(default_concurrency_limit=5).launch()