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()