Jon Solow commited on
Commit
ac8c5cd
1 Parent(s): 79c1f5e

Add practice reports queries and libraries

Browse files
dev-requirements.txt CHANGED
@@ -6,12 +6,16 @@
6
  #
7
  altair==5.0.1
8
  # via streamlit
 
 
9
  anyio==3.7.1
10
  # via httpcore
11
  attrs==23.1.0
12
  # via
13
  # jsonschema
14
  # referencing
 
 
15
  black==23.7.0
16
  # via YFDashboard (pyproject.toml)
17
  blinker==1.6.2
@@ -35,6 +39,8 @@ gitpython==3.1.34
35
  # via streamlit
36
  h11==0.14.0
37
  # via httpcore
 
 
38
  httpcore==0.17.3
39
  # via httpx
40
  httpx==0.24.1
@@ -58,6 +64,10 @@ jsonschema==4.19.0
58
  # via altair
59
  jsonschema-specifications==2023.7.1
60
  # via jsonschema
 
 
 
 
61
  markdown-it-py==3.0.0
62
  # via rich
63
  markupsafe==2.1.3
@@ -103,6 +113,10 @@ protobuf==4.24.0
103
  # via streamlit
104
  pyarrow==12.0.1
105
  # via streamlit
 
 
 
 
106
  pydeck==0.8.0
107
  # via streamlit
108
  pygments==2.16.1
@@ -134,7 +148,9 @@ rpds-py==0.9.2
134
  ruff==0.0.284
135
  # via YFDashboard (pyproject.toml)
136
  six==1.16.0
137
- # via python-dateutil
 
 
138
  smmap==5.0.0
139
  # via gitdb
140
  sniffio==1.3.0
@@ -142,6 +158,8 @@ sniffio==1.3.0
142
  # anyio
143
  # httpcore
144
  # httpx
 
 
145
  streamlit==1.25.0
146
  # via
147
  # YFDashboard (pyproject.toml)
@@ -158,9 +176,15 @@ tornado==6.3.3
158
  # via streamlit
159
  types-pytz==2023.3.0.1
160
  # via pandas-stubs
 
 
 
 
161
  typing-extensions==4.7.1
162
  # via
163
  # mypy
 
 
164
  # streamlit
165
  tzdata==2023.3
166
  # via
@@ -174,5 +198,7 @@ validators==0.21.2
174
  # via streamlit
175
  watchdog==3.0.0
176
  # via streamlit
 
 
177
  zipp==3.16.2
178
  # via importlib-metadata
 
6
  #
7
  altair==5.0.1
8
  # via streamlit
9
+ annotated-types==0.5.0
10
+ # via pydantic
11
  anyio==3.7.1
12
  # via httpcore
13
  attrs==23.1.0
14
  # via
15
  # jsonschema
16
  # referencing
17
+ beautifulsoup4==4.12.2
18
+ # via YFDashboard (pyproject.toml)
19
  black==23.7.0
20
  # via YFDashboard (pyproject.toml)
21
  blinker==1.6.2
 
39
  # via streamlit
40
  h11==0.14.0
41
  # via httpcore
42
+ html5lib==1.1
43
+ # via YFDashboard (pyproject.toml)
44
  httpcore==0.17.3
45
  # via httpx
46
  httpx==0.24.1
 
64
  # via altair
65
  jsonschema-specifications==2023.7.1
66
  # via jsonschema
67
+ lxml==4.9.3
68
+ # via YFDashboard (pyproject.toml)
69
+ lxml-stubs==0.4.0
70
+ # via YFDashboard (pyproject.toml)
71
  markdown-it-py==3.0.0
72
  # via rich
73
  markupsafe==2.1.3
 
113
  # via streamlit
114
  pyarrow==12.0.1
115
  # via streamlit
116
+ pydantic==2.3.0
117
+ # via YFDashboard (pyproject.toml)
118
+ pydantic-core==2.6.3
119
+ # via pydantic
120
  pydeck==0.8.0
121
  # via streamlit
122
  pygments==2.16.1
 
148
  ruff==0.0.284
149
  # via YFDashboard (pyproject.toml)
150
  six==1.16.0
151
+ # via
152
+ # html5lib
153
+ # python-dateutil
154
  smmap==5.0.0
155
  # via gitdb
156
  sniffio==1.3.0
 
158
  # anyio
159
  # httpcore
160
  # httpx
161
+ soupsieve==2.5
162
+ # via beautifulsoup4
163
  streamlit==1.25.0
164
  # via
165
  # YFDashboard (pyproject.toml)
 
176
  # via streamlit
177
  types-pytz==2023.3.0.1
178
  # via pandas-stubs
179
+ types-requests==2.31.0.2
180
+ # via YFDashboard (pyproject.toml)
181
+ types-urllib3==1.26.25.14
182
+ # via types-requests
183
  typing-extensions==4.7.1
184
  # via
185
  # mypy
186
+ # pydantic
187
+ # pydantic-core
188
  # streamlit
189
  tzdata==2023.3
190
  # via
 
198
  # via streamlit
199
  watchdog==3.0.0
200
  # via streamlit
201
+ webencodings==0.5.1
202
+ # via html5lib
203
  zipp==3.16.2
204
  # via importlib-metadata
pyproject.toml CHANGED
@@ -7,8 +7,12 @@ version = "1"
7
  name = "YFDashboard"
8
  dependencies = [
9
  "streamlit",
 
 
 
10
  "numpy",
11
  "pandas",
 
12
  "streamlit-oauth",
13
  ]
14
 
@@ -16,9 +20,11 @@ dependencies = [
16
  dev = [
17
  "black",
18
  "ruff",
 
19
  "mypy",
20
  "pytest",
21
  "pandas-stubs",
 
22
  ]
23
 
24
  [tool.black]
 
7
  name = "YFDashboard"
8
  dependencies = [
9
  "streamlit",
10
+ "beautifulsoup4",
11
+ "html5lib",
12
+ "lxml",
13
  "numpy",
14
  "pandas",
15
+ "pydantic",
16
  "streamlit-oauth",
17
  ]
18
 
 
20
  dev = [
21
  "black",
22
  "ruff",
23
+ "lxml-stubs",
24
  "mypy",
25
  "pytest",
26
  "pandas-stubs",
27
+ "types-requests",
28
  ]
29
 
30
  [tool.black]
requirements.txt CHANGED
@@ -6,12 +6,16 @@
6
  #
7
  altair==5.0.1
8
  # via streamlit
 
 
9
  anyio==3.7.1
10
  # via httpcore
11
  attrs==23.1.0
12
  # via
13
  # jsonschema
14
  # referencing
 
 
15
  blinker==1.6.2
16
  # via streamlit
17
  cachetools==5.3.1
@@ -31,6 +35,8 @@ gitpython==3.1.34
31
  # via streamlit
32
  h11==0.14.0
33
  # via httpcore
 
 
34
  httpcore==0.17.3
35
  # via httpx
36
  httpx==0.24.1
@@ -52,6 +58,8 @@ jsonschema==4.19.0
52
  # via altair
53
  jsonschema-specifications==2023.7.1
54
  # via jsonschema
 
 
55
  markdown-it-py==3.0.0
56
  # via rich
57
  markupsafe==2.1.3
@@ -79,6 +87,10 @@ protobuf==4.24.0
79
  # via streamlit
80
  pyarrow==12.0.1
81
  # via streamlit
 
 
 
 
82
  pydeck==0.8.0
83
  # via streamlit
84
  pygments==2.16.1
@@ -106,7 +118,9 @@ rpds-py==0.9.2
106
  # jsonschema
107
  # referencing
108
  six==1.16.0
109
- # via python-dateutil
 
 
110
  smmap==5.0.0
111
  # via gitdb
112
  sniffio==1.3.0
@@ -114,6 +128,8 @@ sniffio==1.3.0
114
  # anyio
115
  # httpcore
116
  # httpx
 
 
117
  streamlit==1.25.0
118
  # via
119
  # YFDashboard (pyproject.toml)
@@ -129,7 +145,10 @@ toolz==0.12.0
129
  tornado==6.3.3
130
  # via streamlit
131
  typing-extensions==4.7.1
132
- # via streamlit
 
 
 
133
  tzdata==2023.3
134
  # via
135
  # pandas
@@ -142,5 +161,7 @@ validators==0.21.2
142
  # via streamlit
143
  watchdog==3.0.0
144
  # via streamlit
 
 
145
  zipp==3.16.2
146
  # via importlib-metadata
 
6
  #
7
  altair==5.0.1
8
  # via streamlit
9
+ annotated-types==0.5.0
10
+ # via pydantic
11
  anyio==3.7.1
12
  # via httpcore
13
  attrs==23.1.0
14
  # via
15
  # jsonschema
16
  # referencing
17
+ beautifulsoup4==4.12.2
18
+ # via YFDashboard (pyproject.toml)
19
  blinker==1.6.2
20
  # via streamlit
21
  cachetools==5.3.1
 
35
  # via streamlit
36
  h11==0.14.0
37
  # via httpcore
38
+ html5lib==1.1
39
+ # via YFDashboard (pyproject.toml)
40
  httpcore==0.17.3
41
  # via httpx
42
  httpx==0.24.1
 
58
  # via altair
59
  jsonschema-specifications==2023.7.1
60
  # via jsonschema
61
+ lxml==4.9.3
62
+ # via YFDashboard (pyproject.toml)
63
  markdown-it-py==3.0.0
64
  # via rich
65
  markupsafe==2.1.3
 
87
  # via streamlit
88
  pyarrow==12.0.1
89
  # via streamlit
90
+ pydantic==2.3.0
91
+ # via YFDashboard (pyproject.toml)
92
+ pydantic-core==2.6.3
93
+ # via pydantic
94
  pydeck==0.8.0
95
  # via streamlit
96
  pygments==2.16.1
 
118
  # jsonschema
119
  # referencing
120
  six==1.16.0
121
+ # via
122
+ # html5lib
123
+ # python-dateutil
124
  smmap==5.0.0
125
  # via gitdb
126
  sniffio==1.3.0
 
128
  # anyio
129
  # httpcore
130
  # httpx
131
+ soupsieve==2.5
132
+ # via beautifulsoup4
133
  streamlit==1.25.0
134
  # via
135
  # YFDashboard (pyproject.toml)
 
145
  tornado==6.3.3
146
  # via streamlit
147
  typing-extensions==4.7.1
148
+ # via
149
+ # pydantic
150
+ # pydantic-core
151
+ # streamlit
152
  tzdata==2023.3
153
  # via
154
  # pandas
 
161
  # via streamlit
162
  watchdog==3.0.0
163
  # via streamlit
164
+ webencodings==0.5.1
165
+ # via html5lib
166
  zipp==3.16.2
167
  # via importlib-metadata
src/domain/__init__.py ADDED
File without changes
src/domain/conferences.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from typing import List
3
+
4
+
5
+ @dataclass
6
+ class NFLConference:
7
+ name: str
8
+ short_name: str
9
+
10
+ def __post_init__(self):
11
+ ALL_CONFERENCES.append(self)
12
+
13
+
14
+ ALL_CONFERENCES: List[NFLConference] = []
15
+
16
+ NFC = NFLConference(name="National Football Conference", short_name="NFC")
17
+ AFC = NFLConference(name="American Football Conference", short_name="AFC")
src/domain/divisions.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from typing import List
3
+ from domain import conferences
4
+
5
+
6
+ @dataclass
7
+ class NFLDivision:
8
+ name: str
9
+ conference: conferences.NFLConference
10
+
11
+ def __post_init__(self):
12
+ ALL_DIVISIONS.append(self)
13
+
14
+
15
+ ALL_DIVISIONS: List[NFLDivision] = []
16
+
17
+ NFCWest = NFLDivision(name="NFC West", conference=conferences.NFC)
18
+ NFCNorth = NFLDivision(name="NFC North", conference=conferences.NFC)
19
+ NFCSouth = NFLDivision(name="NFC South", conference=conferences.NFC)
20
+ NFCEast = NFLDivision(name="NFC East", conference=conferences.NFC)
21
+ AFCWest = NFLDivision(name="AFC West", conference=conferences.AFC)
22
+ AFCNorth = NFLDivision(name="AFC North", conference=conferences.AFC)
23
+ AFCSouth = NFLDivision(name="AFC South", conference=conferences.AFC)
24
+ AFCEast = NFLDivision(name="AFC East", conference=conferences.AFC)
src/domain/teams.py ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from urllib.parse import urljoin
3
+ from typing import List
4
+ from domain.conferences import NFLConference
5
+ from domain import divisions
6
+
7
+
8
+ @dataclass
9
+ class NFLTeam:
10
+ team_name: str
11
+ team_short_name: str
12
+ city: str
13
+ division: divisions.NFLDivision
14
+ footballguys_short_name: str = ""
15
+ url: str = ""
16
+ injury_report_suffix: str = "/team/injury-report/"
17
+
18
+ def __post_init__(self):
19
+ self.footballguys_short_name = (
20
+ self.team_short_name if self.footballguys_short_name == "" else self.footballguys_short_name
21
+ )
22
+ self.conference: NFLConference = self.division.conference
23
+ self.injury_report_url = urljoin(self.url, self.injury_report_suffix)
24
+ self.team_full_name = " ".join([self.city, self.team_name])
25
+
26
+ ALL_TEAMS.append(self)
27
+
28
+
29
+ ALL_TEAMS: List[NFLTeam] = []
30
+
31
+
32
+ arizona_cardinals = NFLTeam(
33
+ team_name="Cardinals",
34
+ team_short_name="ARI",
35
+ city="Arizona",
36
+ division=divisions.NFCWest,
37
+ url="https://www.azcardinals.com/",
38
+ )
39
+
40
+ atlanta_falcons = NFLTeam(
41
+ team_name="Falcons",
42
+ team_short_name="ATL",
43
+ city="Atlanta",
44
+ division=divisions.NFCSouth,
45
+ url="https://www.atlantafalcons.com/",
46
+ )
47
+
48
+ baltimore_ravens = NFLTeam(
49
+ team_name="Ravens",
50
+ team_short_name="BAL",
51
+ city="Baltimore",
52
+ division=divisions.AFCNorth,
53
+ url="https://www.baltimoreravens.com/",
54
+ )
55
+
56
+ buffalo_bills = NFLTeam(
57
+ team_name="Bills",
58
+ team_short_name="BUF",
59
+ city="Buffalo",
60
+ division=divisions.AFCEast,
61
+ url="https://www.buffalobills.com/",
62
+ )
63
+
64
+ carolina_panthers = NFLTeam(
65
+ team_name="Panthers",
66
+ team_short_name="CAR",
67
+ city="Carolina",
68
+ division=divisions.NFCSouth,
69
+ url="https://www.panthers.com/",
70
+ )
71
+
72
+ chicago_bears = NFLTeam(
73
+ team_name="Bears",
74
+ team_short_name="CHI",
75
+ city="Chicago",
76
+ division=divisions.NFCNorth,
77
+ url="https://www.chicagobears.com/",
78
+ )
79
+
80
+ cincinnati_bengals = NFLTeam(
81
+ team_name="Bengals",
82
+ team_short_name="CIN",
83
+ city="Cincinnati",
84
+ division=divisions.AFCNorth,
85
+ url="https://www.bengals.com/",
86
+ )
87
+
88
+ cleveland_browns = NFLTeam(
89
+ team_name="Browns",
90
+ team_short_name="CLE",
91
+ city="Cleveland",
92
+ division=divisions.AFCNorth,
93
+ url="https://www.clevelandbrowns.com/",
94
+ )
95
+
96
+ dallas_cowboys = NFLTeam(
97
+ team_name="Cowboys",
98
+ team_short_name="DAL",
99
+ city="Dallas",
100
+ division=divisions.NFCEast,
101
+ url="https://www.dallascowboys.com/",
102
+ )
103
+
104
+ denver_broncos = NFLTeam(
105
+ team_name="Broncos",
106
+ team_short_name="DEN",
107
+ city="Denver",
108
+ division=divisions.AFCWest,
109
+ url="https://www.denverbroncos.com/",
110
+ )
111
+
112
+ detroit_lions = NFLTeam(
113
+ team_name="Lions",
114
+ team_short_name="DET",
115
+ city="Detroit",
116
+ division=divisions.NFCNorth,
117
+ url="https://www.detroitlions.com/",
118
+ )
119
+
120
+ green_bay_packers = NFLTeam(
121
+ team_name="Packers",
122
+ team_short_name="GB",
123
+ city="Green Bay",
124
+ division=divisions.NFCNorth,
125
+ url="https://www.packers.com/",
126
+ )
127
+
128
+ houston_texans = NFLTeam(
129
+ team_name="Texans",
130
+ team_short_name="HOU",
131
+ city="Houston",
132
+ division=divisions.AFCSouth,
133
+ url="https://www.houstontexans.com/",
134
+ )
135
+
136
+ indianapolis_colts = NFLTeam(
137
+ city="Indianapolis",
138
+ team_name="Colts",
139
+ team_short_name="IND",
140
+ division=divisions.AFCSouth,
141
+ url="https://www.colts.com/",
142
+ )
143
+
144
+ jacksonville_jaguars = NFLTeam(
145
+ city="Jacksonville",
146
+ team_name="Jaguars",
147
+ team_short_name="JAX",
148
+ division=divisions.AFCSouth,
149
+ url="https://www.jaguars.com/",
150
+ )
151
+
152
+ kansas_city_chiefs = NFLTeam(
153
+ city="Kansas City",
154
+ team_name="Chiefs",
155
+ team_short_name="KC",
156
+ division=divisions.AFCWest,
157
+ url="https://www.chiefs.com/",
158
+ )
159
+
160
+ las_vegas_raiders = NFLTeam(
161
+ city="Las Vegas",
162
+ team_name="Raiders",
163
+ team_short_name="LV",
164
+ division=divisions.AFCWest,
165
+ url="https://www.raiders.com/",
166
+ )
167
+
168
+ los_angeles_chargers = NFLTeam(
169
+ city="Los Angeles",
170
+ team_name="Chargers",
171
+ team_short_name="LAC",
172
+ division=divisions.AFCWest,
173
+ url="https://www.chargers.com/",
174
+ )
175
+
176
+ los_angeles_rams = NFLTeam(
177
+ city="Los Angeles",
178
+ team_name="Rams",
179
+ team_short_name="LAR",
180
+ division=divisions.NFCWest,
181
+ url="https://www.therams.com/",
182
+ )
183
+
184
+ miami_dolphins = NFLTeam(
185
+ city="Miami",
186
+ team_name="Dolphins",
187
+ team_short_name="MIA",
188
+ division=divisions.AFCEast,
189
+ url="https://www.miamidolphins.com/",
190
+ )
191
+
192
+ minnesota_vikings = NFLTeam(
193
+ city="Minnesota",
194
+ team_name="Vikings",
195
+ team_short_name="MIN",
196
+ division=divisions.NFCNorth,
197
+ url="https://www.vikings.com/",
198
+ )
199
+
200
+ new_england_patriots = NFLTeam(
201
+ city="New England",
202
+ team_name="Patriots",
203
+ team_short_name="NE",
204
+ division=divisions.AFCEast,
205
+ url="https://www.patriots.com/",
206
+ )
207
+
208
+ new_orleans_saints = NFLTeam(
209
+ city="New Orleans",
210
+ team_name="Saints",
211
+ team_short_name="NO",
212
+ division=divisions.NFCSouth,
213
+ url="https://www.neworleanssaints.com/",
214
+ )
215
+
216
+ new_york_giants = NFLTeam(
217
+ city="New York",
218
+ team_name="Giants",
219
+ team_short_name="NYG",
220
+ division=divisions.NFCEast,
221
+ url="https://www.giants.com/",
222
+ )
223
+
224
+ new_york_jets = NFLTeam(
225
+ city="New York",
226
+ team_name="Jets",
227
+ team_short_name="NYJ",
228
+ division=divisions.AFCEast,
229
+ url="https://www.newyorkjets.com/",
230
+ )
231
+
232
+ philadelphia_eagles = NFLTeam(
233
+ city="Philadelphia",
234
+ team_name="Eagles",
235
+ team_short_name="PHI",
236
+ division=divisions.NFCEast,
237
+ url="https://www.philadelphiaeagles.com/",
238
+ )
239
+
240
+ pittsburgh_steelers = NFLTeam(
241
+ city="Pittsburgh",
242
+ team_name="Steelers",
243
+ team_short_name="PIT",
244
+ division=divisions.AFCNorth,
245
+ url="https://www.steelers.com/",
246
+ )
247
+
248
+ san_francisco_49ers = NFLTeam(
249
+ city="San Francisco",
250
+ team_name="49ers",
251
+ team_short_name="SF",
252
+ division=divisions.NFCWest,
253
+ url="https://www.49ers.com/",
254
+ )
255
+
256
+ seattle_seahawks = NFLTeam(
257
+ city="Seattle",
258
+ team_name="Seahawks",
259
+ team_short_name="SEA",
260
+ division=divisions.NFCWest,
261
+ url="https://www.seahawks.com/",
262
+ )
263
+
264
+ tampa_bay_buccaneers = NFLTeam(
265
+ city="Tampa Bay",
266
+ team_name="Buccaneers",
267
+ team_short_name="TB",
268
+ division=divisions.NFCSouth,
269
+ url="https://www.buccaneers.com/",
270
+ )
271
+
272
+ tennessee_titans = NFLTeam(
273
+ city="Tennessee",
274
+ team_name="Titans",
275
+ team_short_name="TEN",
276
+ division=divisions.AFCSouth,
277
+ url="https://www.tennesseetitans.com/",
278
+ )
279
+
280
+ washington_football_team = NFLTeam(
281
+ city="Washington",
282
+ team_name="Commanders",
283
+ team_short_name="WAS",
284
+ division=divisions.NFCEast,
285
+ url="https://www.commanders.com/",
286
+ )
src/queries/__init__.py ADDED
File without changes
src/queries/nfl_teams/__init__.py ADDED
File without changes
src/queries/nfl_teams/practice_reports.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import datetime
2
+ from multiprocessing import Pool
3
+ import numpy as np
4
+ import pandas as pd
5
+ from pydantic import BaseModel, Field
6
+ from typing import Optional
7
+ from urllib.parse import urljoin
8
+
9
+ from domain.teams import ALL_TEAMS, NFLTeam
10
+
11
+
12
+ MULTIPROCESSING_ENABLED = False
13
+
14
+ PRACTICE_WEEK = {
15
+ "Mon": 0,
16
+ "Tue": 1,
17
+ "Wed": 2,
18
+ "Thu": 3,
19
+ "Fri": 4,
20
+ "Sat": 5,
21
+ "Sun": 6,
22
+ "Monday": 0,
23
+ "Tuesday": 1,
24
+ "Wednesday": 2,
25
+ "Thursday": 3,
26
+ "Friday": 4,
27
+ "Saturday": 5,
28
+ "Sunday": 6,
29
+ }
30
+
31
+
32
+ DAY_OF_WEEK_STRING_MAPPING = {
33
+ "Monday": "Mon",
34
+ "Tuesday": "Tue",
35
+ "Wednesday": "Wed",
36
+ "Thursday": "Thu",
37
+ "Friday": "Fri",
38
+ "Saturday": "Sat",
39
+ "Sunday": "Sun",
40
+ }
41
+
42
+
43
+ WEEK_1_BEGIN_DATE = datetime.datetime(2023, 9, 4)
44
+ CURRENT_DATE = datetime.datetime.now()
45
+ CURRENT_WEEK = max(1, int(1 + (CURRENT_DATE - WEEK_1_BEGIN_DATE).days / 7))
46
+
47
+
48
+ class PracticeReportRawRow(BaseModel):
49
+ Team: str
50
+ Player: str
51
+ Position: str
52
+ Injury: str
53
+ Sun: Optional[str] = None
54
+ Mon: Optional[str] = None
55
+ Tue: Optional[str] = None
56
+ Wed: Optional[str] = None
57
+ Thu: Optional[str] = None
58
+ Fri: Optional[str] = None
59
+ Sat: Optional[str] = None
60
+ game_status: str = Field(alias="Game Status")
61
+
62
+ @classmethod
63
+ def replace_nan(self, value) -> str:
64
+ if isinstance(value, float):
65
+ if np.isnan(value):
66
+ return ""
67
+ return value
68
+
69
+ @classmethod
70
+ def from_raw(cls, input_dict) -> "PracticeReportRawRow":
71
+ return cls(**{DAY_OF_WEEK_STRING_MAPPING.get(k, k): cls.replace_nan(v) for k, v in input_dict.items()})
72
+
73
+
74
+ def scrape_team_injury_report(team: NFLTeam) -> pd.DataFrame:
75
+ print(f"Scraping Injury Report for: {team.team_full_name}")
76
+ injury_report_url = urljoin(team.injury_report_url, f"week/REG-{CURRENT_WEEK}")
77
+ team_report = pd.read_html(injury_report_url)[0]
78
+ try:
79
+ team_report = pd.read_html(injury_report_url)[0]
80
+ except Exception:
81
+ print(f"Failed to scrape practice report for: {team.team_full_name}")
82
+ return pd.DataFrame()
83
+ validated_row_list = []
84
+ for df_row_dict in team_report.to_dict("records"):
85
+ row_to_add = df_row_dict
86
+ row_to_add["Team"] = team.team_full_name
87
+ validated_row_list.append(PracticeReportRawRow.from_raw(row_to_add))
88
+ validated_df = pd.DataFrame([x.dict() for x in validated_row_list])
89
+ # drop all na columns
90
+ validated_df.dropna(axis=1, how="all", inplace=True)
91
+ # replace day of week with practice day from 1-3
92
+ day_idx = 1
93
+ last_practice_day = None
94
+ for col in validated_df.columns:
95
+ if col in PRACTICE_WEEK:
96
+ validated_df.rename(columns={col: str(day_idx)}, inplace=True)
97
+ day_idx += 1
98
+ last_practice_day = col
99
+ validated_df["Last Practice Day"] = last_practice_day
100
+ return validated_df
101
+
102
+
103
+ def scrape_all_team_injury_report() -> pd.DataFrame:
104
+ if MULTIPROCESSING_ENABLED:
105
+ with Pool() as pool:
106
+ team_df_list = pool.map(scrape_team_injury_report, ALL_TEAMS)
107
+ else:
108
+ team_df_list = [scrape_team_injury_report(team) for team in ALL_TEAMS]
109
+ return pd.concat(team_df_list)