66import 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
8489def 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