Spaces:
Sleeping
Sleeping
Download src/streamlit_app.py from acetwo3ee/WNBA_STATS: direct link, hf CLI and curl.
- Browser
- Download file 8.78 kB
-
https://huggingface.co/spaces/acetwo3ee/WNBA_STATS/resolve/main/src/streamlit_app.py
- Command line
-
hf download hf://spaces/acetwo3ee/WNBA_STATS/src/streamlit_app.py
-
curl -L -o streamlit_app.py https://huggingface.co/spaces/acetwo3ee/WNBA_STATS/resolve/main/src/streamlit_app.py
8.78 kB
| 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)}") |