YFDashboard / src /pages /3_Draft_View.py
Jon Solow
Add depth charts
45e7011
import json
import os
import pandas as pd
import requests
import streamlit as st
from config import DEFAULT_ICON, SEASON
from login_component import is_token_in_session
from shared_page import common_page_config
from streamlit_filter import filter_dataframe
@st.cache_data(ttl=60 * 60 * 24)
def load_yahoo_to_fp_id_map() -> dict[str, str]:
df = pd.read_csv(r"https://raw.githubusercontent.com/dynastyprocess/data/master/files/db_playerids.csv")
for id_col in ["yahoo_id", "fantasypros_id"]:
df[id_col] = df[id_col].fillna(-9999).apply(lambda x: str(int(x)))
player_id_dict = df.set_index("yahoo_id")["fantasypros_id"].to_dict()
# map team DST
player_id_dict.update(
{
"100022": "8000", # Arizona
"100001": "8010", # Atlanta
"100033": "8020", # Baltimore
"100002": "8030", # Buffalo
"100029": "8040", # Carolina
"100003": "8050", # Chicago
"100004": "8060", # Cincinnati
"100005": "8070", # Cleveland
"100006": "8080", # Dallas
"100007": "8090", # Denver
"100008": "8100", # Detroit
"100009": "8110", # Green Bay
"100034": "8120", # Houston
"100011": "8130", # Indianapolis
"100030": "8140", # Jacksonville
"100012": "8150", # Kansas City
"100013": "8220", # Las Vegas
"100014": "8280", # Los Angeles Rams
"100024": "8250", # Los Angeles Chargers
"100015": "8160", # Miami
"100016": "8170", # Minnesota
"100017": "8180", # New England
"100018": "8190", # New Orleans
"100019": "8200", # New York Giants
"100020": "8210", # New York Jets
"100021": "8230", # Philadelphia
"100023": "8240", # Pittsburgh
"100025": "8270", # San Francisco
"100026": "8260", # Seattle
"100027": "8290", # Tampa Bay
"100010": "8300", # Tennessee
"100028": "8310", # Washington
}
)
return player_id_dict
def load_depth_charts():
df = pd.read_csv(os.path.join(os.path.dirname(__file__), "../../tests/mocks/2024 Depth Charts - formatted.csv"))
df["yahoo_id"] = df["yahoo_id"].apply(lambda x: str(int(x)))
df["fp_id"] = df["yahoo_id"].apply(lambda x: load_yahoo_to_fp_id_map().get(x, x))
return df
def extract_ecr_var_data(request_text_str, var_name: str):
start_str = f"""var {var_name} = """
end_str = """};"""
end_offset = 1 # include closing bracket
start_slice_pos = request_text_str.find(start_str) + len(start_str)
first_slice = request_text_str[start_slice_pos:]
end_slice_pos = first_slice.find(end_str) + end_offset
dom_str = first_slice[:end_slice_pos]
var_json = json.loads(dom_str)
return var_json
@st.cache_data(ttl=60 * 60 * 24)
def load_ecr_data():
request_text = get_ecr_request_text()
ecr_data = extract_ecr_var_data(request_text, "ecrData")
ecr_columns = [
"player_id",
"player_name",
"player_position_id",
"player_bye_week",
"rank_ecr",
"pos_rank",
"tier",
]
df_ecr = pd.DataFrame(ecr_data["players"])[ecr_columns]
df_ecr["rank_ecr"] = df_ecr["rank_ecr"].astype(int)
df_ecr["player_id"] = df_ecr["player_id"].apply(lambda x: str(int(x)))
# sos_data = extract_ecr_var_data(request_text, "sosData")
# adp_data = extract_ecr_var_data(request_text, "adpData")
return df_ecr
@st.cache_data(ttl=60 * 60 * 24)
def get_ecr_request_text():
r = requests.get("https://www.fantasypros.com/nfl/rankings/half-point-ppr-cheatsheets.php")
return r.text
@st.cache_resource(ttl=60 * 60 * 24)
def get_league_settings_with_cache(selected_league):
return st.session_state.yahoo_client.parse_league_settings(selected_league)
def highlight_drafted(data_row_series):
return ["background-color: red" if data_row_series.is_drafted else "" for _ in range(len(data_row_series))]
def display_formatted_tiers(df):
st.dataframe(
df.sort_values("rank_ecr").style.apply(highlight_drafted, axis=1),
hide_index=True,
height=35 * (len(df) + 1) + 5,
column_order=[
"rank_ecr",
"player_name",
# "player_position_id",
"player_bye_week",
# "tier",
# "is_drafted",
"Team",
"Depth Position",
"Source",
],
column_config={
"player_name": st.column_config.TextColumn(label="", help="Player's name"),
"player_position_id": st.column_config.TextColumn(label="", help="Player's position"),
"player_bye_week": st.column_config.NumberColumn(label="Bye", help="Player's Bye Week"),
"rank_ecr": st.column_config.NumberColumn(label="Rank", help="Player ECR Rank"),
"tier": st.column_config.NumberColumn(label="Tier", help="Player Tier"),
"is_drafted": st.column_config.CheckboxColumn(label="Drafted", help="Has been drafted"),
"Depth Position": st.column_config.TextColumn(label=""),
"Source": st.column_config.TextColumn(label=""),
},
use_container_width=True,
)
def get_page():
page_title = "Yahoo Draft Live Summary"
st.set_page_config(page_title=page_title, page_icon=DEFAULT_ICON, layout="wide")
common_page_config()
st.title(page_title)
if not (is_token_in_session() and st.session_state.get("user_admin")):
st.write("Exclusive feature")
else:
selected_season = st.selectbox("Select Season", list(range(SEASON, 2012, -1)))
user_leagues = st.session_state.yahoo_client.find_all_leagues_for_logged_in_user(season=selected_season)
selected_league = st.selectbox("Select league", user_leagues)
league_settings = get_league_settings_with_cache(selected_league)
st.header(f"{league_settings.name} - {league_settings.season}")
with st.expander("Show Positions"):
st.dataframe(
pd.DataFrame(league_settings.roster_positions).set_index("position")["count"],
)
draft_result = st.session_state.yahoo_client.get_draft(selected_league)
if st.button("Load / Refresh"):
draft_result = st.session_state.yahoo_client.get_draft(selected_league)
if "player_key" in draft_result:
draft_result["player_id"] = draft_result["player_key"].apply(lambda x: x.rsplit(".", 1)[-1] if x else x)
else:
draft_result["player_id"] = ""
draft_result["fp_id"] = draft_result["player_id"].apply(lambda x: load_yahoo_to_fp_id_map().get(x, x))
ecr_data = load_ecr_data()
draft_result_merge_cols = [
"fp_id",
"team_key",
"round",
"pick",
]
for col in draft_result_merge_cols:
if col not in draft_result:
draft_result[col] = ""
ecr_with_draft = ecr_data.merge(
draft_result[draft_result_merge_cols], how="outer", left_on="player_id", right_on="fp_id"
)
ecr_with_draft["is_drafted"] = ecr_with_draft["fp_id"].notna()
depth_charts = load_depth_charts()
ecr_with_draft = ecr_with_draft.merge(depth_charts, how="left", left_on="player_id", right_on="fp_id")
if ("round" in ecr_with_draft) and ("pick" in ecr_with_draft):
draft_picks_only = ecr_with_draft[ecr_with_draft.is_drafted].sort_values(["round", "pick"])
with st.expander("Show Draft Results"):
pos_pivot_df = draft_picks_only.pivot_table(
values="player_id", columns="player_position_id", index="team_key", aggfunc="count", margins=True
)
st.dataframe(pos_pivot_df, use_container_width=True)
if st.checkbox("Full Results"):
st.dataframe(draft_picks_only)
with st.expander("Unmatched"):
st.dataframe(ecr_with_draft[ecr_with_draft.player_name.isna()])
st.header("ECR Tiers")
with st.expander("Filters"):
filtered_data = filter_dataframe(
ecr_with_draft,
force_on=True,
force_on_columns=["is_drafted", "player_position_id", "Team", "Source", "Depth Position"],
)
position_list = [
x for x in ["QB", "RB", "WR", "TE", "DST", "K"] if x in filtered_data.player_position_id.unique()
]
if not st.checkbox("Show DST/K"):
position_list = [x for x in position_list if x not in ["DST", "K"]]
if st.checkbox("Show Overall"):
position_list = ["OVERALL"]
columns_list = st.columns(len(position_list))
for pos, col in zip(position_list, columns_list):
with col:
st.header(pos)
if pos == "OVERALL":
df_pos = filtered_data
else:
df_pos = filtered_data[filtered_data.player_position_id == pos]
for tier, df_tier in df_pos.groupby("tier"):
st.header(f"Tier {tier}")
display_formatted_tiers(df_tier)
if __name__ == "__main__":
get_page()