Compare commits
11 commits
feature-hu
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98db8d28a7 | ||
|
|
cdaba75591 | ||
|
|
ce36987863 | ||
|
|
17e1f551ec | ||
|
|
d3532386fd | ||
|
|
082f905a25 | ||
|
|
f8ef55628c | ||
|
|
39e6e71da1 | ||
|
|
7115648754 | ||
|
|
2cbdbed180 | ||
|
|
6342be9def |
|
|
@ -2,3 +2,5 @@ ESPN_S2 = 'S2 key here'
|
|||
SWID = 'SWID key here'
|
||||
LEAGUE_ID = 'League ID here'
|
||||
FETCH_LEAGUE = 'true'
|
||||
SPREADSHEET_ID = 'Google Sheets ID here'
|
||||
WORKSHEET_NAME = 'Worksheet name here'
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Copy `.env-template` as `.env` file and enter the following items:
|
|||
- `ESPN_S2`: S2 key from ESPN
|
||||
- `SWID`: SWID key from ESPN
|
||||
- `LEAGUE_ID`: League ID for your Fantasy League from ESPN
|
||||
- `FETCH_LEAGE`: Generally, leave as `true` unless you know what you're doing
|
||||
- `FETCH_LEAGUE`: Generally, leave as `true` unless you know what you're doing
|
||||
|
||||
For more information on how to retrieve these details, head on over to GitHub and [review this discussion](https://github.com/cwendt94/espn-api/discussions/150).
|
||||
|
||||
|
|
|
|||
45
app.py
45
app.py
|
|
@ -1,67 +1,56 @@
|
|||
from config import Config as cfg
|
||||
from config import cfg
|
||||
from datetime import datetime
|
||||
from espn_api.football import League
|
||||
from gspread_dataframe import set_with_dataframe
|
||||
from huey import crontab, RedisHuey
|
||||
from service import gc
|
||||
from tabulate import tabulate
|
||||
|
||||
import pandas as pd
|
||||
|
||||
|
||||
huey = RedisHuey('report-generator', host='redis')
|
||||
|
||||
|
||||
def check_int(s):
|
||||
if s is None:
|
||||
return s
|
||||
if s[0] in ('-', '+'):
|
||||
return s[1:].isdigit()
|
||||
return s.isdigit()
|
||||
|
||||
|
||||
def extract_positional_data(lineup: list, position: str) -> int:
|
||||
def aggregate_positional_points(lineup: list, position: str) -> int:
|
||||
response = 0
|
||||
for player in lineup:
|
||||
if player.lineupSlot == position:
|
||||
response = response + player.points
|
||||
response += player.points
|
||||
return response
|
||||
|
||||
|
||||
def extract_matchup_box_scores(league: League) -> dict:
|
||||
def extract_weekly_box_scores(league: League) -> list:
|
||||
result = []
|
||||
for week in range(1, league.current_week + 1):
|
||||
matchups = league.box_scores(week=week)
|
||||
for matchup in matchups:
|
||||
result.append({
|
||||
'WEEK #': week,
|
||||
'AWAY TEAM': matchup.away_team.team_name,
|
||||
'AWAY TEAM': matchup.away_team.team_name, # pyright: ignore[reportAttributeAccessIssue]
|
||||
'AWAY TEAM SCORE': matchup.away_score,
|
||||
'AWAY TEAM KICKER': extract_positional_data(matchup.away_lineup, 'K'),
|
||||
'AWAY TEAM BENCH': extract_positional_data(matchup.away_lineup, 'BE'),
|
||||
'HOME TEAM': matchup.home_team.team_name,
|
||||
'AWAY TEAM KICKER': aggregate_positional_points(matchup.away_lineup, 'K'),
|
||||
'AWAY TEAM BENCH': aggregate_positional_points(matchup.away_lineup, 'BE'),
|
||||
'HOME TEAM': matchup.home_team.team_name, # pyright: ignore[reportAttributeAccessIssue]
|
||||
'HOME TEAM SCORE': matchup.home_score,
|
||||
'HOME TEAM KICKER': extract_positional_data(matchup.home_lineup, 'K'),
|
||||
'HOME TEAM BENCH': extract_positional_data(matchup.home_lineup, 'BE')
|
||||
'HOME TEAM KICKER': aggregate_positional_points(matchup.home_lineup, 'K'),
|
||||
'HOME TEAM BENCH': aggregate_positional_points(matchup.home_lineup, 'BE')
|
||||
})
|
||||
return result
|
||||
|
||||
|
||||
def write_to_google_spreadsheet(df: pd.DataFrame):
|
||||
spreadsheet = gc.open_by_key(cfg.SPREADSHEET_ID)
|
||||
spreadsheet = gc.open_by_key(str(cfg.SPREADSHEET_ID))
|
||||
worksheet = spreadsheet.worksheet("FantasyData")
|
||||
set_with_dataframe(worksheet, df)
|
||||
|
||||
|
||||
@huey.periodic_task(crontab(hour='6'))
|
||||
def process_daily_report():
|
||||
league = League(league_id=cfg.LEAGUE_ID,
|
||||
year=datetime.now().year,
|
||||
espn_s2=cfg.ESPN_S2,
|
||||
swid=cfg.SWID,
|
||||
fetch_league=cfg.FETCH_LEAGUE)
|
||||
|
||||
matchup = extract_matchup_box_scores(league=league)
|
||||
df = pd.DataFrame.from_dict(matchup)
|
||||
print(tabulate(df, headers='keys', tablefmt='psql', showindex=False))
|
||||
matchup = extract_weekly_box_scores(league=league)
|
||||
df = pd.DataFrame(matchup)
|
||||
print(tabulate(df, headers='keys', tablefmt='psql', showindex=False)) # pyright: ignore[reportArgumentType]
|
||||
write_to_google_spreadsheet(df=df)
|
||||
|
||||
|
||||
process_daily_report()
|
||||
27
config.py
27
config.py
|
|
@ -6,16 +6,27 @@ load_dotenv()
|
|||
|
||||
|
||||
def str2bool(v):
|
||||
return v.lower() in ("yes", "true", "t", "1")
|
||||
return v.lower() in ("yes", "true", "t", "1", "on")
|
||||
|
||||
|
||||
class Config():
|
||||
ESPN_S2 = getenv("ESPN_S2")
|
||||
LEAGUE_ID = getenv("LEAGUE_ID")
|
||||
SWID = getenv("SWID")
|
||||
FETCH_LEAGUE = str2bool(getenv("FETCH_LEAGUE"))
|
||||
SPREADSHEET_ID = getenv("SPREADSHEET_ID")
|
||||
WORKSHEET_NAME = getenv("WORKSHEET_NAME")
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.ESPN_S2 = getenv("ESPN_S2", 0)
|
||||
self.LEAGUE_ID = int(getenv("LEAGUE_ID", 0))
|
||||
self.SWID = getenv("SWID", 0)
|
||||
self.FETCH_LEAGUE = str2bool(getenv("FETCH_LEAGUE", 0))
|
||||
self.SPREADSHEET_ID = getenv("SPREADSHEET_ID", 0)
|
||||
self.SHEET_NAME = getenv("WORKSHEET_NAME", 0)
|
||||
self.check_values()
|
||||
|
||||
def check_values(self):
|
||||
for attribute, value in self.__dict__.items():
|
||||
if value == 0:
|
||||
raise Exception("ERROR: Unproperly set environment variable {attribute}, please review".format(attribute=attribute))
|
||||
|
||||
|
||||
cfg = Config()
|
||||
try:
|
||||
cfg = Config()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
-e git+https://github.com/cwendt94/espn-api@8e131e7ccaa843abac539948c44f9d45bfcee764#egg=espn_api
|
||||
-e git+https://github.com/cwendt94/espn-api#egg=espn_api
|
||||
google-auth-oauthlib==1.2.1
|
||||
gspread==6.1.2
|
||||
gspread-dataframe==4.0.0
|
||||
huey==2.5.2
|
||||
pandas==2.2.3
|
||||
python-dotenv==1.0.1
|
||||
redis==5.1.0
|
||||
tabulate==0.9.0
|
||||
|
|
|
|||
172
wip.ipynb
172
wip.ipynb
|
|
@ -1,172 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from argparse import ArgumentParser\n",
|
||||
"from config import Config as cfg\n",
|
||||
"from datetime import datetime\n",
|
||||
"from espn_api.football import League\n",
|
||||
"from gspread_dataframe import get_as_dataframe, set_with_dataframe\n",
|
||||
"from service import gc\n",
|
||||
"from time import strftime\n",
|
||||
"\n",
|
||||
"import pandas as pd\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def check_int(s):\n",
|
||||
" if s is None:\n",
|
||||
" return s\n",
|
||||
" if s[0] in ('-', '+'):\n",
|
||||
" return s[1:].isdigit()\n",
|
||||
" return s.isdigit()\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def extract_positional_data(lineup: list, position: str) -> int:\n",
|
||||
" response = 0\n",
|
||||
" for player in lineup:\n",
|
||||
" if player.lineupSlot == position:\n",
|
||||
" response = response + player.points\n",
|
||||
" return response\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def extract_matchup_box_scores(league: League) -> dict:\n",
|
||||
" result = []\n",
|
||||
" for week in range(1, league.current_week + 1):\n",
|
||||
" matchups = league.box_scores(week=week)\n",
|
||||
" for matchup in matchups:\n",
|
||||
" result.append({\n",
|
||||
" 'WEEK #': week,\n",
|
||||
" 'AWAY TEAM': matchup.away_team.team_name,\n",
|
||||
" 'AWAY TEAM SCORE': matchup.away_score,\n",
|
||||
" 'AWAY TEAM KICKER': extract_positional_data(matchup.away_lineup, 'K'),\n",
|
||||
" 'AWAY TEAM BENCH': extract_positional_data(matchup.away_lineup, 'BE'),\n",
|
||||
" 'HOME TEAM': matchup.home_team.team_name,\n",
|
||||
" 'HOME TEAM SCORE': matchup.home_score,\n",
|
||||
" 'HOME TEAM KICKER': extract_positional_data(matchup.home_lineup, 'K'),\n",
|
||||
" 'HOME TEAM BENCH': extract_positional_data(matchup.home_lineup, 'BE')\n",
|
||||
" })\n",
|
||||
" return result\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def write_to_google_spreadsheet(df: pd.DataFrame):\n",
|
||||
" spreadsheet = gc.open_by_key(cfg.SPREADSHEET_ID)\n",
|
||||
" worksheet = spreadsheet.worksheet(\"FantasyData\")\n",
|
||||
" set_with_dataframe(worksheet, df)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"league = League(league_id=cfg.LEAGUE_ID, \n",
|
||||
" year=datetime.now().year, \n",
|
||||
" espn_s2=cfg.ESPN_S2, \n",
|
||||
" swid=cfg.SWID, \n",
|
||||
" fetch_league=cfg.FETCH_LEAGUE)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"matchup = extract_matchup_box_scores(league=league)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.DataFrame.from_dict(matchup) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#spreadsheet = gc.open_by_key(cfg.SPREADSHEET_ID)\n",
|
||||
"spreadsheet = gc.open_by_key('1vBtceabKqc0QAs7MOgeg-q0FSHXIbNf31B8XEgzy6s8')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"worksheet = spreadsheet.worksheet(\"FantasyData\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"set_with_dataframe(worksheet, df)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def next_available_row(worksheet):\n",
|
||||
" str_list = list(filter(None, worksheet.col_values(1)))\n",
|
||||
" return str(len(str_list)+1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'7'"
|
||||
]
|
||||
},
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"next_available_row(worksheet=worksheet)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python",
|
||||
"version": "3.10.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
Loading…
Reference in a new issue