NHLcsv / app.py
tygiorgio's picture
Update app.py
6e5f739 verified
Raw
History Blame Contribute Delete
6.19 kB
import os
import requests
import gradio as gr
import pandas as pd
BASE_URL = "https://sportsbook-nash.draftkings.com/sites/US-VA-SB/api/sportscontent/controldata/league/leagueSubcategory/v1/markets"
LEAGUE_ID = "42133"
SUBCATEGORY_ID = "18010"
# OT adjustment factor (1 goal vs ~1.5 goals)
ADJUSTMENT_FACTOR = 0.67
DEBUG = True
def log(msg):
if DEBUG:
print(msg)
# =========================
# Odds Conversion
# =========================
def american_to_prob(odds):
odds = float(odds)
if odds > 0:
return 100 / (odds + 100)
else:
return abs(odds) / (abs(odds) + 100)
def prob_to_decimal(p):
if p <= 0:
return None
return round(1 / p, 3)
def extract_decimal_adjusted(odds):
try:
if odds is None:
return None
if isinstance(odds, dict):
odds = odds.get("american") or odds.get("value") or odds.get("price")
odds = str(odds).strip().replace("−", "-")
# already decimal
if "." in odds and not odds.startswith("+") and not odds.startswith("-"):
base_dec = float(odds)
p = 1 / base_dec
else:
p = american_to_prob(float(odds))
# apply OT adjustment
p_adj = p * ADJUSTMENT_FACTOR
return prob_to_decimal(p_adj)
except:
return None
# =========================
# Copy Format (TSV)
# =========================
def df_to_tsv(df):
if df is None or df.empty:
return ""
return "\n".join(
f"{row['Player']}\t{row['Decimal Odds']}"
for _, row in df.iterrows()
)
# =========================
# Fetch Data
# =========================
def fetch_data():
headers = {
"accept": "*/*",
"content-type": "application/json; charset=utf-8",
"origin": "https://sportsbook.draftkings.com",
"referer": "https://sportsbook.draftkings.com/",
"user-agent": "Mozilla/5.0",
}
params = {
"isBatchable": "false",
"templateVars": f"{LEAGUE_ID},{SUBCATEGORY_ID}",
"eventsQuery": f"$filter=leagueId eq '{LEAGUE_ID}' AND clientMetadata/Subcategories/any(s: s/Id eq '{SUBCATEGORY_ID}')",
"marketsQuery": f"$filter=clientMetadata/subCategoryId eq '{SUBCATEGORY_ID}'",
"include": "Events",
"entity": "events",
}
r = requests.get(BASE_URL, headers=headers, params=params, timeout=20)
r.raise_for_status()
data = r.json()
log(f"Events: {len(data.get('events', []))}")
log(f"Selections: {len(data.get('selections', []))}")
return data
# =========================
# Extract Games
# =========================
def extract_games(data):
games = []
for e in data.get("events", []):
event_id = e.get("id")
name = e.get("name")
if event_id and name:
games.append((name, str(event_id)))
return games
# =========================
# Match Markets
# =========================
def get_market_ids(data, event_id):
market_ids = []
for m in data.get("markets", []):
mid = m.get("id")
if str(m.get("eventId")) == str(event_id):
market_ids.append(str(mid))
if "eventIds" in m and str(event_id) in [str(x) for x in m["eventIds"]]:
market_ids.append(str(mid))
return set(market_ids)
# =========================
# Extract Players
# =========================
def extract_players(data, event_id):
selections = data.get("selections", [])
market_ids = get_market_ids(data, event_id)
rows = []
for s in selections:
market_id = s.get("marketId")
if str(market_id) not in market_ids:
continue
player = None
if s.get("participants"):
player = s["participants"][0].get("name")
if not player:
player = s.get("label") or s.get("outcomeName")
odds = s.get("displayOdds") or s.get("oddsAmerican") or s.get("price")
dec = extract_decimal_adjusted(odds)
if player and dec is not None:
rows.append((player, dec))
df = pd.DataFrame(rows, columns=["Player", "Decimal Odds"])
return df.drop_duplicates().sort_values("Player").reset_index(drop=True)
# =========================
# Initialize
# =========================
def initialize_app():
data = fetch_data()
games = extract_games(data)
if not games:
return {}, gr.Dropdown(choices=[], value=None)
game_map = {name: eid for name, eid in games}
return game_map, gr.Dropdown(
choices=list(game_map.keys()),
value=list(game_map.keys())[0]
)
# =========================
# Run
# =========================
def run_selected_game(game_map, selected_game):
if not selected_game:
return pd.DataFrame(), ""
data = fetch_data()
event_id = game_map[selected_game]
df = extract_players(data, event_id)
return df, df_to_tsv(df)
# =========================
# UI
# =========================
with gr.Blocks(title="DK NHL OT Adjusted Points") as demo:
gr.Markdown("# DK NHL OT Adjusted Points")
game_map_state = gr.State({})
with gr.Row():
game_dropdown = gr.Dropdown(label="Select Game", scale=5)
run_btn = gr.Button("Run", variant="primary")
refresh_btn = gr.Button("Refresh")
output_df = gr.Dataframe(
headers=["Player", "Decimal Odds"],
datatype=["str", "number"],
interactive=False,
label="Adjusted Player Table"
)
copy_box = gr.Textbox(
label="Copy (paste into Excel/Sheets)",
lines=12,
interactive=False
)
demo.load(
initialize_app,
inputs=[],
outputs=[game_map_state, game_dropdown]
)
run_btn.click(
run_selected_game,
inputs=[game_map_state, game_dropdown],
outputs=[output_df, copy_box]
)
refresh_btn.click(
initialize_app,
inputs=[],
outputs=[game_map_state, game_dropdown]
)
# =========================
# Launch
# =========================
if __name__ == "__main__":
demo.queue().launch(
server_name="0.0.0.0",
server_port=int(os.getenv("PORT", 7860))
)