From 9313a6c7da263c17286e0175d8812c02f1f91bdf Mon Sep 17 00:00:00 2001 From: Neal <33704976+nealmick@users.noreply.github.com> Date: Sat, 21 Dec 2024 17:19:34 -0500 Subject: [PATCH] flask upgrades (#452) Add player and team data to flask ui --- Flask/app.py | 192 +++++++++++++++++++++- Flask/templates/index.html | 23 ++- Flask/templates/player_modal.html | 247 ++++++++++++++++++++++++++++ Flask/templates/team_modal.html | 259 ++++++++++++++++++++++++++++++ src/Predict/NN_Runner.py | 19 ++- 5 files changed, 724 insertions(+), 16 deletions(-) create mode 100644 Flask/templates/player_modal.html create mode 100644 Flask/templates/team_modal.html diff --git a/Flask/app.py b/Flask/app.py index 99518a467..4744d52e9 100644 --- a/Flask/app.py +++ b/Flask/app.py @@ -1,10 +1,8 @@ from datetime import date import json -from flask import Flask, render_template +from flask import Flask, render_template,jsonify from functools import lru_cache -import subprocess -import re -import time +import subprocess, requests, re, time @lru_cache() @@ -68,4 +66,188 @@ def index(): draftkings = fetch_draftkings(ttl_hash=get_ttl_hash()) betmgm = fetch_betmgm(ttl_hash=get_ttl_hash()) - return render_template('index.html', today=date.today(), data={"fanduel": fanduel, "draftkings": draftkings, "betmgm": betmgm}) \ No newline at end of file + return render_template('index.html', today=date.today(), data={"fanduel": fanduel, "draftkings": draftkings, "betmgm": betmgm}) + + + + +def get_player_data(team_abv): + """Fetch player data for a given team abbreviation""" + url = "https://tank01-fantasy-stats.p.rapidapi.com/getNBATeamRoster" + headers = { + "x-rapidapi-key": "a0f0cd0b5cmshfef96ed37a9cda6p1f67bajsnfcdd16f37df8", + "x-rapidapi-host": "tank01-fantasy-stats.p.rapidapi.com" + } + querystring = {"teamAbv": team_abv} + + try: + response = requests.get(url, headers=headers, params=querystring) + data = response.json() + + if data.get('statusCode') == 200: + formatted_players = [] + roster = data.get('body', {}).get('roster', []) + + for player in roster: + # Format injury status + injury_status = "Healthy" + if player.get('injury'): + injury_info = player['injury'] + if injury_info.get('designation'): + injury_status = injury_info['designation'] + if injury_info.get('description'): + injury_status += f" - {injury_info['description']}" + + formatted_player = { + 'name': player.get('longName'), + 'shortName': player.get('shortName'), + 'headshot': player.get('nbaComHeadshot'), + 'injury': injury_status, + 'position': player.get('pos'), + 'height': player.get('height'), + 'weight': player.get('weight'), + 'college': player.get('college'), + 'experience': player.get('exp'), + 'jerseyNum': player.get('jerseyNum'), + 'playerId': player.get('playerID'), + 'birthDate': player.get('bDay') + } + formatted_players.append(formatted_player) + + return { + 'success': True, + 'players': formatted_players + } + + return { + 'success': False, + 'error': 'Failed to fetch team data' + } + + except Exception as e: + print(f"Error in get_player_data: {str(e)}") + return { + 'success': False, + 'error': str(e) + } + + +@app.route("/team-data/") +def team_data(team_name): + # Convert full team name to abbreviation using the existing dictionary + team_abv = team_abbreviations.get(team_name) + + if not team_abv: + return jsonify({ + 'success': False, + 'error': f'Team abbreviation not found for {team_name}' + }) + + # Fetch and return the player data + result = get_player_data(team_abv) + return jsonify(result) + + + +@app.route("/player-stats/") +def player_stats(player_id): + headers = { + "x-rapidapi-key": "a0f0cd0b5cmshfef96ed37a9cda6p1f67bajsnfcdd16f37df8", + "x-rapidapi-host": "tank01-fantasy-stats.p.rapidapi.com" + } + + # First get player info + info_url = "https://tank01-fantasy-stats.p.rapidapi.com/getNBAPlayerInfo" + info_querystring = {"playerID": player_id} + + # Then get game stats + games_url = "https://tank01-fantasy-stats.p.rapidapi.com/getNBAGamesForPlayer" + games_querystring = { + "playerID": player_id, + "season": "2024", + } + + try: + # Get both responses + info_response = requests.get(info_url, headers=headers, params=info_querystring) + games_response = requests.get(games_url, headers=headers, params=games_querystring) + + info_data = info_response.json() + games_data = games_response.json() + + if info_data.get('statusCode') == 200 and games_data.get('statusCode') == 200: + # Process games data + games = list(games_data['body'].values()) + games.sort(key=lambda x: x['gameID'], reverse=True) + recent_games = games[:10] + + # Get player info + player_info = info_data['body'] + + # Format injury info + injury_status = "Healthy" + if player_info.get('injury'): + injury_info = player_info['injury'] + injury_status = injury_info + + # Combine and return all data + return jsonify({ + 'success': True, + 'games': recent_games, + 'player': { + 'name': player_info.get('longName'), + 'position': player_info.get('pos'), + 'number': player_info.get('jerseyNum'), + 'height': player_info.get('height'), + 'weight': player_info.get('weight'), + 'team': player_info.get('team'), + 'college': player_info.get('college'), + 'experience': player_info.get('exp'), + 'headshot': player_info.get('nbaComHeadshot'), + 'injury': injury_status + } + }) + + return jsonify({ + 'success': False, + 'error': 'Failed to fetch player data' + }) + except Exception as e: + return jsonify({ + 'success': False, + 'error': str(e) + }) + + +team_abbreviations = { + 'Orlando Magic': 'ORL', + 'Minnesota Timberwolves': 'MIN', + 'Miami Heat': 'MIA', + 'Boston Celtics': 'BOS', + 'LA Clippers': 'LAC', + 'Denver Nuggets': 'DEN', + 'Detroit Pistons': 'DET', + 'Atlanta Hawks': 'ATL', + 'Cleveland Cavaliers': 'CLE', + 'Toronto Raptors': 'TOR', + 'Washington Wizards': 'WAS', + 'Phoenix Suns': 'PHO', + 'San Antonio Spurs': 'SA', + 'Chicago Bulls': 'CHI', + 'Charlotte Hornets': 'CHA', + 'Philadelphia 76ers': 'PHI', + 'New Orleans Pelicans': 'NO', + 'Sacramento Kings': 'SAC', + 'Dallas Mavericks': 'DAL', + 'Houston Rockets': 'HOU', + 'Brooklyn Nets': 'BKN', + 'New York Knicks': 'NY', + 'Utah Jazz': 'UTA', + 'Oklahoma City Thunder': 'OKC', + 'Portland Trail Blazers': 'POR', + 'Indiana Pacers': 'IND', + 'Milwaukee Bucks': 'MIL', + 'Golden State Warriors': 'GS', + 'Memphis Grizzlies': 'MEM', + 'Los Angeles Lakers': 'LAL' +} \ No newline at end of file diff --git a/Flask/templates/index.html b/Flask/templates/index.html index 5486e812c..81b997bf5 100644 --- a/Flask/templates/index.html +++ b/Flask/templates/index.html @@ -4,6 +4,10 @@ + + + + NBA Machine Learning Picks +
@@ -30,7 +35,7 @@

🏀 NBA AI Model Pic BetMGM - + {% for game_key in data.get('fanduel') %} {% set teams = game_key.split(':') %} @@ -44,10 +49,15 @@

🏀 NBA AI Model Pic - {{ teams[0] }} + + {{ teams[0] }} + - @ {{ teams[1] }} + + @ + {{ teams[1] }} + @@ -120,13 +130,14 @@

🏀 NBA AI Model Pic - + +

+ {% include 'team_modal.html' %} + {% include 'player_modal.html' %} - + \ No newline at end of file diff --git a/Flask/templates/player_modal.html b/Flask/templates/player_modal.html new file mode 100644 index 000000000..4aa36ed61 --- /dev/null +++ b/Flask/templates/player_modal.html @@ -0,0 +1,247 @@ + + + + + \ No newline at end of file diff --git a/Flask/templates/team_modal.html b/Flask/templates/team_modal.html new file mode 100644 index 000000000..a97c59444 --- /dev/null +++ b/Flask/templates/team_modal.html @@ -0,0 +1,259 @@ + +{% for game_key in data.get('fanduel') %} +{% set teams = game_key.split(':') %} +{% for team in teams %} + +{% endfor %} +{% endfor %} + + \ No newline at end of file diff --git a/src/Predict/NN_Runner.py b/src/Predict/NN_Runner.py index 8b821d54e..f869fcc24 100644 --- a/src/Predict/NN_Runner.py +++ b/src/Predict/NN_Runner.py @@ -1,23 +1,30 @@ import copy - import numpy as np import tensorflow as tf from colorama import Fore, Style, init, deinit from keras.models import load_model - from src.Utils import Expected_Value from src.Utils import Kelly_Criterion as kc init() -model = load_model('Models/NN_Models/Trained-Model-ML-1699315388.285516') -ou_model = load_model("Models/NN_Models/Trained-Model-OU-1699315414.2268295") +_model = None +_ou_model = None + +def _load_models(): + global _model, _ou_model + if _model is None: + _model = load_model('Models/NN_Models/Trained-Model-ML-1699315388.285516') + if _ou_model is None: + _ou_model = load_model("Models/NN_Models/Trained-Model-OU-1699315414.2268295") def nn_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_odds, kelly_criterion): + _load_models() + ml_predictions_array = [] for row in data: - ml_predictions_array.append(model.predict(np.array([row]))) + ml_predictions_array.append(_model.predict(np.array([row]))) frame_uo = copy.deepcopy(frame_ml) frame_uo['OU'] = np.asarray(todays_games_uo) @@ -28,7 +35,7 @@ def nn_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_ ou_predictions_array = [] for row in data: - ou_predictions_array.append(ou_model.predict(np.array([row]))) + ou_predictions_array.append(_ou_model.predict(np.array([row]))) count = 0 for game in games: