James McCool commited on
Commit
0464302
·
1 Parent(s): b4f9135

Initial commit for bridge stage

Browse files
.streamlit/secrets.toml ADDED
@@ -0,0 +1 @@
 
 
1
+ PGA_models = 'https://docs.google.com/spreadsheets/d/1lMLxWdvCnOFBtG9dhM0zv2USuxZbkogI_2jnxFfQVVs/edit#gid=1733549835'
Dockerfile CHANGED
@@ -5,11 +5,23 @@ WORKDIR /app
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
 
8
  git \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
  COPY requirements.txt ./
12
  COPY src/ ./src/
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  RUN pip3 install -r requirements.txt
15
 
 
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
8
+ software-properties-common \
9
  git \
10
  && rm -rf /var/lib/apt/lists/*
11
 
12
  COPY requirements.txt ./
13
  COPY src/ ./src/
14
+ COPY .streamlit/ ./.streamlit/
15
+
16
+ ENV MONGO_URI="mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
17
+ ENV PGA_DATA='https://docs.google.com/spreadsheets/d/1lMLxWdvCnOFBtG9dhM0zv2USuxZbkogI_2jnxFfQVVs/edit#gid=1733549835'
18
+ RUN useradd -m -u 1000 user
19
+ USER user
20
+ ENV HOME=/home/user\
21
+ PATH=/home/user/.local/bin:$PATH
22
+ WORKDIR $HOME/app
23
+ RUN pip install --no-cache-dir --upgrade pip
24
+ COPY --chown=user . $HOME/app
25
 
26
  RUN pip3 install -r requirements.txt
27
 
requirements.txt CHANGED
@@ -1,3 +1,9 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
 
1
+ streamlit
2
+ gspread
3
+ openpyxl
4
+ matplotlib
5
+ streamlit-aggrid
6
+ pulp
7
+ docker
8
+ plotly
9
+ scipy
src/database.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gspread
2
+
3
+ scope = ['https://www.googleapis.com/auth/spreadsheets',
4
+ "https://www.googleapis.com/auth/drive"]
5
+
6
+ credentials = {
7
+ "type": "service_account",
8
+ "project_id": "sheets-api-connect-378620",
9
+ "private_key_id": "1005124050c80d085e2c5b344345715978dd9cc9",
10
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtKa01beXwc88R\nnPZVQTNPVQuBnbwoOfc66gW3547ja/UEyIGAF112dt/VqHprRafkKGmlg55jqJNt\na4zceLKV+wTm7vBu7lDISTJfGzCf2TrxQYNqwMKE2LOjI69dBM8u4Dcb4k0wcp9v\ntW1ZzLVVuwTvmrg7JBHjiSaB+x5wxm/r3FOiJDXdlAgFlytzqgcyeZMJVKKBQHyJ\njEGg/1720A0numuOCt71w/2G0bDmijuj1e6tH32MwRWcvRNZ19K9ssyDz2S9p68s\nYDhIxX69OWxwScTIHLY6J2t8txf/XMivL/636fPlDADvBEVTdlT606n8CcKUVQeq\npUVdG+lfAgMBAAECggEAP38SUA7B69eTfRpo658ycOs3Amr0JW4H/bb1rNeAul0K\nZhwd/HnU4E07y81xQmey5kN5ZeNrD5EvqkZvSyMJHV0EEahZStwhjCfnDB/cxyix\nZ+kFhv4y9eK+kFpUAhBy5nX6T0O+2T6WvzAwbmbVsZ+X8kJyPuF9m8ldcPlD0sce\ntj8NwVq1ys52eosqs7zi2vjt+eMcaY393l4ls+vNq8Yf27cfyFw45W45CH/97/Nu\n5AmuzlCOAfFF+z4OC5g4rei4E/Qgpxa7/uom+BVfv9G0DIGW/tU6Sne0+37uoGKt\nW6DzhgtebUtoYkG7ZJ05BTXGp2lwgVcNRoPwnKJDxQKBgQDT5wYPUBDW+FHbvZSp\nd1m1UQuXyerqOTA9smFaM8sr/UraeH85DJPEIEk8qsntMBVMhvD3Pw8uIUeFNMYj\naLmZFObsL+WctepXrVo5NB6RtLB/jZYxiKMatMLUJIYtcKIp+2z/YtKiWcLnwotB\nWdCjVnPTxpkurmF2fWP/eewZ+wKBgQDRMtJg7etjvKyjYNQ5fARnCc+XsI3gkBe1\nX9oeXfhyfZFeBXWnZzN1ITgFHplDznmBdxAyYGiQdbbkdKQSghviUQ0igBvoDMYy\n1rWcy+a17Mj98uyNEfmb3X2cC6WpvOZaGHwg9+GY67BThwI3FqHIbyk6Ko09WlTX\nQpRQjMzU7QKBgAfi1iflu+q0LR+3a3vvFCiaToskmZiD7latd9AKk2ocsBd3Woy9\n+hXXecJHPOKV4oUJlJgvAZqe5HGBqEoTEK0wyPNLSQlO/9ypd+0fEnArwFHO7CMF\nycQprAKHJXM1eOOFFuZeQCaInqdPZy1UcV5Szla4UmUZWkk1m24blHzXAoGBAMcA\nyH4qdbxX9AYrC1dvsSRvgcnzytMvX05LU0uF6tzGtG0zVlub4ahvpEHCfNuy44UT\nxRWW/oFFaWjjyFxO5sWggpUqNuHEnRopg3QXx22SRRTGbN45li/+QAocTkgsiRh1\nqEcYZsO4mPCsQqAy6E2p6RcK+Xa+omxvSnVhq0x1AoGAKr8GdkCl4CF6rieLMAQ7\nLNBuuoYGaHoh8l5E2uOQpzwxVy/nMBcAv+2+KqHEzHryUv1owOi6pMLv7A9mTFoS\n18B0QRLuz5fSOsVnmldfC9fpUc6H8cH1SINZpzajqQA74bPwELJjnzrCnH79TnHG\nJuElxA33rFEjbgbzdyrE768=\n-----END PRIVATE KEY-----\n",
11
+ "client_email": "gspread-connection@sheets-api-connect-378620.iam.gserviceaccount.com",
12
+ "client_id": "106625872877651920064",
13
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
14
+ "token_uri": "https://oauth2.googleapis.com/token",
15
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
16
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40sheets-api-connect-378620.iam.gserviceaccount.com"
17
+ }
18
+
19
+ gc = gspread.service_account_from_dict(credentials)
src/streamlit_app.py CHANGED
@@ -1,40 +1,78 @@
1
- import altair as alt
2
- import numpy as np
3
  import pandas as pd
4
  import streamlit as st
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import pandas as pd
2
  import streamlit as st
3
+ import os
4
+ from database import gc
5
 
6
+ st.set_page_config(layout="wide")
7
+
8
+ PGA_models = os.getenv('PGA_DATA')
9
+
10
+ st.markdown("""
11
+ <style>
12
+ /* Tab styling */
13
+ .stElementContainer [data-baseweb="button-group"] {
14
+ gap: 2.000rem;
15
+ padding: 4px;
16
+ }
17
+ .stElementContainer [kind="segmented_control"] {
18
+ height: 2.000rem;
19
+ white-space: pre-wrap;
20
+ background-color: #DAA520;
21
+ color: white;
22
+ border-radius: 20px;
23
+ gap: 1px;
24
+ padding: 10px 20px;
25
+ font-weight: bold;
26
+ transition: all 0.3s ease;
27
+ }
28
+ .stElementContainer [kind="segmented_controlActive"] {
29
+ height: 3.000rem;
30
+ background-color: #DAA520;
31
+ border: 3px solid #FFD700;
32
+ border-radius: 10px;
33
+ color: black;
34
+ }
35
+ .stElementContainer [kind="segmented_control"]:hover {
36
+ background-color: #FFD700;
37
+ cursor: pointer;
38
+ }
39
+
40
+ div[data-baseweb="select"] > div {
41
+ background-color: #DAA520;
42
+ color: white;
43
+ }
44
+
45
+ </style>""", unsafe_allow_html=True)
46
+
47
+ @st.cache_data
48
+ def load_dk_player_model(URL):
49
+ sh = gc.open_by_url(URL)
50
+ worksheet = sh.worksheet('Odds_vs_Salary')
51
+ raw_display = pd.DataFrame(worksheet.get_all_records())
52
+ raw_display = raw_display.drop(['ID', 'Roster Position', 'Cut%'], axis=1)
53
+ raw_display.rename(columns={"Name": "Player"}, inplace = True)
54
+ data_cols = raw_display.columns.drop(['Player'])
55
+ raw_display[data_cols] = raw_display[data_cols].apply(pd.to_numeric, errors='coerce')
56
+
57
+ return raw_display
58
+
59
+ def convert_df_to_csv(df):
60
+ return df.to_csv().encode('utf-8')
61
+
62
+ format_dict = {'Cut%': '{:.2%}', 'Win Odds': '{:.2%}','T5 Odds': '{:.2%}', 'T10 Odds': '{:.2%}','T20 Odds': '{:.2%}'}
63
+
64
+
65
+ if st.button("Reset Data", key='reset1'):
66
+ # Clear values from *all* all in-memory and on-disk data caches:
67
+ # i.e. clear values from both square and cube
68
+ st.cache_data.clear()
69
+ hold_display = load_dk_player_model(PGA_models)
70
+ display = hold_display.set_index('Player')
71
+ st.dataframe(display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(format_dict, precision=2), use_container_width = True)
72
+ st.download_button(
73
+ label="Export Model",
74
+ data=convert_df_to_csv(display),
75
+ file_name='PGA_DK_Vegas_Salary_export.csv',
76
+ mime='text/csv',
77
+ key='DK_download',
78
+ )