import streamlit as st st.set_page_config(layout="wide") for name in dir(): if not name.startswith('_'): del globals()[name] import numpy as np import pandas as pd import streamlit as st import gspread from reportlab.lib import colors from reportlab.lib.pagesizes import letter, landscape from reportlab.platypus import SimpleDocTemplate, Table, TableStyle from io import BytesIO @st.cache_resource def init_conn(): scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive'] credentials = { "type": "service_account", "project_id": "model-sheets-connect", "private_key_id": st.secrets['model_sheets_connect_pk'], "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDiu1v/e6KBKOcK\ncx0KQ23nZK3ZVvADYy8u/RUn/EDI82QKxTd/DizRLIV81JiNQxDJXSzgkbwKYEDm\n48E8zGvupU8+Nk76xNPakrQKy2Y8+VJlq5psBtGchJTuUSHcXU5Mg2JhQsB376PJ\nsCw552K6Pw8fpeMDJDZuxpKSkaJR6k9G5Dhf5q8HDXnC5Rh/PRFuKJ2GGRpX7n+2\nhT/sCax0J8jfdTy/MDGiDfJqfQrOPrMKELtsGHR9Iv6F4vKiDqXpKfqH+02E9ptz\nBk+MNcbZ3m90M8ShfRu28ebebsASfarNMzc3dk7tb3utHOGXKCf4tF8yYKo7x8BZ\noO9X4gSfAgMBAAECggEAU8ByyMpSKlTCF32TJhXnVJi/kS+IhC/Qn5JUDMuk4LXr\naAEWsWO6kV/ZRVXArjmuSzuUVrXumISapM9Ps5Ytbl95CJmGDiLDwRL815nvv6k3\nUyAS8EGKjz74RpoIoH6E7EWCAzxlnUgTn+5oP9Flije97epYk3H+e2f1f5e1Nn1d\nYNe8U+1HqJgILcxA1TAUsARBfoD7+K3z/8DVPHI8IpzAh6kTHqhqC23Rram4XoQ6\nzj/ZdVBjvnKuazETfsD+Vl3jGLQA8cKQVV70xdz3xwLcNeHsbPbpGBpZUoF73c65\nkAXOrjYl0JD5yAk+hmYhXr6H9c6z5AieuZGDrhmlFQKBgQDzV6LRXmjn4854DP/J\nI82oX2GcI4eioDZPRukhiQLzYerMQBmyqZIRC+/LTCAhYQSjNgMa+ZKyvLqv48M0\n/x398op/+n3xTs+8L49SPI48/iV+mnH7k0WI/ycd4OOKh8rrmhl/0EWb9iitwJYe\nMjTV/QxNEpPBEXfR1/mvrN/lVQKBgQDuhomOxUhWVRVH6x03slmyRBn0Oiw4MW+r\nrt1hlNgtVmTc5Mu+4G0USMZwYuOB7F8xG4Foc7rIlwS7Ic83jMJxemtqAelwOLdV\nXRLrLWJfX8+O1z/UE15l2q3SUEnQ4esPHbQnZowHLm0mdL14qSVMl1mu1XfsoZ3z\nJZTQb48CIwKBgEWbzQRtKD8lKDupJEYqSrseRbK/ax43DDITS77/DWwHl33D3FYC\nMblUm8ygwxQpR4VUfwDpYXBlklWcJovzamXpSnsfcYVkkQH47NuOXPXPkXQsw+w+\nDYcJzeu7F/vZqk9I7oBkWHUrrik9zPNoUzrfPvSRGtkAoTDSwibhoc5dAoGBAMHE\nK0T/ANeZQLNuzQps6S7G4eqjwz5W8qeeYxsdZkvWThOgDd/ewt3ijMnJm5X05hOn\ni4XF1euTuvUl7wbqYx76Wv3/1ZojiNNgy7ie4rYlyB/6vlBS97F4ZxJdxMlabbCW\n6b3EMWa4EVVXKoA1sCY7IVDE+yoQ1JYsZmq45YzPAoGBANWWHuVueFGZRDZlkNlK\nh5OmySmA0NdNug3G1upaTthyaTZ+CxGliwBqMHAwpkIRPwxUJpUwBTSEGztGTAxs\nWsUOVWlD2/1JaKSmHE8JbNg6sxLilcG6WEDzxjC5dLL1OrGOXj9WhC9KX3sq6qb6\nF/j9eUXfXjAlb042MphoF3ZC\n-----END PRIVATE KEY-----\n", "client_email": "gspread-connection@model-sheets-connect.iam.gserviceaccount.com", "client_id": "100369174533302798535", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40model-sheets-connect.iam.gserviceaccount.com" } gc_con = gspread.service_account_from_dict(credentials, scope) return gc_con gcservice_account = init_conn() NHL_data = st.secrets['NHL_Data'] percentages_format = {'Shots': '{:.2%}', 'HDCF': '{:.2%}', 'Goals': '{:.2%}', 'Assists': '{:.2%}', 'Blocks': '{:.2%}', 'L14_Shots': '{:.2%}', 'L14_HDCF': '{:.2%}', 'L14_Goals': '{:.2%}', 'L14_Assists': '{:.2%}', 'L14_Blocks': '{:.2%}', 'Max Goal%': '{:.2%}', 'L14 Max Goal%': '{:.2%}'} matchups_format = {'HDCF%': '{:.2%}', 'o_HDCA%': '{:.2%}', 'HDCF_m%': '{:.2%}'} @st.cache_resource(ttl = 599) def init_baselines(): parse_hold = pd.DataFrame(columns=['Line', 'SK1', 'SK2', 'SK3', 'Cost', 'Team Total', 'Shots', 'HDCF', 'Goals', 'Assists', 'Blocks', 'L14_Shots', 'L14_HDCF', 'L14_Goals', 'L14_Assists', 'L14_Blocks', 'Max Goal%']) sh = gcservice_account.open_by_url(NHL_data) worksheet = sh.worksheet('Player_Level_ROO') raw_display = pd.DataFrame(worksheet.get_values()) raw_display.columns = raw_display.iloc[0] raw_display = raw_display[1:] raw_display = raw_display.reset_index(drop=True) raw_display = raw_display[raw_display['Opp'] != ""] team_frame = raw_display[['Team', 'Opp']] team_list = team_frame['Team'].unique() team_dict = dict(zip(team_frame['Team'], team_frame['Opp'])) worksheet = sh.worksheet('Matchups') raw_display = pd.DataFrame(worksheet.get_values()) raw_display.columns = raw_display.iloc[0] raw_display = raw_display[1:] raw_display = raw_display.reset_index(drop=True) raw_display = raw_display[raw_display['Opp'] != ""] matchups = raw_display[['Team', 'Opp', 'FL1$', 'FL2$', 'FL3$', 'Team Total', 'Game Pace', 'SF', 'o_SA', 'SF_m', 'HDCF', 'o_HDCA', 'HDCF_m', 'HDCF%', 'o_HDCA%', 'HDCF_m%', 'HDSF+']] data_cols = matchups.columns.drop(['Team', 'Opp']) matchups[data_cols] = matchups[data_cols].apply(pd.to_numeric, errors='coerce') matchups = matchups.dropna(subset='FL1$') matchups = matchups.sort_values(by='HDCF_m', ascending=False) worksheet = sh.worksheet('Marketshares') raw_display = pd.DataFrame(worksheet.get_values()) raw_display.columns = raw_display.iloc[0] raw_display = raw_display[1:] raw_display = raw_display.reset_index(drop=True) # raw_display = raw_display[raw_display['Line'] != ""] overall_ms = raw_display[['Line', 'SK1', 'SK2', 'SK3', 'Cost', 'Team Total', 'Shots', 'HDCF', 'Goals', 'Assists', 'Blocks', 'L14_Shots', 'L14_HDCF', 'L14_Goals', 'L14_Assists', 'L14_Blocks']] pat = '|'.join(team_list) s = overall_ms['Line'].str.extract('('+ pat + ')', expand=False) overall_ms['Max Goal%'] = overall_ms.groupby(s)['Goals'].transform('max') overall_ms['L14 Max Goal%'] = overall_ms.groupby(s)['L14_Goals'].transform('max') data_cols = overall_ms.columns.drop(['Line', 'SK1', 'SK2', 'SK3']) overall_ms[data_cols] = overall_ms[data_cols].apply(pd.to_numeric, errors='coerce') overall_ms['Proj Goal'] = overall_ms['Goals'] * overall_ms['Team Total'] overall_ms['L14 Proj Goal'] = overall_ms['L14_Goals'] * overall_ms['Team Total'] overall_ms = overall_ms[['Line', 'SK1', 'SK2', 'SK3', 'Cost', 'Team Total', 'Shots', 'HDCF', 'Goals', 'Max Goal%', 'Proj Goal', 'Assists', 'Blocks', 'L14_Shots', 'L14_HDCF', 'L14_Goals', 'L14 Max Goal%', 'L14 Proj Goal', 'L14_Assists', 'L14_Blocks']] overall_ms = overall_ms.sort_values(by='Shots', ascending=False) return matchups, overall_ms, team_frame, team_list, team_dict def convert_df_to_csv(df): return df.to_csv().encode('utf-8') def convert_df_to_pdf(df): try: # Create a buffer to receive PDF data buffer = BytesIO() # Create the PDF object using the buffer as its "file" doc = SimpleDocTemplate(buffer, pagesize=landscape(letter)) # Convert DataFrame to a list of lists for the table data = [df.columns.tolist()] + df.values.tolist() # Create the table table = Table(data) # Add style to the table style = TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.grey), ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONTSIZE', (0, 0), (-1, 0), 10), ('BOTTOMPADDING', (0, 0), (-1, 0), 12), ('BACKGROUND', (0, 1), (-1, -1), colors.white), ('TEXTCOLOR', (0, 1), (-1, -1), colors.black), ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'), ('FONTSIZE', (0, 1), (-1, -1), 8), ('GRID', (0, 0), (-1, -1), 1, colors.black), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ]) table.setStyle(style) # Build the PDF elements = [table] doc.build(elements) # Get the value of the BytesIO buffer pdf = buffer.getvalue() buffer.close() return pdf except Exception as e: st.error(f"Error generating PDF: {str(e)}") return None matchups, overall_ms, team_frame, team_list, team_dict = init_baselines() col1, col2 = st.columns([1, 9]) with col1: if st.button("Reset Data", key='reset1'): st.cache_data.clear() matchups, overall_ms, team_frame, team_list, team_dict = init_baselines() split_var1 = st.radio("View matchups or line marketshares?", ('Slate Matchups', 'Line Marketshares'), key='split_var1') if split_var1 == "Line Marketshares": team_var = st.radio("View all teams or specific teams?", ('All Teams', 'Specific Teams'), key='team_var') if team_var == "All Teams": team_split = team_frame.Team.values.tolist() elif team_var == "Specific Teams": team_split = st.multiselect('Which teams would you like to include in the tables?', options = team_frame['Team'].unique(), key='team_var1') with col2: if split_var1 == 'Slate Matchups': display_table = matchups display_table = display_table.set_index('Team') st.dataframe(display_table.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(matchups_format, precision=2), height=500, use_container_width = True) elif split_var1 == 'Line Marketshares': display_table = overall_ms display_parsed = display_table[display_table['Line'].str.contains('|'.join(team_split))] display_parsed = display_parsed.set_index('Line') st.dataframe(display_parsed.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), height=500, use_container_width = True) download_var = st.selectbox('What download would you like?', options = ['CSV', 'PDF'], key='download_var') if st.button('Download'): if download_var == 'CSV': st.download_button( label="Export Marketshares (CSV)", data=convert_df_to_csv(display_table), file_name='Marketshares_export.csv', mime='text/csv', ) elif download_var == 'PDF': st.download_button( label="Export Marketshares (PDF)", data=convert_df_to_pdf(display_table), file_name='Marketshares_export.pdf', mime='application/pdf', )