Spaces:
Sleeping
Sleeping
File size: 8,776 Bytes
d5aed59 65f66ec 9b4705e 8b671c6 4c938b0 9b4705e 65f66ec 9b4705e 65f66ec 9b4705e 65f66ec 9b4705e 65f66ec 9b4705e 65f66ec 9b4705e 44d5540 9b4705e 44d5540 8b671c6 9b4705e 44d5540 9b4705e 8b671c6 9b4705e 44d5540 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | import streamlit as st
import requests
import pandas as pd
st.set_page_config(layout="wide")
# Define API URLs and headers
slate_url = "https://www.rotowire.com/daily/wnba/api/slate-list.php?siteID=1"
player_url_base = "https://www.rotowire.com/daily/wnba/api/players.php?slateID="
headers = {
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "en-US,en;q=0.9",
"Cookie": "PHPSESSID=b340dce31e2fe6b24ba4dcc921561b50; _fbp=fb.1.1753692771687.711224744180466095; _gcl_au=1.1.1672675840.1753692772; _ga=GA1.1.661634385.1753692772; intercom-id-bfhjit7z=85529c35-cb6c-4007-9335-0687d15c18a1; intercom-session-bfhjit7z=; intercom-device-id-bfhjit7z=83ce3491-d957-4599-89eb-2dbfcfffed54; cookieyes-consent=consentid:NHZGWmhCeURaeGUySlh5cTJaTEJOcWdPU2lZT1pCd3Y,consent:yes,action:no,necessary:yes,functional:yes,analytics:yes,performance:yes,advertisement:yes,other:yes; sharedid=b24bed8b-091f-4e7e-add8-96cd466790e7; sharedid_cst=kSylLAssaw%3D%3D; _lr_retry_request=true; _lr_env_src_ats=false; hb_insticator_uid=54225407-2db3-40d3-af18-f82167168130; pbjs-unifiedid=%7B%22TDID%22%3A%2273bf1881-4f9b-4c6f-9bb0-100d21c50499%22%2C%22TDID_LOOKUP%22%3A%22TRUE%22%2C%22TDID_CREATED_AT%22%3A%222025-06-28T08%3A52%3A51%22%7D; pbjs-unifiedid_cst=kSylLAssaw%3D%3D; _cc_id=de8e1434a7144b27260fdc79a8c30409; panoramaId=c4024b79a49a7f854a05b3190db54945a7025ae2ab983e5c2283ff0dc2cd405a; panoramaId_expiry=1754297572016; panoramaIdType=panoIndiv; connectId=%7B%22ttl%22%3A86400000%2C%22lastUsed%22%3A1753692774128%2C%22lastSynced%22%3A1753692774128%7D; cto_bidid=wNpa_V95NWJWZkFCV004YXNKdHFBZFBpaURJYXpVcCUyQjFPSmZCOEtyZnR1blJja25WM0Q1SHNIMm01bVZVZEpwdVJoQ2w4U0M5U0U2eVBEckxEZ09yODBrVDdzTGxMd0NpSzYxZm5xd0p4WTBINWFrJTNE; __gads=ID=62cdc6dbf3fa4d4e:T=1753692773:RT=1753692773:S=ALNI_MZcj2DhLz4YVMYbd_CLQ7dQMzbI5g; __gpi=UID=000011702b223793:T=1753692773:RT=1753692773:S=ALNI_Mb3F1y3HUi-GqjxvM-KBF1M3-5QHg; __eoi=ID=86abfa80c7e66266:T=1753692773:RT=1753692773:S=AA-AfjbkQxgd9_sZXLVHRz2hGqh4; idw-fe-id=8027215f-1b18-4092-9444-efece70b61b2; _lr_sampling_rate=100; cto_bundle=SiXMDV9LeGhTdEZUbkkyNlM2Mk1pdFI4WmslMkJLbzJqZ2h5b0F1eSUyQkRSdlI5dWFZbXVtQlA2VURSOUZwTDllR1NrV3ZNNVh6dEQzSzMwMlY0WW95VjFaSndNWFViYXMyRmolMkJOVlFsWUpFd0lhTTVwaTJpSldEOFFTVDZDdjZ6R01qT2FWUmUzSmdmTldzWVdiSUluVzMlMkY3Vm9oJTJGNXZRblIxOUJKSTRTc1ZWOFdGb2lwYnZ3TW1JZ2lyOFYlMkZ2YVVYNHdNczdmdVZsMFB3djhQYk03eThvREFia2VnTm9JT09lNzZURGtkY2xSbjRxSjVHYXpBOTV0Y0NjU0Z3bWlDSCUyQlg3dkk; rwlanding=%252Fdaily%252Fwnba%252Foptimizer.php; rw_tsd=1753692771__(direct)__(none)__(not set)__web__desktop; _rdt_uuid=1753692771432.f1d64ec6-1ed1-4659-b976-692ca175ebc1; _uetsid=3e8225106b9011f08382991a4653144e; _uetvid=3e823a306b9011f0bf4075c7ff02c82e; _ga_DJZM5GNYZ8=GS2.1.s1753692771$o1$g1$t1753693293$j27$l0$h1870534944",
"Referer": "https://www.rotowire.com/daily/wnba/optimizer.php",
"Sec-Ch-Ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"Windows\"",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
}
# Streamlit app title
st.title("WNBA Player Data")
# Fetch slate ID list
st.write("### Slate ID List")
try:
slate_response = requests.get(slate_url, headers=headers)
if slate_response.status_code == 200:
slate_data = slate_response.json()
# Handle slate data (list or nested 'slates')
if isinstance(slate_data, list):
slate_ids = [str(item.get('slateID')) for item in slate_data if 'slateID' in item]
elif isinstance(slate_data, dict) and 'slates' in slate_data:
slate_ids = [str(item.get('slateID')) for item in slate_data['slates'] if 'slateID' in item]
else:
st.error("Unexpected slate JSON structure. Please share the slate JSON response.")
slate_ids = []
if slate_ids:
st.write("Available Slate IDs:", ", ".join(slate_ids))
else:
st.error("No slate IDs found in the response.")
else:
st.error(f"Failed to fetch slate IDs: Status code {slate_response.status_code}")
except Exception as e:
st.error(f"An error occurred while fetching slate IDs: {str(e)}")
# Input for manual slate ID
slate_id = st.text_input("Enter Slate ID", value="512")
# Fetch player data for the entered slate ID
if slate_id:
player_url = f"{player_url_base}{slate_id}"
try:
response = requests.get(player_url, headers=headers)
if response.status_code == 200:
data = response.json()
# Convert JSON to DataFrame
if isinstance(data, list):
df = pd.DataFrame(data)
elif isinstance(data, dict) and 'players' in data:
df = pd.DataFrame(data['players'])
else:
st.error("Unexpected player JSON structure. Please share the player JSON response.")
st.stop()
# Combine firstName and lastName into Player
if 'firstName' in df.columns and 'lastName' in df.columns:
df['Player'] = df['firstName'] + ' ' + df['lastName']
# Extract nested fields
if 'team' in df.columns:
df['Team'] = df['team'].apply(lambda x: x.get('abbr') if isinstance(x, dict) else x)
if 'opponent' in df.columns:
df['Opp'] = df['opponent'].apply(lambda x: x.get('team') if isinstance(x, dict) else x)
if 'lineup' in df.columns:
df['Lineup'] = df['lineup'].apply(lambda x: x.get('slot') if isinstance(x, dict) else x)
# Flatten only stats.avgFpts
if 'stats' in df.columns:
stats_df = pd.json_normalize(df['stats'].apply(lambda x: x.get('avgFpts', {})))
# Rename columns to match desired names
stats_df = stats_df.rename(columns={
'last14': 'L14 FPTS',
'last3': 'L3 FPTS',
'last5': 'L5 FPTS',
'last7': 'L7 FPTS',
'season': 'AVG FPTS'
})
df = pd.concat([df.drop(columns=['stats']), stats_df], axis=1)
# Rename columns
column_mapping = {
'Player': 'Player',
'rotoPos': 'Position',
'injuryStatus': 'InjuryStatus',
'Team': 'Team',
'salary': 'Salary',
'minutes': 'Minutes',
'Lineup': 'Lineup',
'pts': 'FP',
'Opp': 'Opp'
}
df = df.rename(columns=column_mapping)
# Convert Lineup to 'Yes'/'No'
if 'Lineup' in df.columns:
df['Lineup'] = df['Lineup'].map({True: 'Yes', False: 'No', 'Yes': 'Yes', 'No': 'No', 1: 'Yes', 0: 'No', 'OUT': 'No'})
# Format Salary column to include '$'
if 'Salary' in df.columns:
df['Salary'] = df['Salary'].apply(lambda x: f"$ {x}" if pd.notnull(x) and isinstance(x, (int, float)) else x)
# Get unique teams for dropdown
if 'Team' in df.columns:
team_list = sorted(df['Team'].dropna().unique())
selected_teams = st.multiselect("Select Team(s)", team_list, default=team_list)
# Filter DataFrame by selected teams
if selected_teams:
df = df[df['Team'].isin(selected_teams)]
# Select desired columns
base_columns = ['Player', 'Position', 'InjuryStatus', 'Team', 'Salary', 'Minutes', 'Lineup', 'FP', 'Opp']
stats_columns = ['L14 FPTS', 'L3 FPTS', 'L5 FPTS', 'L7 FPTS', 'AVG FPTS']
desired_columns = base_columns + stats_columns
available_columns = [col for col in desired_columns if col in df.columns]
if available_columns:
df = df[available_columns]
st.write("### Player Data")
st.dataframe(df) # Display the DataFrame
else:
st.error("None of the desired columns were found. Displaying all columns instead.")
st.dataframe(df) # Fallback to all columns
else:
st.error(f"Failed to fetch player data: Status code {response.status_code}")
except Exception as e:
st.error(f"An error occurred while fetching player data: {str(e)}") |