import atexit import datetime from flask import Flask, request, jsonify from apscheduler.schedulers.background import BackgroundScheduler import utils app = Flask(__name__) # Global variables (saves time on loading data) state_vars = None reload_timestamp = datetime.datetime.now().strftime('%D %T') def load_data(test=False): """ Reload the state variables """ global state_vars, reload_timestamp if test: state_vars = utils.test_load_state_vars() else: state_vars = utils.load_state_vars() reload_timestamp = datetime.datetime.now().strftime('%D %T') print(f'Reloaded data at {reload_timestamp}') def start_scheduler(): scheduler = BackgroundScheduler() scheduler.add_job(func=load_data, trigger="interval", seconds=60*30) scheduler.start() # Shut down the scheduler when exiting the app atexit.register(lambda: scheduler.shutdown()) @app.route('/', methods=['GET']) def home(): return "Welcome to the Bittensor Pretraining Leaderboard API!" @app.route('/updated', methods=['GET']) def updated(): return reload_timestamp @app.route('/benchmark', methods=['GET']) def benchmark(): """ Get the benchmarks and the timestamp Returns: - benchmarks: List of dicts (from pandas DataFrame) - benchmark_timestamp: String """ benchmarks = state_vars.get("benchmarks", None) benchmark_timestamp = state_vars.get("benchmark_timestamp", None) return jsonify( { "benchmarks": benchmarks.to_dict(orient='records'), "benchmark_timestamp": benchmark_timestamp.strftime('%Y-%m-%d %H:%M:%S') } ) @app.route('/metagraph', methods=['GET']) def metagraph(): """ Get the metagraph data Returns: - metagraph_data: List of dicts (from pandas DataFrame) """ metagraph = state_vars["metagraph"] return jsonify( utils.make_metagraph_dataframe(metagraph).to_dict(orient='records') ) @app.route('/leaderboard', methods=['GET']) def leaderboard(): """ Get the leaderboard data Returns: - leaderboard_data: List of dicts (from pandas DataFrame) """ model_data = state_vars["model_data"] scores = state_vars["scores"] show_stale = request.args.get('show_stale') return jsonify( utils.leaderboard_data(model_data, scores, show_stale=show_stale) ) @app.route('/loss', methods=['GET']) def loss(): """ Get the losses over time Returns: - losses_over_time: List of dicts (from pandas DataFrame) """ vali_runs = state_vars["vali_runs"] return jsonify( utils.get_losses_over_time(vali_runs).to_dict(orient='records') ) @app.route('/validator', methods=['GET']) def validator(): """ Get the validator data Returns: - validator_data: List of dicts (from pandas DataFrame) """ model_data = state_vars["model_data"] validator_df = state_vars["validator_df"] validator_df = utils.make_validator_dataframe(validator_df, model_data) json_data = [ row.dropna().to_dict() for _, row in validator_df.iterrows() ] return jsonify(json_data) @app.route('/model-data', methods=['GET']) def model_data(): """ Get the model data Returns: - model_data: List of dicts (from list of ModelData) - winner_data: dict containing top earning miners """ model_data = state_vars["model_data"] winner_data = { f"{c.namespace}/{c.name} ({c.commit[0:8]}) · (τ{round(c.emission, 2):,})": c.incentive for c in model_data if c.incentive } return jsonify({ 'model_data': [md.to_dict() for md in model_data], 'winner_data': winner_data }) if __name__ == '__main__': load_data() start_scheduler() app.run(host='0.0.0.0', port=5000, debug=True)