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)}")