Skip to content

Commit ac89e0b

Browse files
committed
Revised github action
1 parent a2ed905 commit ac89e0b

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

.github/workflows/load-weekly-data.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ on:
1111
description: "Week number (leave blank for all)"
1212
required: false
1313
default: ""
14+
allow_empty:
15+
description: "Succeed with empty CSV if data not yet published"
16+
required: false
17+
type: boolean
18+
default: false
1419
schedule:
1520
- cron: '0 10 * * TUE'
1621

@@ -45,6 +50,10 @@ jobs:
4550
ARGS=( )
4651
if [ -n "${{ inputs.season }}" ]; then ARGS+=(--season "${{ inputs.season }}"); fi
4752
if [ -n "${{ inputs.week }}" ]; then ARGS+=(--week "${{ inputs.week }}"); fi
53+
# Auto-allow empty results on scheduled runs, or if user requested it
54+
if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ inputs.allow_empty }}" = "true" ]; then
55+
ARGS+=(--allow-empty)
56+
fi
4857
python scripts/load_weekly_data.py "${ARGS[@]}" --output nfl_weekly_stats.csv
4958
5059
- name: Upload CSV artifact

scripts/load_weekly_data.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import typer
77

88

9-
def _resolve_weekly_loader() -> Callable[[int], pd.DataFrame]:
9+
def _resolve_weekly_loader() -> tuple[str, str, Callable[[int], pd.DataFrame]]:
1010
# Prefer nflreadpy, fallback to nfl_data_py for compatibility
1111
try:
1212
import nflreadpy as nfr # type: ignore
@@ -21,7 +21,7 @@ def _load(season: int, _func=func):
2121
return _func(years=[season])
2222
except TypeError:
2323
return _func(season)
24-
return _load
24+
return ("nflreadpy", name, _load)
2525
raise ImportError("nflreadpy found but no weekly import function detected")
2626
except Exception:
2727
pass
@@ -32,14 +32,14 @@ def _load(season: int, _func=func):
3232
def _load(season: int):
3333
return ndp.import_weekly_data(years=[season])
3434

35-
return _load
35+
return ("nfl_data_py", "import_weekly_data", _load)
3636
except Exception as exc:
3737
raise RuntimeError(
3838
"No data provider available. Install nflreadpy or nfl_data_py."
3939
) from exc
4040

4141

42-
def _resolve_schedule_loader() -> Callable[[int], pd.DataFrame]:
42+
def _resolve_schedule_loader() -> tuple[str, str, Callable[[int], pd.DataFrame]]:
4343
# Prefer nflreadpy, fallback to nfl_data_py
4444
try:
4545
import nflreadpy as nfr # type: ignore
@@ -52,7 +52,7 @@ def _load(season: int, _func=func):
5252
return _func(years=[season])
5353
except TypeError:
5454
return _func(season)
55-
return _load
55+
return ("nflreadpy", name, _load)
5656
raise ImportError("nflreadpy found but no schedule import function detected")
5757
except Exception:
5858
pass
@@ -63,36 +63,39 @@ def _load(season: int, _func=func):
6363
def _load(season: int):
6464
return ndp.import_schedules([season])
6565

66-
return _load
66+
return ("nfl_data_py", "import_schedules", _load)
6767
except Exception as exc:
6868
raise RuntimeError(
6969
"No schedule provider available. Install nflreadpy or nfl_data_py."
7070
) from exc
7171

7272

73-
def load_weekly(season: int, week: Optional[int] = None) -> pd.DataFrame:
74-
load = _resolve_weekly_loader()
73+
def load_weekly(season: int, week: Optional[int] = None, verbose: bool = False) -> pd.DataFrame:
74+
provider, func_name, load = _resolve_weekly_loader()
7575
df = load(season)
76+
if verbose:
77+
print(f"Provider={provider} func={func_name} rows={len(df)} cols={list(df.columns)[:8]}...")
7678
# Ensure expected basic columns exist; nfl_data_py schema may evolve
77-
if week is not None:
78-
df = df[df["week"] == week]
79+
# Normalize week to numeric for robust filtering
80+
if "week" in df.columns:
81+
df["week"] = pd.to_numeric(df["week"], errors="coerce")
82+
if week is not None and "week" in df.columns:
83+
df = df[df["week"] == int(week)]
7984
# Normalize column names (lower_snake)
8085
df.columns = [str(c).strip().replace(" ", "_").lower() for c in df.columns]
8186
return df.reset_index(drop=True)
8287

8388

8489
def describe_availability(season: int) -> str:
8590
try:
86-
load_sched = _resolve_schedule_loader()
91+
provider, func_name, load_sched = _resolve_schedule_loader()
8792
sched = load_sched(season)
8893
if sched is None or len(sched) == 0:
8994
return f"No schedule available for season {season}."
9095
weeks = sorted(set(sched["week"].dropna().astype(int)))
9196
min_w, max_w = (min(weeks), max(weeks)) if weeks else (None, None)
92-
return (
93-
f"Season {season} schedule weeks: {weeks if weeks else 'unknown'}. "
94-
+ (f"Min={min_w} Max={max_w}" if weeks else "")
95-
)
97+
return (f"Season {season} schedule weeks: {weeks if weeks else 'unknown'}; "
98+
f"min={min_w} max={max_w}; provider={provider}.{func_name}")
9699
except Exception as _:
97100
return f"Could not determine schedule for season {season}."
98101

@@ -104,6 +107,7 @@ def main(
104107
allow_empty: bool = typer.Option(
105108
False, help="Allow empty result without failing (writes empty CSV)"
106109
),
110+
verbose: bool = typer.Option(False, help="Print provider and basic diagnostics"),
107111
):
108112
# Fallback to environment if CLI not provided
109113
if season is None:
@@ -127,7 +131,7 @@ def main(
127131
week = None
128132

129133
try:
130-
df = load_weekly(season, week)
134+
df = load_weekly(season, week, verbose=verbose)
131135
except Exception as exc:
132136
hint = describe_availability(season)
133137
msg = (

0 commit comments

Comments
 (0)