cfbd_json_py.rankings

  1# Creation Date: 08/30/2023 01:13 EDT
  2# Last Updated Date: 09/16/2024 06:10 PM EDT
  3# Author: Joseph Armstrong (armstrongjoseph08@gmail.com)
  4# File Name: rankings.py
  5# Purpose: Houses functions pertaining to CFB poll data within the CFBD API.
  6###############################################################################
  7
  8from datetime import datetime
  9
 10import pandas as pd
 11import requests
 12# from tqdm import tqdm
 13
 14from cfbd_json_py.utls import get_cfbd_api_token
 15
 16
 17def get_cfbd_poll_rankings(
 18    season: int,
 19    api_key: str = None,
 20    api_key_dir: str = None,
 21    week: int = None,
 22    season_type: str = "regular",  # "regular" or "postseason"
 23    return_as_dict: bool = False,
 24):
 25    """
 26    Allows you to get CFB poll rankings data from the CFBD API.
 27
 28    Parameters
 29    ----------
 30    `season` (int, mandatory):
 31        Required argument.
 32        Specifies the season you want CFB poll rankings data from.
 33        This must be specified, otherwise this package, and by extension
 34        the CFBD API, will not accept
 35        the request to get CFB poll rankings data.
 36
 37    `api_key` (str, optional):
 38        Semi-optional argument.
 39        If `api_key` is null, this function will attempt to load a CFBD API key
 40        from the python environment, or from a file on this computer.
 41        If `api_key` is not null,
 42        this function will automatically assume that the
 43        inputted `api_key` is a valid CFBD API key.
 44
 45    `api_key_dir` (str, optional):
 46        Optional argument.
 47        If `api_key` is set to am empty string, this variable is ignored.
 48        If `api_key_dir` is null, and `api_key` is null,
 49        this function will try to find
 50        a CFBD API key file in this user's home directory.
 51        If `api_key_dir` is set to a string, and `api_key` is null,
 52        this function will assume that `api_key_dir` is a directory,
 53        and will try to find a CFBD API key file in that directory.
 54
 55    `week` (int, optional):
 56        Optional argument.
 57        If `week` is set to an integer, this function will attempt
 58        to load CFB poll rankings data from games in that season,
 59        and in that week.
 60
 61    `season_type` (str, semi-optional):
 62        Semi-optional argument.
 63        By default, this will be set to "regular", for the CFB regular season.
 64        If you want CFB poll rankings data for non-regular season games,
 65        set `season_type` to "postseason".
 66        If `season_type` is set to anything but "regular" or "postseason",
 67        a `ValueError()` will be raised.
 68
 69    `return_as_dict` (bool, semi-optional):
 70        Semi-optional argument.
 71        If you want this function to return the data
 72        as a dictionary (read: JSON object),
 73        instead of a pandas `DataFrame` object,
 74        set `return_as_dict` to `True`.
 75
 76    Usage
 77    ----------
 78    ```
 79    import time
 80
 81    from cfbd_json_py.rankings import get_cfbd_poll_rankings
 82
 83
 84    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 85
 86    if cfbd_key != "tigersAreAwesome":
 87        print(
 88            "Using the user's API key declared in this " +
 89            "script for this example."
 90        )
 91
 92        # Get CFB poll data for the 2020 CFB season.
 93        print("Get CFB poll data for the 2020 CFB season.")
 94        json_data = get_cfbd_poll_rankings(
 95            api_key=cfbd_key,
 96            season=2020
 97        )
 98        print(json_data)
 99        time.sleep(5)
100
101        # Get CFB poll data from week 10 of the 2023 CFB season.
102        print("Get CFB poll data from week 10 of the 2023 CFB season.")
103        json_data = get_cfbd_poll_rankings(
104            api_key=cfbd_key,
105            season=2023,
106            week=10
107        )
108        print(json_data)
109        time.sleep(5)
110
111        # Get CFB poll data for the 2021 CFB season, during the postseason.
112        print(
113            "Get CFB poll data for the 2021 CFB season, during the postseason."
114        )
115        json_data = get_cfbd_poll_rankings(
116            api_key=cfbd_key,
117            season=2021,
118            season_type="postseason"
119        )
120        print(json_data)
121        time.sleep(5)
122
123        # You can also tell this function to just return the API call as
124        # a Dictionary (read: JSON) object.
125        print(
126            "You can also tell this function to just return the API call " +
127            "as a dictionary (read: JSON) object."
128        )
129        json_data = get_cfbd_poll_rankings(
130            api_key=cfbd_key,
131            season=2020,
132            week=10,
133            return_as_dict=True
134        )
135        print(json_data)
136
137    else:
138        # Alternatively, if the CFBD API key exists in this python environment,
139        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
140        # you could just call these functions directly,
141        # without setting the API key in the script.
142        print(
143            "Using the user's API key supposedly loaded into " +
144            "this python environment for this example."
145        )
146
147        # Get CFB poll data for the 2020 CFB season.
148        print("Get CFB poll data for the 2020 CFB season.")
149        json_data = get_cfbd_poll_rankings(
150            season=2020
151        )
152        print(json_data)
153        time.sleep(5)
154
155        # Get CFB poll data from week 10 of the 2023 CFB season.
156        print("Get CFB poll data from week 10 of the 2023 CFB season.")
157        json_data = get_cfbd_poll_rankings(
158            season=2023,
159            week=10
160        )
161        print(json_data)
162        time.sleep(5)
163
164        # Get CFB poll data for the 2021 CFB season, during the postseason.
165        print(
166            "Get CFB poll data for the 2021 CFB season, during the postseason."
167        )
168        json_data = get_cfbd_poll_rankings(
169            season=2021,
170            season_type="postseason"
171        )
172        print(json_data)
173        time.sleep(5)
174
175        # You can also tell this function to just return the API call as
176        # a Dictionary (read: JSON) object.
177        print(
178            "You can also tell this function to just return the API call " +
179            "as a dictionary (read: JSON) object."
180        )
181        json_data = get_cfbd_poll_rankings(
182            season=2020,
183            week=10,
184            return_as_dict=True
185        )
186        print(json_data)
187
188    ```
189    Returns
190    ----------
191    A pandas `DataFrame` object with CFB Poll data,
192    or (if `return_as_dict` is set to `True`)
193    a dictionary object with CFB Poll data.
194
195
196    """
197    now = datetime.now()
198    rankings_df = pd.DataFrame()
199    row_df = pd.DataFrame()
200    url = "https://api.collegefootballdata.com/rankings"
201
202    ##########################################################################
203
204    if api_key is not None:
205        real_api_key = api_key
206        del api_key
207    else:
208        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
209
210    if real_api_key == "tigersAreAwesome":
211        raise ValueError(
212            "You actually need to change `cfbd_key` to your CFBD API key."
213        )
214    elif "Bearer " in real_api_key:
215        pass
216    elif "Bearer" in real_api_key:
217        real_api_key = real_api_key.replace("Bearer", "Bearer ")
218    else:
219        real_api_key = "Bearer " + real_api_key
220
221    if season is None:
222        # This should never happen without user tampering, but if it does,
223        # we need to raise an error,
224        # because the CFBD API will refuse this call without a valid season.
225        raise SystemError(
226            "I don't know how, I don't know why, "
227            + "but you managed to call this function "
228            + "while `season` was `None` (NULL),"
229            + " and the function got to this point in the code."
230            + "\nIf you have a GitHub account, "
231            + "please raise an issue on this python package's GitHub page:\n"
232            + "https://github.com/armstjc/cfbd-json-py/issues"
233        )
234    elif season > (now.year + 1):
235        raise ValueError(f"`season` cannot be greater than {season}.")
236    elif season < 1869:
237        raise ValueError("`season` cannot be less than 1869.")
238
239    if season_type != "regular" and season_type != "postseason":
240        raise ValueError(
241            '`season_type` must be set to either ' +
242            '"regular" or "postseason" for this function to work.'
243        )
244
245    if week is not None and week < 0:
246        raise ValueError("`week` must be a positive number.")
247
248    if season_type != "regular" and season_type != "postseason":
249        raise ValueError(
250            '`season_type` must be set to either ' +
251            '"regular" or "postseason" for this function to work.'
252        )
253    # URL builder
254    ##########################################################################
255
256    # Required by API
257    url += f"?year={season}"
258
259    if week is not None:
260        url += f"&week={week}"
261
262    if season_type is not None:
263        url += f"&seasonType={season_type}"
264
265    headers = {
266        "Authorization": f"{real_api_key}", "accept": "application/json"
267    }
268    response = requests.get(url, headers=headers)
269
270    if response.status_code == 200:
271        pass
272    elif response.status_code == 401:
273        raise ConnectionRefusedError(
274            "Could not connect. " +
275            "The connection was refused.\nHTTP Status Code 401."
276        )
277    else:
278        raise ConnectionError(
279            f"Could not connect.\nHTTP Status code {response.status_code}"
280        )
281
282    json_data = response.json()
283
284    if return_as_dict is True:
285        return json_data
286
287    for week in json_data:
288        w_season = week["season"]
289        w_season_type = week["seasonType"]
290        w_week = week["week"]
291
292        for poll in week["polls"]:
293            p_poll_name = poll["poll"]
294
295            for team in poll["ranks"]:
296                row_df = pd.DataFrame(
297                    {
298                        "season": w_season,
299                        "season_type": w_season_type,
300                        "week": w_week,
301                        "poll_name": p_poll_name,
302                    },
303                    index=[0],
304                )
305
306                row_df["poll_rank"] = team["rank"]
307                row_df["school_name"] = team["school"]
308                row_df["conference_name"] = team["conference"]
309                row_df["first_place_votes"] = team["firstPlaceVotes"]
310                row_df["points"] = team["points"]
311
312                rankings_df = pd.concat(
313                    [rankings_df, row_df],
314                    ignore_index=True
315                )
316                del row_df
317
318            del p_poll_name
319
320        del w_season, w_season_type, w_week
321    return rankings_df
def get_cfbd_poll_rankings( season: int, api_key: str = None, api_key_dir: str = None, week: int = None, season_type: str = 'regular', return_as_dict: bool = False):
 18def get_cfbd_poll_rankings(
 19    season: int,
 20    api_key: str = None,
 21    api_key_dir: str = None,
 22    week: int = None,
 23    season_type: str = "regular",  # "regular" or "postseason"
 24    return_as_dict: bool = False,
 25):
 26    """
 27    Allows you to get CFB poll rankings data from the CFBD API.
 28
 29    Parameters
 30    ----------
 31    `season` (int, mandatory):
 32        Required argument.
 33        Specifies the season you want CFB poll rankings data from.
 34        This must be specified, otherwise this package, and by extension
 35        the CFBD API, will not accept
 36        the request to get CFB poll rankings data.
 37
 38    `api_key` (str, optional):
 39        Semi-optional argument.
 40        If `api_key` is null, this function will attempt to load a CFBD API key
 41        from the python environment, or from a file on this computer.
 42        If `api_key` is not null,
 43        this function will automatically assume that the
 44        inputted `api_key` is a valid CFBD API key.
 45
 46    `api_key_dir` (str, optional):
 47        Optional argument.
 48        If `api_key` is set to am empty string, this variable is ignored.
 49        If `api_key_dir` is null, and `api_key` is null,
 50        this function will try to find
 51        a CFBD API key file in this user's home directory.
 52        If `api_key_dir` is set to a string, and `api_key` is null,
 53        this function will assume that `api_key_dir` is a directory,
 54        and will try to find a CFBD API key file in that directory.
 55
 56    `week` (int, optional):
 57        Optional argument.
 58        If `week` is set to an integer, this function will attempt
 59        to load CFB poll rankings data from games in that season,
 60        and in that week.
 61
 62    `season_type` (str, semi-optional):
 63        Semi-optional argument.
 64        By default, this will be set to "regular", for the CFB regular season.
 65        If you want CFB poll rankings data for non-regular season games,
 66        set `season_type` to "postseason".
 67        If `season_type` is set to anything but "regular" or "postseason",
 68        a `ValueError()` will be raised.
 69
 70    `return_as_dict` (bool, semi-optional):
 71        Semi-optional argument.
 72        If you want this function to return the data
 73        as a dictionary (read: JSON object),
 74        instead of a pandas `DataFrame` object,
 75        set `return_as_dict` to `True`.
 76
 77    Usage
 78    ----------
 79    ```
 80    import time
 81
 82    from cfbd_json_py.rankings import get_cfbd_poll_rankings
 83
 84
 85    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 86
 87    if cfbd_key != "tigersAreAwesome":
 88        print(
 89            "Using the user's API key declared in this " +
 90            "script for this example."
 91        )
 92
 93        # Get CFB poll data for the 2020 CFB season.
 94        print("Get CFB poll data for the 2020 CFB season.")
 95        json_data = get_cfbd_poll_rankings(
 96            api_key=cfbd_key,
 97            season=2020
 98        )
 99        print(json_data)
100        time.sleep(5)
101
102        # Get CFB poll data from week 10 of the 2023 CFB season.
103        print("Get CFB poll data from week 10 of the 2023 CFB season.")
104        json_data = get_cfbd_poll_rankings(
105            api_key=cfbd_key,
106            season=2023,
107            week=10
108        )
109        print(json_data)
110        time.sleep(5)
111
112        # Get CFB poll data for the 2021 CFB season, during the postseason.
113        print(
114            "Get CFB poll data for the 2021 CFB season, during the postseason."
115        )
116        json_data = get_cfbd_poll_rankings(
117            api_key=cfbd_key,
118            season=2021,
119            season_type="postseason"
120        )
121        print(json_data)
122        time.sleep(5)
123
124        # You can also tell this function to just return the API call as
125        # a Dictionary (read: JSON) object.
126        print(
127            "You can also tell this function to just return the API call " +
128            "as a dictionary (read: JSON) object."
129        )
130        json_data = get_cfbd_poll_rankings(
131            api_key=cfbd_key,
132            season=2020,
133            week=10,
134            return_as_dict=True
135        )
136        print(json_data)
137
138    else:
139        # Alternatively, if the CFBD API key exists in this python environment,
140        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
141        # you could just call these functions directly,
142        # without setting the API key in the script.
143        print(
144            "Using the user's API key supposedly loaded into " +
145            "this python environment for this example."
146        )
147
148        # Get CFB poll data for the 2020 CFB season.
149        print("Get CFB poll data for the 2020 CFB season.")
150        json_data = get_cfbd_poll_rankings(
151            season=2020
152        )
153        print(json_data)
154        time.sleep(5)
155
156        # Get CFB poll data from week 10 of the 2023 CFB season.
157        print("Get CFB poll data from week 10 of the 2023 CFB season.")
158        json_data = get_cfbd_poll_rankings(
159            season=2023,
160            week=10
161        )
162        print(json_data)
163        time.sleep(5)
164
165        # Get CFB poll data for the 2021 CFB season, during the postseason.
166        print(
167            "Get CFB poll data for the 2021 CFB season, during the postseason."
168        )
169        json_data = get_cfbd_poll_rankings(
170            season=2021,
171            season_type="postseason"
172        )
173        print(json_data)
174        time.sleep(5)
175
176        # You can also tell this function to just return the API call as
177        # a Dictionary (read: JSON) object.
178        print(
179            "You can also tell this function to just return the API call " +
180            "as a dictionary (read: JSON) object."
181        )
182        json_data = get_cfbd_poll_rankings(
183            season=2020,
184            week=10,
185            return_as_dict=True
186        )
187        print(json_data)
188
189    ```
190    Returns
191    ----------
192    A pandas `DataFrame` object with CFB Poll data,
193    or (if `return_as_dict` is set to `True`)
194    a dictionary object with CFB Poll data.
195
196
197    """
198    now = datetime.now()
199    rankings_df = pd.DataFrame()
200    row_df = pd.DataFrame()
201    url = "https://api.collegefootballdata.com/rankings"
202
203    ##########################################################################
204
205    if api_key is not None:
206        real_api_key = api_key
207        del api_key
208    else:
209        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
210
211    if real_api_key == "tigersAreAwesome":
212        raise ValueError(
213            "You actually need to change `cfbd_key` to your CFBD API key."
214        )
215    elif "Bearer " in real_api_key:
216        pass
217    elif "Bearer" in real_api_key:
218        real_api_key = real_api_key.replace("Bearer", "Bearer ")
219    else:
220        real_api_key = "Bearer " + real_api_key
221
222    if season is None:
223        # This should never happen without user tampering, but if it does,
224        # we need to raise an error,
225        # because the CFBD API will refuse this call without a valid season.
226        raise SystemError(
227            "I don't know how, I don't know why, "
228            + "but you managed to call this function "
229            + "while `season` was `None` (NULL),"
230            + " and the function got to this point in the code."
231            + "\nIf you have a GitHub account, "
232            + "please raise an issue on this python package's GitHub page:\n"
233            + "https://github.com/armstjc/cfbd-json-py/issues"
234        )
235    elif season > (now.year + 1):
236        raise ValueError(f"`season` cannot be greater than {season}.")
237    elif season < 1869:
238        raise ValueError("`season` cannot be less than 1869.")
239
240    if season_type != "regular" and season_type != "postseason":
241        raise ValueError(
242            '`season_type` must be set to either ' +
243            '"regular" or "postseason" for this function to work.'
244        )
245
246    if week is not None and week < 0:
247        raise ValueError("`week` must be a positive number.")
248
249    if season_type != "regular" and season_type != "postseason":
250        raise ValueError(
251            '`season_type` must be set to either ' +
252            '"regular" or "postseason" for this function to work.'
253        )
254    # URL builder
255    ##########################################################################
256
257    # Required by API
258    url += f"?year={season}"
259
260    if week is not None:
261        url += f"&week={week}"
262
263    if season_type is not None:
264        url += f"&seasonType={season_type}"
265
266    headers = {
267        "Authorization": f"{real_api_key}", "accept": "application/json"
268    }
269    response = requests.get(url, headers=headers)
270
271    if response.status_code == 200:
272        pass
273    elif response.status_code == 401:
274        raise ConnectionRefusedError(
275            "Could not connect. " +
276            "The connection was refused.\nHTTP Status Code 401."
277        )
278    else:
279        raise ConnectionError(
280            f"Could not connect.\nHTTP Status code {response.status_code}"
281        )
282
283    json_data = response.json()
284
285    if return_as_dict is True:
286        return json_data
287
288    for week in json_data:
289        w_season = week["season"]
290        w_season_type = week["seasonType"]
291        w_week = week["week"]
292
293        for poll in week["polls"]:
294            p_poll_name = poll["poll"]
295
296            for team in poll["ranks"]:
297                row_df = pd.DataFrame(
298                    {
299                        "season": w_season,
300                        "season_type": w_season_type,
301                        "week": w_week,
302                        "poll_name": p_poll_name,
303                    },
304                    index=[0],
305                )
306
307                row_df["poll_rank"] = team["rank"]
308                row_df["school_name"] = team["school"]
309                row_df["conference_name"] = team["conference"]
310                row_df["first_place_votes"] = team["firstPlaceVotes"]
311                row_df["points"] = team["points"]
312
313                rankings_df = pd.concat(
314                    [rankings_df, row_df],
315                    ignore_index=True
316                )
317                del row_df
318
319            del p_poll_name
320
321        del w_season, w_season_type, w_week
322    return rankings_df

Allows you to get CFB poll rankings data from the CFBD API.

Parameters

season (int, mandatory): Required argument. Specifies the season you want CFB poll rankings data from. This must be specified, otherwise this package, and by extension the CFBD API, will not accept the request to get CFB poll rankings data.

api_key (str, optional): Semi-optional argument. If api_key is null, this function will attempt to load a CFBD API key from the python environment, or from a file on this computer. If api_key is not null, this function will automatically assume that the inputted api_key is a valid CFBD API key.

api_key_dir (str, optional): Optional argument. If api_key is set to am empty string, this variable is ignored. If api_key_dir is null, and api_key is null, this function will try to find a CFBD API key file in this user's home directory. If api_key_dir is set to a string, and api_key is null, this function will assume that api_key_dir is a directory, and will try to find a CFBD API key file in that directory.

week (int, optional): Optional argument. If week is set to an integer, this function will attempt to load CFB poll rankings data from games in that season, and in that week.

season_type (str, semi-optional): Semi-optional argument. By default, this will be set to "regular", for the CFB regular season. If you want CFB poll rankings data for non-regular season games, set season_type to "postseason". If season_type is set to anything but "regular" or "postseason", a ValueError() will be raised.

return_as_dict (bool, semi-optional): Semi-optional argument. If you want this function to return the data as a dictionary (read: JSON object), instead of a pandas DataFrame object, set return_as_dict to True.

Usage

import time

from cfbd_json_py.rankings import get_cfbd_poll_rankings


cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.

if cfbd_key != "tigersAreAwesome":
    print(
        "Using the user's API key declared in this " +
        "script for this example."
    )

    # Get CFB poll data for the 2020 CFB season.
    print("Get CFB poll data for the 2020 CFB season.")
    json_data = get_cfbd_poll_rankings(
        api_key=cfbd_key,
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get CFB poll data from week 10 of the 2023 CFB season.
    print("Get CFB poll data from week 10 of the 2023 CFB season.")
    json_data = get_cfbd_poll_rankings(
        api_key=cfbd_key,
        season=2023,
        week=10
    )
    print(json_data)
    time.sleep(5)

    # Get CFB poll data for the 2021 CFB season, during the postseason.
    print(
        "Get CFB poll data for the 2021 CFB season, during the postseason."
    )
    json_data = get_cfbd_poll_rankings(
        api_key=cfbd_key,
        season=2021,
        season_type="postseason"
    )
    print(json_data)
    time.sleep(5)

    # You can also tell this function to just return the API call as
    # a Dictionary (read: JSON) object.
    print(
        "You can also tell this function to just return the API call " +
        "as a dictionary (read: JSON) object."
    )
    json_data = get_cfbd_poll_rankings(
        api_key=cfbd_key,
        season=2020,
        week=10,
        return_as_dict=True
    )
    print(json_data)

else:
    # Alternatively, if the CFBD API key exists in this python environment,
    # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
    # you could just call these functions directly,
    # without setting the API key in the script.
    print(
        "Using the user's API key supposedly loaded into " +
        "this python environment for this example."
    )

    # Get CFB poll data for the 2020 CFB season.
    print("Get CFB poll data for the 2020 CFB season.")
    json_data = get_cfbd_poll_rankings(
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get CFB poll data from week 10 of the 2023 CFB season.
    print("Get CFB poll data from week 10 of the 2023 CFB season.")
    json_data = get_cfbd_poll_rankings(
        season=2023,
        week=10
    )
    print(json_data)
    time.sleep(5)

    # Get CFB poll data for the 2021 CFB season, during the postseason.
    print(
        "Get CFB poll data for the 2021 CFB season, during the postseason."
    )
    json_data = get_cfbd_poll_rankings(
        season=2021,
        season_type="postseason"
    )
    print(json_data)
    time.sleep(5)

    # You can also tell this function to just return the API call as
    # a Dictionary (read: JSON) object.
    print(
        "You can also tell this function to just return the API call " +
        "as a dictionary (read: JSON) object."
    )
    json_data = get_cfbd_poll_rankings(
        season=2020,
        week=10,
        return_as_dict=True
    )
    print(json_data)

Returns

A pandas DataFrame object with CFB Poll data, or (if return_as_dict is set to True) a dictionary object with CFB Poll data.