cfbd_json_py.plays

   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: plays.py
   5# Purpose: Houses functions pertaining to CFB play data within the CFBD API.
   6###############################################################################
   7
   8import logging
   9from datetime import datetime
  10
  11import pandas as pd
  12import requests
  13# from tqdm import tqdm
  14
  15from cfbd_json_py.utls import get_cfbd_api_token
  16
  17
  18def get_cfbd_pbp_data(
  19    season: int,
  20    week: int,
  21    api_key: str = None,
  22    api_key_dir: str = None,
  23    season_type: str = "regular",
  24    # required if team, offense, or defense, not specified
  25    team: str = None,
  26    offensive_team: str = None,
  27    defensive_team: str = None,
  28    conference: str = None,
  29    offensive_conference: str = None,
  30    defensive_conference: str = None,
  31    play_type: int = None,
  32    ncaa_division: str = "fbs",
  33    return_as_dict: bool = False,
  34):
  35    """
  36    Allows you to get CFB play-by-play (PBP) data from the CFBD API.
  37
  38    Parameters
  39    ----------
  40    `season` (int, mandatory):
  41        Required argument.
  42        Specifies the season you want CFB PBP data from.
  43        This must be specified, otherwise this package, and by extension
  44        the CFBD API, will not accept the request to get CFB PBP data.
  45
  46    `week` (int, optional):
  47        Required argument.
  48        This is the week you want CFB PBP data from.
  49        For a list of valid season-week combinations,
  50        use `cfbd_json_py.games.get_cfbd_season_weeks()`.
  51
  52    `api_key` (str, optional):
  53        Semi-optional argument.
  54        If `api_key` is null, this function will attempt to load a CFBD API key
  55        from the python environment, or from a file on this computer.
  56        If `api_key` is not null,
  57        this function will automatically assume that the
  58        inputted `api_key` is a valid CFBD API key.
  59
  60    `api_key_dir` (str, optional):
  61        Optional argument.
  62        If `api_key` is set to am empty string, this variable is ignored.
  63        If `api_key_dir` is null, and `api_key` is null,
  64        this function will try to find
  65        a CFBD API key file in this user's home directory.
  66        If `api_key_dir` is set to a string, and `api_key` is null,
  67        this function will assume that `api_key_dir` is a directory,
  68        and will try to find a CFBD API key file in that directory.
  69
  70    `week` (int, optional):
  71        Optional argument.
  72        If `week` is set to an integer, this function will attempt
  73        to load CFB poll rankings data from games in that season,
  74        and in that week.
  75
  76    `season_type` (str, semi-optional):
  77        Semi-optional argument.
  78        By default, this will be set to "regular", for the CFB regular season.
  79        If you want CFB poll rankings data for non-regular season games,
  80        set `season_type` to "postseason".
  81        If `season_type` is set to anything but "regular" or "postseason",
  82        a `ValueError()` will be raised.
  83
  84    `offensive_team` (str, optional):
  85        Optional argument.
  86        If you only want CFB drive data from a team, while they are on offense,
  87        regardless if they are the home/away team,
  88        set `team` to the name of the team you want CFB drive data from.
  89
  90    `defensive_team` (str, optional):
  91        Optional argument.
  92        If you only want CFB drive data from a team, while they are on defense,
  93        regardless if they are the home/away team,
  94        set `team` to the name of the team you want CFB drive data from.
  95
  96    `conference` (str, optional):
  97        Optional argument.
  98        If you only want CFB drive data from games
  99        involving teams from a specific conference,
 100        set `conference` to the abbreviation
 101        of the conference you want CFB drive data from.
 102        For a list of conferences,
 103        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 104        function.
 105
 106    `offensive_conference` (str, optional):
 107        Optional argument.
 108        If you only want CFB drive data from games
 109        where the offensive team is from a specific conference,
 110        set `conference` to the abbreviation
 111        of the conference you want CFB drive data from.
 112        For a list of conferences,
 113        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 114        function.
 115
 116    `defensive_conference` (str, optional):
 117        Optional argument.
 118        If you only want CFB drive data from games
 119        where the defensive team is from a specific conference,
 120        set `conference` to the abbreviation
 121        of the conference you want CFB drive data from.
 122        For a list of conferences,
 123        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 124        function.
 125
 126    `play_type` (int, optional):
 127        Optional argument.
 128        If want to drill down, and only get plays of a specific type,
 129        (like rushing, passing, kicking plays),
 130        set `play_type` to the ID for the play type you want returned.
 131        To retrieve a list of valid play type IDs,
 132        use `cfbd_json_py.plays.get_cfbd_pbp_play_types()`.
 133
 134    `ncaa_division` (str, semi-optional):
 135        Semi-optional argument.
 136        By default, `ncaa_division` will be set to "fbs",
 137        short for the Football Bowl Subdivision (FBS),
 138        formerly known as D1-A (read as "division one single A"),
 139        the highest level in the NCAA football pyramid,
 140        where teams can scholarship up to 85 players
 141        on their football team solely for athletic ability,
 142        and often have the largest athletics budgets
 143        within the NCAA.
 144
 145        Other valid inputs are:
 146        - "fcs": Football Championship Subdivision (FCS),
 147            formerly known as D1-AA (read as "division one double A").
 148            An FCS school is still in the 1st division of the NCAA,
 149            making them eligible for the March Madness tournament,
 150            but may not have the resources to compete at the FBS level
 151            at this time. FCS schools are limited to 63 athletic scholarships
 152            for football.
 153        - "ii": NCAA Division II. Schools in this and D3 are not
 154            eligible for the March Madness tournament,
 155            and are limited to 36 athletic scholarships
 156            for their football team.
 157        - "iii": NCAA Division III. The largest single division within the
 158            NCAA football pyramid.
 159            D3 schools have the distinction of being part of
 160            the only NCAA division that cannot give out scholarships solely
 161            for athletic ability.
 162
 163
 164    `return_as_dict` (bool, semi-optional):
 165        Semi-optional argument.
 166        If you want this function to return
 167        the data as a dictionary (read: JSON object),
 168        instead of a pandas `DataFrame` object,
 169        set `return_as_dict` to `True`.
 170
 171    Usage
 172    ----------
 173    ```
 174    import time
 175
 176    from cfbd_json_py.plays import get_cfbd_pbp_data
 177
 178
 179    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 180
 181    if cfbd_key != "tigersAreAwesome":
 182        print(
 183            "Using the user's API key declared in this script " +
 184            "for this example."
 185        )
 186
 187        # Get CFB PBP data for
 188        # the University of Cincinnati Football Team
 189        # for week 10 of the 2021 season
 190        print("Get CFB PBP data for week 10 of the 2021 season.")
 191        json_data = get_cfbd_pbp_data(
 192            api_key=cfbd_key,
 193            season=2021,
 194            week=10,
 195            team="Cincinnati"
 196        )
 197        print(json_data)
 198        time.sleep(5)
 199
 200        # Get CFB PBP data for when the Ohio State Buckeyes Football Team
 201        # was on offense for week 10 of the 2021 season
 202        print(
 203            "Get CFB PBP data for when the Ohio State Buckeyes " +
 204            "Football Team was on offense for week 10 of the 2021 season"
 205        )
 206        json_data = get_cfbd_pbp_data(
 207            api_key=cfbd_key,
 208            season=2021,
 209            week=10,
 210            offensive_team="Ohio State"
 211        )
 212        print(json_data)
 213        time.sleep(5)
 214
 215        # Get CFB PBP data for when the LSU Tigers Football Team
 216        # was on defense for week 10 of the 2021 season
 217        print(
 218            "Get CFB PBP data for when the LSU Tigers Football Team " +
 219            "was on defense for week 10 of the 2021 season"
 220        )
 221        json_data = get_cfbd_pbp_data(
 222            api_key=cfbd_key,
 223            season=2021,
 224            week=10,
 225            defensive_team="LSU"
 226        )
 227        print(json_data)
 228        time.sleep(5)
 229
 230        # Get CFB PBP data for teams in the Southeastern Conference (SEC)
 231        # for week 10 of the 2021 CFB season.
 232        print(
 233            "Get CFB PBP data for teams in " +
 234            "the Southeastern Conference (SEC) " +
 235            "for week 10 of the 2021 CFB season."
 236        )
 237        json_data = get_cfbd_pbp_data(
 238            api_key=cfbd_key,
 239            season=2021,
 240            week=10,
 241            conference="SEC"
 242        )
 243        print(json_data)
 244        time.sleep(5)
 245
 246        # Get CFB PBP data for teams in the Big 10 (B1G) Conference,
 247        # while on offense, for week 10 of the 2021 CFB season.
 248        print(
 249            "Get CFB PBP data for teams in the Big 10 (B1G) Conference " +
 250            "while on offense, for week 10 of the 2021 CFB season."
 251        )
 252        json_data = get_cfbd_pbp_data(
 253            api_key=cfbd_key,
 254            season=2021,
 255            week=10,
 256            offensive_conference="B1G"
 257        )
 258        print(json_data)
 259        time.sleep(5)
 260
 261        # Get CFB PBP data for teams in the Atlantic Coast Conference (ACC),
 262        # while on defense, for week 10 of the 2021 CFB season.
 263        print(
 264            "Get CFB PBP data for teams in " +
 265            "the Atlantic Coast Conference (ACC), while on defense, " +
 266            "for week 10 of the 2021 CFB season."
 267        )
 268        json_data = get_cfbd_pbp_data(
 269            api_key=cfbd_key,
 270            season=2021,
 271            week=10,
 272            defensive_conference="ACC"
 273        )
 274        print(json_data)
 275        time.sleep(5)
 276
 277        # Get every run play for week 10 of the 2021 CFB season.
 278        print("Get every run play for week 10 of the 2021 CFB season.")
 279        json_data = get_cfbd_pbp_data(
 280            api_key=cfbd_key,
 281            season=2021,
 282            week=10,
 283            play_type=5 # ID for run plays.
 284            # See `cfbd_json_py.plays.get_cfbd_pbp_play_types()`
 285            # for a list of play type IDs.
 286        )
 287        print(json_data)
 288        time.sleep(5)
 289
 290        # Get CFB PBP data for Football Championship Subdivision (FCS)
 291        # teams in week 10 of the 2021 CFB season.
 292        print(
 293            "Get CFB PBP data for Football Championship Subdivision (FCS)" +
 294            " teams in week 10 of the 2021 CFB season."
 295        )
 296        json_data = get_cfbd_pbp_data(
 297            api_key=cfbd_key,
 298            season=2021,
 299            week=10,
 300            ncaa_division="fcs"
 301        )
 302        print(json_data)
 303        time.sleep(5)
 304
 305        # Get CFB PBP data for week 10 of the 2021 season
 306        print("Get CFB PBP data for week 10 of the 2021 season.")
 307        json_data = get_cfbd_pbp_data(
 308            api_key=cfbd_key,
 309            season=2021,
 310            week=10
 311        )
 312        print(json_data)
 313        time.sleep(5)
 314
 315        # You can also tell this function to just return the API call as
 316        # a Dictionary (read: JSON) object.
 317        print(
 318            "You can also tell this function to just return the API call " +
 319            "as a Dictionary (read: JSON) object."
 320        )
 321        json_data = get_cfbd_pbp_data(
 322            api_key=cfbd_key,
 323            season=2020,
 324            week=10,
 325            defensive_team="LSU",
 326            return_as_dict=True
 327        )
 328        print(json_data)
 329
 330    else:
 331        # Alternatively, if the CFBD API key exists in this python environment,
 332        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 333        # you could just call these functions directly,
 334        # without setting the API key in the script.
 335        print(
 336            "Using the user's API key supposedly loaded " +
 337            "into this python environment for this example."
 338        )
 339
 340        # Get CFB PBP data for the University of Cincinnati Football Team
 341        # for week 10 of the 2021 season
 342        print(
 343            "Get CFB play-by-play (PBP) data for " +
 344            "the University of Cincinnati Football Team " +
 345            "for week 10 of the 2021 season"
 346        )
 347        json_data = get_cfbd_pbp_data(
 348            season=2021,
 349            week=10,
 350            team="Cincinnati"
 351        )
 352        print(json_data)
 353        time.sleep(5)
 354
 355        # Get CFB PBP data for when the Ohio State Buckeyes Football Team
 356        # was on offense for week 10 of the 2021 season
 357        print(
 358            "Get CFB PBP data for when " +
 359            "the Ohio State Buckeyes Football Team was on offense " +
 360            "for week 10 of the 2021 season"
 361        )
 362        json_data = get_cfbd_pbp_data(
 363            season=2021,
 364            week=10,
 365            offensive_team="Ohio State"
 366        )
 367        print(json_data)
 368        time.sleep(5)
 369
 370        # Get CFB PBP data for when the LSU Tigers Football Team
 371        # was on defense for week 10 of the 2021 season
 372        print(
 373            "Get CFB PBP data for when the LSU Tigers Football Team " +
 374            "was on defense for week 10 of the 2021 season"
 375        )
 376        json_data = get_cfbd_pbp_data(
 377            season=2021,
 378            week=10,
 379            defensive_team="LSU"
 380        )
 381        print(json_data)
 382        time.sleep(5)
 383
 384        # Get CFB PBP data for teams in the Southeastern Conference (SEC)
 385        # for week 10 of the 2021 CFB season.
 386        print(
 387            "Get CFB PBP data for teams in " +
 388            "the Southeastern Conference (SEC) " +
 389            "for week 10 of the 2021 CFB season."
 390        )
 391        json_data = get_cfbd_pbp_data(
 392            season=2021,
 393            week=10,
 394            conference="SEC"
 395        )
 396        print(json_data)
 397        time.sleep(5)
 398
 399        # Get CFB PBP data for teams in the Big 10 (B1G) Conference,
 400        # while on offense, for week 10 of the 2021 CFB season.
 401        print(
 402            "Get CFB PBP data for teams in the Big 10 (B1G) Conference " +
 403            "while on offense, for week 10 of the 2021 CFB season."
 404        )
 405        json_data = get_cfbd_pbp_data(
 406            season=2021,
 407            week=10,
 408            offensive_conference="B1G"
 409        )
 410        print(json_data)
 411        time.sleep(5)
 412
 413        # Get CFB PBP data for teams in the Atlantic Coast Conference (ACC),
 414        # while on defense, for week 10 of the 2021 CFB season.
 415        print(
 416            "Get CFB PBP data for teams in " +
 417            "the Atlantic Coast Conference (ACC), while on defense, " +
 418            "for week 10 of the 2021 CFB season."
 419        )
 420        json_data = get_cfbd_pbp_data(
 421            season=2021,
 422            week=10,
 423            defensive_conference="ACC"
 424        )
 425        print(json_data)
 426        time.sleep(5)
 427
 428        # Get every run play for week 10 of the 2021 CFB season.
 429        print("Get every run play for week 10 of the 2021 CFB season.")
 430        json_data = get_cfbd_pbp_data(
 431            season=2021,
 432            week=10,
 433            play_type=5 # ID for run plays.
 434            # See `cfbd_json_py.plays.get_cfbd_pbp_play_types()`
 435            # for a list of play type IDs.
 436        )
 437        print(json_data)
 438        time.sleep(5)
 439
 440        # Get CFB PBP data for Football Championship Subdivision (FCS)
 441        # teams in week 10 of the 2021 CFB season.
 442        print(
 443            "Get CFB PBP data for Football Championship Subdivision (FCS)" +
 444            " teams in week 10 of the 2021 CFB season."
 445        )
 446        json_data = get_cfbd_pbp_data(
 447            season=2021,
 448            week=10,
 449            ncaa_division="fcs"
 450        )
 451        print(json_data)
 452        time.sleep(5)
 453
 454        # Get CFB PBP data for week 10 of the 2021 season
 455        print("Get CFB PBP data for week 10 of the 2021 season.")
 456        json_data = get_cfbd_pbp_data(
 457            season=2021,
 458            week=10
 459        )
 460        print(json_data)
 461        time.sleep(5)
 462
 463        # You can also tell this function to just return the API call as
 464        # a Dictionary (read: JSON) object.
 465        print(
 466            "You can also tell this function to just return the API call " +
 467            "as a Dictionary (read: JSON) object."
 468        )
 469        json_data = get_cfbd_pbp_data(
 470            season=2020,
 471            week=10,
 472            defensive_team="LSU",
 473            return_as_dict=True
 474        )
 475        print(json_data)
 476
 477    ```
 478    Returns
 479    ----------
 480    A pandas `DataFrame` object with CFB PBP data,
 481    or (if `return_as_dict` is set to `True`)
 482    a dictionary object with CFB PBP data.
 483
 484    """
 485
 486    now = datetime.now()
 487    pbp_df = pd.DataFrame()
 488    # row_df = pd.DataFrame()
 489    url = "https://api.collegefootballdata.com/plays"
 490
 491    # Input validation
 492    ##########################################################################
 493
 494    if api_key is not None:
 495        real_api_key = api_key
 496        del api_key
 497    else:
 498        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
 499
 500    if real_api_key == "tigersAreAwesome":
 501        raise ValueError(
 502            "You actually need to change `cfbd_key` to your CFBD API key."
 503        )
 504    elif "Bearer " in real_api_key:
 505        pass
 506    elif "Bearer" in real_api_key:
 507        real_api_key = real_api_key.replace("Bearer", "Bearer ")
 508    else:
 509        real_api_key = "Bearer " + real_api_key
 510
 511    if season is None:
 512        # This should never happen without user tampering, but if it does,
 513        # we need to raise an error,
 514        # because the CFBD API will refuse this call without a valid season.
 515        raise SystemError(
 516            "I don't know how, I don't know why, "
 517            + "but you managed to call this function "
 518            + "while `season` was `None` (NULL),"
 519            + " and the function got to this point in the code."
 520            + "\nIf you have a GitHub account, "
 521            + "please raise an issue on this python package's GitHub page:\n"
 522            + "https://github.com/armstjc/cfbd-json-py/issues"
 523        )
 524    elif season > (now.year + 1):
 525        raise ValueError(f"`season` cannot be greater than {season}.")
 526    elif season < 1869:
 527        raise ValueError("`season` cannot be less than 1869.")
 528
 529    if season_type != "regular" and season_type != "postseason":
 530        raise ValueError(
 531            '`season_type` must be set to either ' +
 532            '"regular" or "postseason" for this function to work.'
 533        )
 534
 535    if (
 536        ncaa_division.lower() == "fbs"
 537        or ncaa_division.lower() == "fcs"
 538        or ncaa_division.lower() == "ii"
 539        or ncaa_division.lower() == "iii"
 540    ):
 541        pass
 542    else:
 543        raise ValueError(
 544            "An invalid NCAA Division was inputted when calling this function."
 545            + '\nValid inputs are:\n-"fbs"\n-"fcs"\n-"ii"\n-"iii"'
 546            + f"\n\nYou entered:\n{ncaa_division}"
 547        )
 548
 549    if week is None and (
 550        team is None and offensive_team is None and defensive_team is None
 551    ):
 552        raise ValueError(
 553            "If `week` is set to `None` when calling this function, "
 554            + "the following variables must be set "
 555            + "to a valid non-null variable:"
 556            + "\n- `team`"
 557            + "\n- `offensive_team`"
 558            + "\n- `defensive_team`"
 559        )
 560    # URL builder
 561    ##########################################################################
 562
 563    # Required by API
 564    url += f"?seasonType={season_type}"
 565
 566    url += f"&year={season}"
 567
 568    url += f"&week={week}"
 569
 570    if team is not None:
 571        url += f"&team={team}"
 572
 573    if offensive_team is not None:
 574        url += f"&offense={offensive_team}"
 575
 576    if defensive_team is not None:
 577        url += f"&defense={defensive_team}"
 578
 579    if conference is not None:
 580        url += f"&conference={conference}"
 581
 582    if offensive_conference is not None:
 583        url += f"&offenseConference={offensive_conference}"
 584
 585    if defensive_conference is not None:
 586        url += f"&defenseConference={defensive_conference}"
 587
 588    if ncaa_division is not None:
 589        url += f"&classification={ncaa_division}"
 590
 591    if play_type is not None:
 592        url += f"&playType={play_type}"
 593
 594    headers = {
 595        "Authorization": f"{real_api_key}",
 596        "accept": "application/json"
 597    }
 598
 599    response = requests.get(url, headers=headers)
 600
 601    if response.status_code == 200:
 602        pass
 603    elif response.status_code == 401:
 604        raise ConnectionRefusedError(
 605            "Could not connect. The connection was refused." +
 606            "\nHTTP Status Code 401."
 607        )
 608    else:
 609        raise ConnectionError(
 610            f"Could not connect.\nHTTP Status code {response.status_code}"
 611        )
 612
 613    json_data = response.json()
 614
 615    if return_as_dict is True:
 616        return json_data
 617
 618    pbp_df = pd.json_normalize(json_data)
 619    pbp_df.rename(
 620        columns={
 621            "id": "play_id",
 622            "offense": "offensive_team_name",
 623            "offense_conference": "offensive_conference_name",
 624            "defense": "defensive_team_name",
 625            "defense_conference": "defensive_conference_name",
 626            "home": "home_team_name",
 627            "away": "away_team_name",
 628            "clock.minutes": "clock_minutes",
 629            "clock.seconds": "clock_seconds",
 630        },
 631        inplace=True,
 632    )
 633    return pbp_df
 634
 635
 636def get_cfbd_pbp_play_types(
 637    api_key: str = None,
 638    api_key_dir: str = None,
 639    return_as_dict: bool = False
 640):
 641    """
 642    Allows you to get CFBD PBP play types from the CFBD API.
 643
 644    Parameters
 645    ----------
 646
 647    `api_key` (str, optional):
 648        Semi-optional argument.
 649        If `api_key` is null, this function will attempt to load a CFBD API key
 650        from the python environment, or from a file on this computer.
 651        If `api_key` is not null,
 652        this function will automatically assume that the
 653        inputted `api_key` is a valid CFBD API key.
 654
 655    `api_key_dir` (str, optional):
 656        Optional argument.
 657        If `api_key` is set to am empty string, this variable is ignored.
 658        If `api_key_dir` is null, and `api_key` is null,
 659        this function will try to find
 660        a CFBD API key file in this user's home directory.
 661        If `api_key_dir` is set to a string, and `api_key` is null,
 662        this function will assume that `api_key_dir` is a directory,
 663        and will try to find a CFBD API key file in that directory.
 664
 665    `return_as_dict` (bool, semi-optional):
 666        Semi-optional argument.
 667        If you want this function to return
 668        the data as a dictionary (read: JSON object),
 669        instead of a pandas `DataFrame` object,
 670        set `return_as_dict` to `True`.
 671
 672    Usage
 673    ----------
 674    ```
 675    ```
 676    Returns
 677    ----------
 678    A pandas `DataFrame` object with CFBD PBP play types,
 679    or (if `return_as_dict` is set to `True`)
 680    a dictionary object with CFBD PBP play types.
 681
 682    """
 683    # now = datetime.now()
 684    plays_df = pd.DataFrame()
 685    plays_df_arr = []
 686    row_df = pd.DataFrame()
 687    url = "https://api.collegefootballdata.com/play/types"
 688
 689    # Input validation
 690    ##########################################################################
 691
 692    if api_key is not None:
 693        real_api_key = api_key
 694        del api_key
 695    else:
 696        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
 697
 698    if real_api_key == "tigersAreAwesome":
 699        raise ValueError(
 700            "You actually need to change `cfbd_key` to your CFBD API key."
 701        )
 702    elif "Bearer " in real_api_key:
 703        pass
 704    elif "Bearer" in real_api_key:
 705        real_api_key = real_api_key.replace("Bearer", "Bearer ")
 706    else:
 707        real_api_key = "Bearer " + real_api_key
 708
 709    headers = {
 710        "Authorization": f"{real_api_key}",
 711        "accept": "application/json"
 712    }
 713
 714    response = requests.get(url, headers=headers)
 715
 716    if response.status_code == 200:
 717        pass
 718    elif response.status_code == 401:
 719        raise ConnectionRefusedError(
 720            "Could not connect. The connection was refused." +
 721            "\nHTTP Status Code 401."
 722        )
 723    else:
 724        raise ConnectionError(
 725            f"Could not connect.\nHTTP Status code {response.status_code}"
 726        )
 727
 728    json_data = response.json()
 729
 730    if return_as_dict is True:
 731        return json_data
 732
 733    for p in json_data:
 734        p_id = p["id"]
 735        row_df = pd.DataFrame({"play_type_id": p_id}, index=[0])
 736        row_df["play_type_text"] = p["text"]
 737        row_df["play_type_abv"] = p["abbreviation"]
 738        # plays_df = pd.concat([plays_df, row_df], ignore_index=True)
 739        plays_df_arr.append(row_df)
 740        del row_df
 741        del p_id
 742
 743    plays_df = pd.concat(plays_df_arr, ignore_index=True)
 744    return plays_df
 745
 746
 747def get_cfbd_pbp_stats(
 748    api_key: str = None,
 749    api_key_dir: str = None,
 750    season: int = None,
 751    week: int = None,
 752    team: str = None,
 753    game_id: int = None,
 754    athlete_id: int = None,
 755    stat_type_id: int = None,
 756    season_type: str = "both",  # "regular", "postseason", or "both"
 757    conference: str = None,
 758    return_as_dict: bool = False,
 759):
 760    """
 761    Allows you to get stats for various players
 762    from CFB play-by-play (PBP) data within the CFBD API.
 763
 764    Parameters
 765    ----------
 766
 767    `api_key` (str, optional):
 768        Semi-optional argument.
 769        If `api_key` is null, this function will attempt to load a CFBD API key
 770        from the python environment, or from a file on this computer.
 771        If `api_key` is not null,
 772        this function will automatically assume that the
 773        inputted `api_key` is a valid CFBD API key.
 774
 775    `api_key_dir` (str, optional):
 776        Optional argument.
 777        If `api_key` is set to am empty string, this variable is ignored.
 778        If `api_key_dir` is null, and `api_key` is null,
 779        this function will try to find
 780        a CFBD API key file in this user's home directory.
 781        If `api_key_dir` is set to a string, and `api_key` is null,
 782        this function will assume that `api_key_dir` is a directory,
 783        and will try to find a CFBD API key file in that directory.
 784
 785    `season` (int, optional):
 786        Semi-optional argument.
 787        Specifies the season you want CFB PBP data from.
 788        This must be specified, otherwise this package, and by extension
 789        the CFBD API, will not accept the request to get CFB PBP data.
 790
 791    `week` (int, optional):
 792        Optional argument.
 793        If `week` is set to an integer, this function will attempt
 794        to load CFB poll rankings data from games in that season,
 795        and in that week.
 796
 797    `team` (str, optional):
 798        Optional argument.
 799        If you only want stats for a specific team,
 800        set `team` to the name of that specific team.
 801
 802    `game_id` (int, optional):
 803        Optional argument.
 804        If you only want stats for a specific game,
 805        set `game_id` to the ID of that specific game.
 806
 807    `athlete_id` (int, optional):
 808        Optional argument.
 809        If you only want stats for a specific player,
 810        set `athlete_id` to the ID of the player you want stats for.
 811
 812    `stats_type_id` (int, optional):
 813        Optional argument.
 814        If want to drill down, and only get plays of a specific type,
 815        (like rushing, passing, kicking plays),
 816        set `play_type` to the ID for the play type you want returned.
 817        To retrieve a list of valid play type IDs,
 818        use `cfbd_json_py.plays.get_cfbd_pbp_play_types()`.
 819
 820    `season_type` (str, semi-optional):
 821        Semi-optional argument.
 822        By default, this will be set to "regular", for the CFB regular season.
 823        If you want CFB poll rankings data for non-regular season games,
 824        set `season_type` to "postseason".
 825        If `season_type` is set to anything but "regular" or "postseason",
 826        a `ValueError()` will be raised.
 827
 828    `conference` (str, optional):
 829        Optional argument.
 830        If you only want CFB drive data from games
 831        involving teams from a specific conference,
 832        set `conference` to the abbreviation
 833        of the conference you want CFB drive data from.
 834        For a list of conferences,
 835        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 836        function.
 837
 838    `return_as_dict` (bool, semi-optional):
 839        Semi-optional argument.
 840        If you want this function to return
 841        the data as a dictionary (read: JSON object),
 842        instead of a pandas `DataFrame` object,
 843        set `return_as_dict` to `True`.
 844
 845    Usage
 846    ----------
 847    ```
 848    import time
 849
 850    from cfbd_json_py.plays import get_cfbd_pbp_stats
 851
 852
 853    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 854
 855    if cfbd_key != "tigersAreAwesome":
 856        print(
 857            "Using the user's API key declared in this script " +
 858            "for this example."
 859        )
 860
 861        # Get CFB PBP stats data for the 2020 CFB season.
 862        print("Get CFB PBP stats data for the 2020 CFB season.")
 863        json_data = get_cfbd_pbp_stats(
 864            api_key=cfbd_key,
 865            season=2020
 866        )
 867        print(json_data)
 868        time.sleep(5)
 869
 870        # Get CFB PBP stats data for week 10 of the 2020 CFB season.
 871        print("Get CFB PBP stats data for week 10 of the 2020 CFB season.")
 872        json_data = get_cfbd_pbp_stats(
 873            api_key=cfbd_key,
 874            season=2020,
 875            week=10
 876        )
 877        print(json_data)
 878        time.sleep(5)
 879
 880        # Get CFB PBP stats data for a 2019 game between
 881        # the Ohio State Buckeyes and Clemson Tigers football teams.
 882        print(
 883            "Get CFB PBP stats data for a 2019 game between " +
 884            "the Ohio State Buckeyes and Clemson Tigers football teams."
 885        )
 886        json_data = get_cfbd_pbp_stats(
 887            api_key=cfbd_key,
 888            game_id=401135279
 889        )
 890        print(json_data)
 891        time.sleep(5)
 892
 893        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
 894        # during the 2020 CFB Season.
 895        print("Get CFB PBP stats data for the 2020 CFB season.")
 896        json_data = get_cfbd_pbp_stats(
 897            api_key=cfbd_key,
 898            season=2020,
 899            athlete_id=4360310
 900        )
 901        print(json_data)
 902        time.sleep(5)
 903
 904        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
 905        # during the 2020 CFB Season,
 906        # but only return plays where Lawrence scored a touchdown.
 907        print("Get CFB PBP stats data for the 2020 CFB season.")
 908        json_data = get_cfbd_pbp_stats(
 909            api_key=cfbd_key,
 910            season=2020,
 911            athlete_id=4360310,
 912            stat_type_id=22
 913        )
 914        print(json_data)
 915        time.sleep(5)
 916
 917        # Get CFB PBP stats data for the 2020 CFB season,
 918        # but only for postseason games.
 919        print("Get CFB PBP stats data for the 2020 CFB season.")
 920        json_data = get_cfbd_pbp_stats(
 921            api_key=cfbd_key,
 922            season=2020,
 923            season_type="postseason"
 924        )
 925        print(json_data)
 926        time.sleep(5)
 927
 928        # Get CFB PBP stats data for the 2020 CFB season,
 929        # but only for Big 10 (B1G) games.
 930        print("Get CFB PBP stats data for the 2020 CFB season.")
 931        json_data = get_cfbd_pbp_stats(
 932            api_key=cfbd_key,
 933            season=2020,
 934            conference="B1G"
 935        )
 936        print(json_data)
 937        time.sleep(5)
 938
 939        # Get CFB PBP stats data for the 2020 CFB season.
 940        print("Get CFB PBP stats data for the 2020 CFB season.")
 941        json_data = get_cfbd_pbp_stats(
 942            api_key=cfbd_key,
 943            season=2020
 944        )
 945        print(json_data)
 946        time.sleep(5)
 947
 948        # You can also tell this function to just return the API call as
 949        # a Dictionary (read: JSON) object.
 950        print(
 951            "You can also tell this function to just return the API call " +
 952            "as a Dictionary (read: JSON) object."
 953        )
 954        json_data = get_cfbd_pbp_stats(
 955            api_key=cfbd_key,
 956            season=2020,
 957            week=10,
 958            return_as_dict=True
 959        )
 960        print(json_data)
 961
 962    else:
 963        # Alternatively, if the CFBD API key exists in this python environment,
 964        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 965        # you could just call these functions directly,
 966        # without setting the API key in the script.
 967        print(
 968            "Using the user's API key supposedly loaded " +
 969            "into this python environment for this example."
 970        )
 971
 972        # Get CFB PBP stats data for the 2020 CFB season.
 973        print("Get CFB PBP stats data for the 2020 CFB season.")
 974        json_data = get_cfbd_pbp_stats(
 975            season=2020
 976        )
 977        print(json_data)
 978        time.sleep(5)
 979
 980        # Get CFB PBP stats data for week 10 of the 2020 CFB season.
 981        print("Get CFB PBP stats data for week 10 of the 2020 CFB season.")
 982        json_data = get_cfbd_pbp_stats(
 983            season=2020,
 984            week=10
 985        )
 986        print(json_data)
 987        time.sleep(5)
 988
 989        # Get CFB PBP stats data for a 2019 game between
 990        # the Ohio State Buckeyes and Clemson Tigers football teams.
 991        print(
 992            "Get CFB PBP stats data for a 2019 game between " +
 993            "the Ohio State Buckeyes and Clemson Tigers football teams."
 994        )
 995        json_data = get_cfbd_pbp_stats(
 996            game_id=401135279
 997        )
 998        print(json_data)
 999        time.sleep(5)
1000
1001        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
1002        # during the 2020 CFB Season.
1003        print("Get CFB PBP stats data for the 2020 CFB season.")
1004        json_data = get_cfbd_pbp_stats(
1005            season=2020,
1006            athlete_id=4360310
1007        )
1008        print(json_data)
1009        time.sleep(5)
1010
1011        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
1012        # during the 2020 CFB Season,
1013        # but only return plays where Lawrence scored a touchdown.
1014        print("Get CFB PBP stats data for the 2020 CFB season.")
1015        json_data = get_cfbd_pbp_stats(
1016            season=2020,
1017            athlete_id=4360310,
1018            stat_type_id=22
1019        )
1020        print(json_data)
1021        time.sleep(5)
1022
1023        # Get CFB PBP stats data for the 2020 CFB season,
1024        # but only for postseason games.
1025        print("Get CFB PBP stats data for the 2020 CFB season.")
1026        json_data = get_cfbd_pbp_stats(
1027            season=2020,
1028            season_type="postseason"
1029        )
1030        print(json_data)
1031        time.sleep(5)
1032
1033        # Get CFB PBP stats data for the 2020 CFB season,
1034        # but only for Big 10 (B1G) games.
1035        print("Get CFB PBP stats data for the 2020 CFB season.")
1036        json_data = get_cfbd_pbp_stats(
1037            season=2020,
1038            conference="B1G"
1039        )
1040        print(json_data)
1041        time.sleep(5)
1042
1043        # You can also tell this function to just return the API call as
1044        # a Dictionary (read: JSON) object.
1045        print(
1046            "You can also tell this function to just return the API call " +
1047            "as a Dictionary (read: JSON) object."
1048        )
1049        json_data = get_cfbd_pbp_stats(
1050            season=2020,
1051            week=10,
1052            return_as_dict=True
1053        )
1054        print(json_data)
1055
1056    ```
1057    Returns
1058    ----------
1059    A pandas `DataFrame` object with CFB PBP data,
1060    or (if `return_as_dict` is set to `True`)
1061    a dictionary object with CFB PBP data.
1062
1063    """
1064    now = datetime.now()
1065    pbp_df = pd.DataFrame()
1066    url = "https://api.collegefootballdata.com/play/stats"
1067
1068    # Input validation
1069    ##########################################################################
1070
1071    if api_key is not None:
1072        real_api_key = api_key
1073        del api_key
1074    else:
1075        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1076
1077    if real_api_key == "tigersAreAwesome":
1078        raise ValueError(
1079            "You actually need to change `cfbd_key` to your CFBD API key."
1080        )
1081    elif "Bearer " in real_api_key:
1082        pass
1083    elif "Bearer" in real_api_key:
1084        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1085    else:
1086        real_api_key = "Bearer " + real_api_key
1087
1088    if season is not None and (season > (now.year + 1)):
1089        raise ValueError(f"`season` cannot be greater than {season}.")
1090    elif season is not None and season < 1869:
1091        raise ValueError("`season` cannot be less than 1869.")
1092
1093    if (
1094        season_type != "regular"
1095        and season_type != "postseason"
1096        and season_type != "both"
1097    ):
1098        raise ValueError(
1099            '`season_type` must be set to either ' +
1100            '"regular", "postseason", or "both" for this function to work.'
1101        )
1102
1103    if season is None and game_id is None:
1104        logging.warning(
1105            "This endpoint only returns the top 1,000 results. "
1106            + "Not setting a value for `season` or `game_id` "
1107            + "is not a recommended practice."
1108        )
1109    elif (
1110        (season is not None) and
1111        (game_id is not None)
1112    ):
1113        logging.warning(
1114            "Setting a value for both `season` and `game_id` "
1115            + "may not yeld the results you want. "
1116            + "If you just want PBP stats for a valid game ID, "
1117            + "just set `game_id` to a valid game ID."
1118        )
1119
1120    # URL builder
1121    ##########################################################################
1122
1123    url_elements = 0
1124
1125    if season_type is not None and url_elements == 0:
1126        url += f"?seasonType={season_type}"
1127        url_elements += 1
1128    elif season_type is not None:
1129        url += f"&seasonType={season_type}"
1130        url_elements += 1
1131
1132    if season is not None and url_elements == 0:
1133        url += f"?year={season}"
1134        url_elements += 1
1135    elif season is not None:
1136        url += f"&year={season}"
1137        url_elements += 1
1138
1139    if week is not None and url_elements == 0:
1140        url += f"?week={week}"
1141        url_elements += 1
1142    elif week is not None:
1143        url += f"&week={week}"
1144        url_elements += 1
1145
1146    if team is not None and url_elements == 0:
1147        url += f"?team={team}"
1148        url_elements += 1
1149    elif team is not None:
1150        url += f"&team={team}"
1151        url_elements += 1
1152
1153    if conference is not None and url_elements == 0:
1154        url += f"&conference={conference}"
1155        url_elements += 1
1156    elif conference is not None:
1157        url += f"&conference={conference}"
1158        url_elements += 1
1159
1160    if game_id is not None and url_elements == 0:
1161        url += f"&gameId={game_id}"
1162        url_elements += 1
1163    elif game_id is not None:
1164        url += f"&gameId={game_id}"
1165        url_elements += 1
1166
1167    if athlete_id is not None and url_elements == 0:
1168        url += f"&athleteId={athlete_id}"
1169        url_elements += 1
1170    elif athlete_id is not None:
1171        url += f"&athleteId={athlete_id}"
1172        url_elements += 1
1173
1174    if stat_type_id is not None and url_elements == 0:
1175        url += f"&statTypeId={stat_type_id}"
1176        url_elements += 1
1177    elif stat_type_id is not None:
1178        url += f"&statTypeId={stat_type_id}"
1179        url_elements += 1
1180
1181    headers = {
1182        "Authorization": f"{real_api_key}",
1183        "accept": "application/json"
1184    }
1185
1186    response = requests.get(url, headers=headers)
1187
1188    if response.status_code == 200:
1189        pass
1190    elif response.status_code == 401:
1191        raise ConnectionRefusedError(
1192            "Could not connect. The connection was refused." +
1193            "\nHTTP Status Code 401."
1194        )
1195    else:
1196        raise ConnectionError(
1197            f"Could not connect.\nHTTP Status code {response.status_code}"
1198        )
1199
1200    json_data = response.json()
1201
1202    if return_as_dict is True:
1203        return json_data
1204
1205    pbp_df = pd.json_normalize(json_data)
1206    pbp_df.rename(
1207        columns={
1208            "gameId": "game_id",
1209            "teamScore": "team_score",
1210            "opponentScore": "opponent_score",
1211            "driveId": "drive_id",
1212            "playId": "play_id",
1213            "yardsToGoal": "yards_to_goal",
1214            "athleteId": "athlete_id",
1215            "athleteName": "athlete_name",
1216            "statType": "stat_type",
1217        },
1218        inplace=True,
1219    )
1220    # TODO: Implement an option to put all stats for
1221    # a specific game on a single line.
1222    return pbp_df
1223
1224
1225def get_cfbd_pbp_stat_types(
1226    api_key: str = None,
1227    api_key_dir: str = None,
1228    return_as_dict: bool = False
1229):
1230    """
1231    Allows you to get CFBD PBP stat types from the CFBD API.
1232
1233    Parameters
1234    ----------
1235
1236    `api_key` (str, optional):
1237        Semi-optional argument.
1238        If `api_key` is null, this function will attempt to load a CFBD API key
1239        from the python environment, or from a file on this computer.
1240        If `api_key` is not null,
1241        this function will automatically assume that the
1242        inputted `api_key` is a valid CFBD API key.
1243
1244    `api_key_dir` (str, optional):
1245        Optional argument.
1246        If `api_key` is set to am empty string, this variable is ignored.
1247        If `api_key_dir` is null, and `api_key` is null,
1248        this function will try to find
1249        a CFBD API key file in this user's home directory.
1250        If `api_key_dir` is set to a string, and `api_key` is null,
1251        this function will assume that `api_key_dir` is a directory,
1252        and will try to find a CFBD API key file in that directory.
1253
1254    `return_as_dict` (bool, semi-optional):
1255        Semi-optional argument.
1256        If you want this function to return
1257        the data as a dictionary (read: JSON object),
1258        instead of a pandas `DataFrame` object,
1259        set `return_as_dict` to `True`.
1260
1261    Usage
1262    ----------
1263    ```
1264    ```
1265    Returns
1266    ----------
1267    A pandas `DataFrame` object with CFBD PBP stat types,
1268    or (if `return_as_dict` is set to `True`)
1269    a dictionary object with CFBD PBP stat types.
1270
1271    """
1272    # now = datetime.now()
1273    plays_df = pd.DataFrame()
1274    plays_df_arr = []
1275    row_df = pd.DataFrame()
1276    url = "https://api.collegefootballdata.com/play/types"
1277
1278    # Input validation
1279    ##########################################################################
1280
1281    if api_key is not None:
1282        real_api_key = api_key
1283        del api_key
1284    else:
1285        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1286
1287    if real_api_key == "tigersAreAwesome":
1288        raise ValueError(
1289            "You actually need to change `cfbd_key` to your CFBD API key."
1290        )
1291    elif "Bearer " in real_api_key:
1292        pass
1293    elif "Bearer" in real_api_key:
1294        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1295    else:
1296        real_api_key = "Bearer " + real_api_key
1297
1298    headers = {
1299        "Authorization": f"{real_api_key}",
1300        "accept": "application/json"
1301    }
1302
1303    response = requests.get(url, headers=headers)
1304
1305    if response.status_code == 200:
1306        pass
1307    elif response.status_code == 401:
1308        raise ConnectionRefusedError(
1309            "Could not connect. The connection was refused." +
1310            "\nHTTP Status Code 401."
1311        )
1312    else:
1313        raise ConnectionError(
1314            f"Could not connect.\nHTTP Status code {response.status_code}"
1315        )
1316
1317    json_data = response.json()
1318
1319    if return_as_dict is True:
1320        return json_data
1321
1322    for p in json_data:
1323        p_id = p["id"]
1324        row_df = pd.DataFrame({"stat_type_id": p_id}, index=[0])
1325        row_df["stat_type_abv"] = p["abbreviation"]
1326        try:
1327            row_df["stat_type_text"] = p["name"]
1328        except KeyError:
1329            row_df["stat_type_text"] = p["text"]
1330        # plays_df = pd.concat([plays_df, row_df], ignore_index=True)
1331        plays_df_arr.append(row_df)
1332
1333        del row_df
1334        del p_id
1335
1336    plays_df = pd.concat(plays_df_arr, ignore_index=True)
1337    return plays_df
1338
1339
1340###############################################################################
1341# Patreon Only Functions.
1342#   No caching, because the entire point of these functions are to get people
1343#   data ASAP, and right before kickoff.
1344###############################################################################
1345
1346
1347def get_cfbd_live_pbp_data(
1348    game_id: int,
1349    api_key: str = None,
1350    api_key_dir: str = None,
1351    # return_as_dict: bool = False,
1352):
1353    """ """
1354    url = f"https://api.collegefootballdata.com/live/plays?id={game_id}"
1355
1356    if api_key is not None:
1357        real_api_key = api_key
1358        del api_key
1359    else:
1360        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1361
1362    if real_api_key == "tigersAreAwesome":
1363        raise ValueError(
1364            "You actually need to change `cfbd_key` to your CFBD API key."
1365        )
1366    elif "Bearer " in real_api_key:
1367        pass
1368    elif "Bearer" in real_api_key:
1369        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1370    else:
1371        real_api_key = "Bearer " + real_api_key
1372
1373    headers = {
1374        "Authorization": f"{real_api_key}",
1375        "accept": "application/json"
1376    }
1377
1378    response = requests.get(url, headers=headers)
1379
1380    if response.status_code == 200:
1381        pass
1382    elif response.status_code == 401:
1383        raise ConnectionRefusedError(
1384            "Could not connect. The connection was refused.\n" +
1385            "HTTP Status Code 401."
1386        )
1387    else:
1388        raise ConnectionError(
1389            f"Could not connect.\nHTTP Status code {response.status_code}"
1390        )
1391
1392    json_data = response.json()
1393    return json_data
def get_cfbd_pbp_data( season: int, week: int, api_key: str = None, api_key_dir: str = None, season_type: str = 'regular', team: str = None, offensive_team: str = None, defensive_team: str = None, conference: str = None, offensive_conference: str = None, defensive_conference: str = None, play_type: int = None, ncaa_division: str = 'fbs', return_as_dict: bool = False):
 19def get_cfbd_pbp_data(
 20    season: int,
 21    week: int,
 22    api_key: str = None,
 23    api_key_dir: str = None,
 24    season_type: str = "regular",
 25    # required if team, offense, or defense, not specified
 26    team: str = None,
 27    offensive_team: str = None,
 28    defensive_team: str = None,
 29    conference: str = None,
 30    offensive_conference: str = None,
 31    defensive_conference: str = None,
 32    play_type: int = None,
 33    ncaa_division: str = "fbs",
 34    return_as_dict: bool = False,
 35):
 36    """
 37    Allows you to get CFB play-by-play (PBP) data from the CFBD API.
 38
 39    Parameters
 40    ----------
 41    `season` (int, mandatory):
 42        Required argument.
 43        Specifies the season you want CFB PBP data from.
 44        This must be specified, otherwise this package, and by extension
 45        the CFBD API, will not accept the request to get CFB PBP data.
 46
 47    `week` (int, optional):
 48        Required argument.
 49        This is the week you want CFB PBP data from.
 50        For a list of valid season-week combinations,
 51        use `cfbd_json_py.games.get_cfbd_season_weeks()`.
 52
 53    `api_key` (str, optional):
 54        Semi-optional argument.
 55        If `api_key` is null, this function will attempt to load a CFBD API key
 56        from the python environment, or from a file on this computer.
 57        If `api_key` is not null,
 58        this function will automatically assume that the
 59        inputted `api_key` is a valid CFBD API key.
 60
 61    `api_key_dir` (str, optional):
 62        Optional argument.
 63        If `api_key` is set to am empty string, this variable is ignored.
 64        If `api_key_dir` is null, and `api_key` is null,
 65        this function will try to find
 66        a CFBD API key file in this user's home directory.
 67        If `api_key_dir` is set to a string, and `api_key` is null,
 68        this function will assume that `api_key_dir` is a directory,
 69        and will try to find a CFBD API key file in that directory.
 70
 71    `week` (int, optional):
 72        Optional argument.
 73        If `week` is set to an integer, this function will attempt
 74        to load CFB poll rankings data from games in that season,
 75        and in that week.
 76
 77    `season_type` (str, semi-optional):
 78        Semi-optional argument.
 79        By default, this will be set to "regular", for the CFB regular season.
 80        If you want CFB poll rankings data for non-regular season games,
 81        set `season_type` to "postseason".
 82        If `season_type` is set to anything but "regular" or "postseason",
 83        a `ValueError()` will be raised.
 84
 85    `offensive_team` (str, optional):
 86        Optional argument.
 87        If you only want CFB drive data from a team, while they are on offense,
 88        regardless if they are the home/away team,
 89        set `team` to the name of the team you want CFB drive data from.
 90
 91    `defensive_team` (str, optional):
 92        Optional argument.
 93        If you only want CFB drive data from a team, while they are on defense,
 94        regardless if they are the home/away team,
 95        set `team` to the name of the team you want CFB drive data from.
 96
 97    `conference` (str, optional):
 98        Optional argument.
 99        If you only want CFB drive data from games
100        involving teams from a specific conference,
101        set `conference` to the abbreviation
102        of the conference you want CFB drive data from.
103        For a list of conferences,
104        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
105        function.
106
107    `offensive_conference` (str, optional):
108        Optional argument.
109        If you only want CFB drive data from games
110        where the offensive team is from a specific conference,
111        set `conference` to the abbreviation
112        of the conference you want CFB drive data from.
113        For a list of conferences,
114        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
115        function.
116
117    `defensive_conference` (str, optional):
118        Optional argument.
119        If you only want CFB drive data from games
120        where the defensive team is from a specific conference,
121        set `conference` to the abbreviation
122        of the conference you want CFB drive data from.
123        For a list of conferences,
124        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
125        function.
126
127    `play_type` (int, optional):
128        Optional argument.
129        If want to drill down, and only get plays of a specific type,
130        (like rushing, passing, kicking plays),
131        set `play_type` to the ID for the play type you want returned.
132        To retrieve a list of valid play type IDs,
133        use `cfbd_json_py.plays.get_cfbd_pbp_play_types()`.
134
135    `ncaa_division` (str, semi-optional):
136        Semi-optional argument.
137        By default, `ncaa_division` will be set to "fbs",
138        short for the Football Bowl Subdivision (FBS),
139        formerly known as D1-A (read as "division one single A"),
140        the highest level in the NCAA football pyramid,
141        where teams can scholarship up to 85 players
142        on their football team solely for athletic ability,
143        and often have the largest athletics budgets
144        within the NCAA.
145
146        Other valid inputs are:
147        - "fcs": Football Championship Subdivision (FCS),
148            formerly known as D1-AA (read as "division one double A").
149            An FCS school is still in the 1st division of the NCAA,
150            making them eligible for the March Madness tournament,
151            but may not have the resources to compete at the FBS level
152            at this time. FCS schools are limited to 63 athletic scholarships
153            for football.
154        - "ii": NCAA Division II. Schools in this and D3 are not
155            eligible for the March Madness tournament,
156            and are limited to 36 athletic scholarships
157            for their football team.
158        - "iii": NCAA Division III. The largest single division within the
159            NCAA football pyramid.
160            D3 schools have the distinction of being part of
161            the only NCAA division that cannot give out scholarships solely
162            for athletic ability.
163
164
165    `return_as_dict` (bool, semi-optional):
166        Semi-optional argument.
167        If you want this function to return
168        the data as a dictionary (read: JSON object),
169        instead of a pandas `DataFrame` object,
170        set `return_as_dict` to `True`.
171
172    Usage
173    ----------
174    ```
175    import time
176
177    from cfbd_json_py.plays import get_cfbd_pbp_data
178
179
180    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
181
182    if cfbd_key != "tigersAreAwesome":
183        print(
184            "Using the user's API key declared in this script " +
185            "for this example."
186        )
187
188        # Get CFB PBP data for
189        # the University of Cincinnati Football Team
190        # for week 10 of the 2021 season
191        print("Get CFB PBP data for week 10 of the 2021 season.")
192        json_data = get_cfbd_pbp_data(
193            api_key=cfbd_key,
194            season=2021,
195            week=10,
196            team="Cincinnati"
197        )
198        print(json_data)
199        time.sleep(5)
200
201        # Get CFB PBP data for when the Ohio State Buckeyes Football Team
202        # was on offense for week 10 of the 2021 season
203        print(
204            "Get CFB PBP data for when the Ohio State Buckeyes " +
205            "Football Team was on offense for week 10 of the 2021 season"
206        )
207        json_data = get_cfbd_pbp_data(
208            api_key=cfbd_key,
209            season=2021,
210            week=10,
211            offensive_team="Ohio State"
212        )
213        print(json_data)
214        time.sleep(5)
215
216        # Get CFB PBP data for when the LSU Tigers Football Team
217        # was on defense for week 10 of the 2021 season
218        print(
219            "Get CFB PBP data for when the LSU Tigers Football Team " +
220            "was on defense for week 10 of the 2021 season"
221        )
222        json_data = get_cfbd_pbp_data(
223            api_key=cfbd_key,
224            season=2021,
225            week=10,
226            defensive_team="LSU"
227        )
228        print(json_data)
229        time.sleep(5)
230
231        # Get CFB PBP data for teams in the Southeastern Conference (SEC)
232        # for week 10 of the 2021 CFB season.
233        print(
234            "Get CFB PBP data for teams in " +
235            "the Southeastern Conference (SEC) " +
236            "for week 10 of the 2021 CFB season."
237        )
238        json_data = get_cfbd_pbp_data(
239            api_key=cfbd_key,
240            season=2021,
241            week=10,
242            conference="SEC"
243        )
244        print(json_data)
245        time.sleep(5)
246
247        # Get CFB PBP data for teams in the Big 10 (B1G) Conference,
248        # while on offense, for week 10 of the 2021 CFB season.
249        print(
250            "Get CFB PBP data for teams in the Big 10 (B1G) Conference " +
251            "while on offense, for week 10 of the 2021 CFB season."
252        )
253        json_data = get_cfbd_pbp_data(
254            api_key=cfbd_key,
255            season=2021,
256            week=10,
257            offensive_conference="B1G"
258        )
259        print(json_data)
260        time.sleep(5)
261
262        # Get CFB PBP data for teams in the Atlantic Coast Conference (ACC),
263        # while on defense, for week 10 of the 2021 CFB season.
264        print(
265            "Get CFB PBP data for teams in " +
266            "the Atlantic Coast Conference (ACC), while on defense, " +
267            "for week 10 of the 2021 CFB season."
268        )
269        json_data = get_cfbd_pbp_data(
270            api_key=cfbd_key,
271            season=2021,
272            week=10,
273            defensive_conference="ACC"
274        )
275        print(json_data)
276        time.sleep(5)
277
278        # Get every run play for week 10 of the 2021 CFB season.
279        print("Get every run play for week 10 of the 2021 CFB season.")
280        json_data = get_cfbd_pbp_data(
281            api_key=cfbd_key,
282            season=2021,
283            week=10,
284            play_type=5 # ID for run plays.
285            # See `cfbd_json_py.plays.get_cfbd_pbp_play_types()`
286            # for a list of play type IDs.
287        )
288        print(json_data)
289        time.sleep(5)
290
291        # Get CFB PBP data for Football Championship Subdivision (FCS)
292        # teams in week 10 of the 2021 CFB season.
293        print(
294            "Get CFB PBP data for Football Championship Subdivision (FCS)" +
295            " teams in week 10 of the 2021 CFB season."
296        )
297        json_data = get_cfbd_pbp_data(
298            api_key=cfbd_key,
299            season=2021,
300            week=10,
301            ncaa_division="fcs"
302        )
303        print(json_data)
304        time.sleep(5)
305
306        # Get CFB PBP data for week 10 of the 2021 season
307        print("Get CFB PBP data for week 10 of the 2021 season.")
308        json_data = get_cfbd_pbp_data(
309            api_key=cfbd_key,
310            season=2021,
311            week=10
312        )
313        print(json_data)
314        time.sleep(5)
315
316        # You can also tell this function to just return the API call as
317        # a Dictionary (read: JSON) object.
318        print(
319            "You can also tell this function to just return the API call " +
320            "as a Dictionary (read: JSON) object."
321        )
322        json_data = get_cfbd_pbp_data(
323            api_key=cfbd_key,
324            season=2020,
325            week=10,
326            defensive_team="LSU",
327            return_as_dict=True
328        )
329        print(json_data)
330
331    else:
332        # Alternatively, if the CFBD API key exists in this python environment,
333        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
334        # you could just call these functions directly,
335        # without setting the API key in the script.
336        print(
337            "Using the user's API key supposedly loaded " +
338            "into this python environment for this example."
339        )
340
341        # Get CFB PBP data for the University of Cincinnati Football Team
342        # for week 10 of the 2021 season
343        print(
344            "Get CFB play-by-play (PBP) data for " +
345            "the University of Cincinnati Football Team " +
346            "for week 10 of the 2021 season"
347        )
348        json_data = get_cfbd_pbp_data(
349            season=2021,
350            week=10,
351            team="Cincinnati"
352        )
353        print(json_data)
354        time.sleep(5)
355
356        # Get CFB PBP data for when the Ohio State Buckeyes Football Team
357        # was on offense for week 10 of the 2021 season
358        print(
359            "Get CFB PBP data for when " +
360            "the Ohio State Buckeyes Football Team was on offense " +
361            "for week 10 of the 2021 season"
362        )
363        json_data = get_cfbd_pbp_data(
364            season=2021,
365            week=10,
366            offensive_team="Ohio State"
367        )
368        print(json_data)
369        time.sleep(5)
370
371        # Get CFB PBP data for when the LSU Tigers Football Team
372        # was on defense for week 10 of the 2021 season
373        print(
374            "Get CFB PBP data for when the LSU Tigers Football Team " +
375            "was on defense for week 10 of the 2021 season"
376        )
377        json_data = get_cfbd_pbp_data(
378            season=2021,
379            week=10,
380            defensive_team="LSU"
381        )
382        print(json_data)
383        time.sleep(5)
384
385        # Get CFB PBP data for teams in the Southeastern Conference (SEC)
386        # for week 10 of the 2021 CFB season.
387        print(
388            "Get CFB PBP data for teams in " +
389            "the Southeastern Conference (SEC) " +
390            "for week 10 of the 2021 CFB season."
391        )
392        json_data = get_cfbd_pbp_data(
393            season=2021,
394            week=10,
395            conference="SEC"
396        )
397        print(json_data)
398        time.sleep(5)
399
400        # Get CFB PBP data for teams in the Big 10 (B1G) Conference,
401        # while on offense, for week 10 of the 2021 CFB season.
402        print(
403            "Get CFB PBP data for teams in the Big 10 (B1G) Conference " +
404            "while on offense, for week 10 of the 2021 CFB season."
405        )
406        json_data = get_cfbd_pbp_data(
407            season=2021,
408            week=10,
409            offensive_conference="B1G"
410        )
411        print(json_data)
412        time.sleep(5)
413
414        # Get CFB PBP data for teams in the Atlantic Coast Conference (ACC),
415        # while on defense, for week 10 of the 2021 CFB season.
416        print(
417            "Get CFB PBP data for teams in " +
418            "the Atlantic Coast Conference (ACC), while on defense, " +
419            "for week 10 of the 2021 CFB season."
420        )
421        json_data = get_cfbd_pbp_data(
422            season=2021,
423            week=10,
424            defensive_conference="ACC"
425        )
426        print(json_data)
427        time.sleep(5)
428
429        # Get every run play for week 10 of the 2021 CFB season.
430        print("Get every run play for week 10 of the 2021 CFB season.")
431        json_data = get_cfbd_pbp_data(
432            season=2021,
433            week=10,
434            play_type=5 # ID for run plays.
435            # See `cfbd_json_py.plays.get_cfbd_pbp_play_types()`
436            # for a list of play type IDs.
437        )
438        print(json_data)
439        time.sleep(5)
440
441        # Get CFB PBP data for Football Championship Subdivision (FCS)
442        # teams in week 10 of the 2021 CFB season.
443        print(
444            "Get CFB PBP data for Football Championship Subdivision (FCS)" +
445            " teams in week 10 of the 2021 CFB season."
446        )
447        json_data = get_cfbd_pbp_data(
448            season=2021,
449            week=10,
450            ncaa_division="fcs"
451        )
452        print(json_data)
453        time.sleep(5)
454
455        # Get CFB PBP data for week 10 of the 2021 season
456        print("Get CFB PBP data for week 10 of the 2021 season.")
457        json_data = get_cfbd_pbp_data(
458            season=2021,
459            week=10
460        )
461        print(json_data)
462        time.sleep(5)
463
464        # You can also tell this function to just return the API call as
465        # a Dictionary (read: JSON) object.
466        print(
467            "You can also tell this function to just return the API call " +
468            "as a Dictionary (read: JSON) object."
469        )
470        json_data = get_cfbd_pbp_data(
471            season=2020,
472            week=10,
473            defensive_team="LSU",
474            return_as_dict=True
475        )
476        print(json_data)
477
478    ```
479    Returns
480    ----------
481    A pandas `DataFrame` object with CFB PBP data,
482    or (if `return_as_dict` is set to `True`)
483    a dictionary object with CFB PBP data.
484
485    """
486
487    now = datetime.now()
488    pbp_df = pd.DataFrame()
489    # row_df = pd.DataFrame()
490    url = "https://api.collegefootballdata.com/plays"
491
492    # Input validation
493    ##########################################################################
494
495    if api_key is not None:
496        real_api_key = api_key
497        del api_key
498    else:
499        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
500
501    if real_api_key == "tigersAreAwesome":
502        raise ValueError(
503            "You actually need to change `cfbd_key` to your CFBD API key."
504        )
505    elif "Bearer " in real_api_key:
506        pass
507    elif "Bearer" in real_api_key:
508        real_api_key = real_api_key.replace("Bearer", "Bearer ")
509    else:
510        real_api_key = "Bearer " + real_api_key
511
512    if season is None:
513        # This should never happen without user tampering, but if it does,
514        # we need to raise an error,
515        # because the CFBD API will refuse this call without a valid season.
516        raise SystemError(
517            "I don't know how, I don't know why, "
518            + "but you managed to call this function "
519            + "while `season` was `None` (NULL),"
520            + " and the function got to this point in the code."
521            + "\nIf you have a GitHub account, "
522            + "please raise an issue on this python package's GitHub page:\n"
523            + "https://github.com/armstjc/cfbd-json-py/issues"
524        )
525    elif season > (now.year + 1):
526        raise ValueError(f"`season` cannot be greater than {season}.")
527    elif season < 1869:
528        raise ValueError("`season` cannot be less than 1869.")
529
530    if season_type != "regular" and season_type != "postseason":
531        raise ValueError(
532            '`season_type` must be set to either ' +
533            '"regular" or "postseason" for this function to work.'
534        )
535
536    if (
537        ncaa_division.lower() == "fbs"
538        or ncaa_division.lower() == "fcs"
539        or ncaa_division.lower() == "ii"
540        or ncaa_division.lower() == "iii"
541    ):
542        pass
543    else:
544        raise ValueError(
545            "An invalid NCAA Division was inputted when calling this function."
546            + '\nValid inputs are:\n-"fbs"\n-"fcs"\n-"ii"\n-"iii"'
547            + f"\n\nYou entered:\n{ncaa_division}"
548        )
549
550    if week is None and (
551        team is None and offensive_team is None and defensive_team is None
552    ):
553        raise ValueError(
554            "If `week` is set to `None` when calling this function, "
555            + "the following variables must be set "
556            + "to a valid non-null variable:"
557            + "\n- `team`"
558            + "\n- `offensive_team`"
559            + "\n- `defensive_team`"
560        )
561    # URL builder
562    ##########################################################################
563
564    # Required by API
565    url += f"?seasonType={season_type}"
566
567    url += f"&year={season}"
568
569    url += f"&week={week}"
570
571    if team is not None:
572        url += f"&team={team}"
573
574    if offensive_team is not None:
575        url += f"&offense={offensive_team}"
576
577    if defensive_team is not None:
578        url += f"&defense={defensive_team}"
579
580    if conference is not None:
581        url += f"&conference={conference}"
582
583    if offensive_conference is not None:
584        url += f"&offenseConference={offensive_conference}"
585
586    if defensive_conference is not None:
587        url += f"&defenseConference={defensive_conference}"
588
589    if ncaa_division is not None:
590        url += f"&classification={ncaa_division}"
591
592    if play_type is not None:
593        url += f"&playType={play_type}"
594
595    headers = {
596        "Authorization": f"{real_api_key}",
597        "accept": "application/json"
598    }
599
600    response = requests.get(url, headers=headers)
601
602    if response.status_code == 200:
603        pass
604    elif response.status_code == 401:
605        raise ConnectionRefusedError(
606            "Could not connect. The connection was refused." +
607            "\nHTTP Status Code 401."
608        )
609    else:
610        raise ConnectionError(
611            f"Could not connect.\nHTTP Status code {response.status_code}"
612        )
613
614    json_data = response.json()
615
616    if return_as_dict is True:
617        return json_data
618
619    pbp_df = pd.json_normalize(json_data)
620    pbp_df.rename(
621        columns={
622            "id": "play_id",
623            "offense": "offensive_team_name",
624            "offense_conference": "offensive_conference_name",
625            "defense": "defensive_team_name",
626            "defense_conference": "defensive_conference_name",
627            "home": "home_team_name",
628            "away": "away_team_name",
629            "clock.minutes": "clock_minutes",
630            "clock.seconds": "clock_seconds",
631        },
632        inplace=True,
633    )
634    return pbp_df

Allows you to get CFB play-by-play (PBP) data from the CFBD API.

Parameters

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

week (int, optional): Required argument. This is the week you want CFB PBP data from. For a list of valid season-week combinations, use cfbd_json_py.games.get_cfbd_season_weeks().

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.

offensive_team (str, optional): Optional argument. If you only want CFB drive data from a team, while they are on offense, regardless if they are the home/away team, set team to the name of the team you want CFB drive data from.

defensive_team (str, optional): Optional argument. If you only want CFB drive data from a team, while they are on defense, regardless if they are the home/away team, set team to the name of the team you want CFB drive data from.

conference (str, optional): Optional argument. If you only want CFB drive data from games involving teams from a specific conference, set conference to the abbreviation of the conference you want CFB drive data from. For a list of conferences, use the cfbd_json_py.conferences.get_cfbd_conference_info() function.

offensive_conference (str, optional): Optional argument. If you only want CFB drive data from games where the offensive team is from a specific conference, set conference to the abbreviation of the conference you want CFB drive data from. For a list of conferences, use the cfbd_json_py.conferences.get_cfbd_conference_info() function.

defensive_conference (str, optional): Optional argument. If you only want CFB drive data from games where the defensive team is from a specific conference, set conference to the abbreviation of the conference you want CFB drive data from. For a list of conferences, use the cfbd_json_py.conferences.get_cfbd_conference_info() function.

play_type (int, optional): Optional argument. If want to drill down, and only get plays of a specific type, (like rushing, passing, kicking plays), set play_type to the ID for the play type you want returned. To retrieve a list of valid play type IDs, use cfbd_json_py.plays.get_cfbd_pbp_play_types().

ncaa_division (str, semi-optional): Semi-optional argument. By default, ncaa_division will be set to "fbs", short for the Football Bowl Subdivision (FBS), formerly known as D1-A (read as "division one single A"), the highest level in the NCAA football pyramid, where teams can scholarship up to 85 players on their football team solely for athletic ability, and often have the largest athletics budgets within the NCAA.

Other valid inputs are:
- "fcs": Football Championship Subdivision (FCS),
    formerly known as D1-AA (read as "division one double A").
    An FCS school is still in the 1st division of the NCAA,
    making them eligible for the March Madness tournament,
    but may not have the resources to compete at the FBS level
    at this time. FCS schools are limited to 63 athletic scholarships
    for football.
- "ii": NCAA Division II. Schools in this and D3 are not
    eligible for the March Madness tournament,
    and are limited to 36 athletic scholarships
    for their football team.
- "iii": NCAA Division III. The largest single division within the
    NCAA football pyramid.
    D3 schools have the distinction of being part of
    the only NCAA division that cannot give out scholarships solely
    for athletic ability.

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.plays import get_cfbd_pbp_data


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 PBP data for
    # the University of Cincinnati Football Team
    # for week 10 of the 2021 season
    print("Get CFB PBP data for week 10 of the 2021 season.")
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        team="Cincinnati"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for when the Ohio State Buckeyes Football Team
    # was on offense for week 10 of the 2021 season
    print(
        "Get CFB PBP data for when the Ohio State Buckeyes " +
        "Football Team was on offense for week 10 of the 2021 season"
    )
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        offensive_team="Ohio State"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for when the LSU Tigers Football Team
    # was on defense for week 10 of the 2021 season
    print(
        "Get CFB PBP data for when the LSU Tigers Football Team " +
        "was on defense for week 10 of the 2021 season"
    )
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        defensive_team="LSU"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for teams in the Southeastern Conference (SEC)
    # for week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for teams in " +
        "the Southeastern Conference (SEC) " +
        "for week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        conference="SEC"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for teams in the Big 10 (B1G) Conference,
    # while on offense, for week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for teams in the Big 10 (B1G) Conference " +
        "while on offense, for week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        offensive_conference="B1G"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for teams in the Atlantic Coast Conference (ACC),
    # while on defense, for week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for teams in " +
        "the Atlantic Coast Conference (ACC), while on defense, " +
        "for week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        defensive_conference="ACC"
    )
    print(json_data)
    time.sleep(5)

    # Get every run play for week 10 of the 2021 CFB season.
    print("Get every run play for week 10 of the 2021 CFB season.")
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        play_type=5 # ID for run plays.
        # See `cfbd_json_py.plays.get_cfbd_pbp_play_types()`
        # for a list of play type IDs.
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for Football Championship Subdivision (FCS)
    # teams in week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for Football Championship Subdivision (FCS)" +
        " teams in week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10,
        ncaa_division="fcs"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for week 10 of the 2021 season
    print("Get CFB PBP data for week 10 of the 2021 season.")
    json_data = get_cfbd_pbp_data(
        api_key=cfbd_key,
        season=2021,
        week=10
    )
    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_pbp_data(
        api_key=cfbd_key,
        season=2020,
        week=10,
        defensive_team="LSU",
        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 PBP data for the University of Cincinnati Football Team
    # for week 10 of the 2021 season
    print(
        "Get CFB play-by-play (PBP) data for " +
        "the University of Cincinnati Football Team " +
        "for week 10 of the 2021 season"
    )
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        team="Cincinnati"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for when the Ohio State Buckeyes Football Team
    # was on offense for week 10 of the 2021 season
    print(
        "Get CFB PBP data for when " +
        "the Ohio State Buckeyes Football Team was on offense " +
        "for week 10 of the 2021 season"
    )
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        offensive_team="Ohio State"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for when the LSU Tigers Football Team
    # was on defense for week 10 of the 2021 season
    print(
        "Get CFB PBP data for when the LSU Tigers Football Team " +
        "was on defense for week 10 of the 2021 season"
    )
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        defensive_team="LSU"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for teams in the Southeastern Conference (SEC)
    # for week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for teams in " +
        "the Southeastern Conference (SEC) " +
        "for week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        conference="SEC"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for teams in the Big 10 (B1G) Conference,
    # while on offense, for week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for teams in the Big 10 (B1G) Conference " +
        "while on offense, for week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        offensive_conference="B1G"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for teams in the Atlantic Coast Conference (ACC),
    # while on defense, for week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for teams in " +
        "the Atlantic Coast Conference (ACC), while on defense, " +
        "for week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        defensive_conference="ACC"
    )
    print(json_data)
    time.sleep(5)

    # Get every run play for week 10 of the 2021 CFB season.
    print("Get every run play for week 10 of the 2021 CFB season.")
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        play_type=5 # ID for run plays.
        # See `cfbd_json_py.plays.get_cfbd_pbp_play_types()`
        # for a list of play type IDs.
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for Football Championship Subdivision (FCS)
    # teams in week 10 of the 2021 CFB season.
    print(
        "Get CFB PBP data for Football Championship Subdivision (FCS)" +
        " teams in week 10 of the 2021 CFB season."
    )
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10,
        ncaa_division="fcs"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP data for week 10 of the 2021 season
    print("Get CFB PBP data for week 10 of the 2021 season.")
    json_data = get_cfbd_pbp_data(
        season=2021,
        week=10
    )
    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_pbp_data(
        season=2020,
        week=10,
        defensive_team="LSU",
        return_as_dict=True
    )
    print(json_data)

Returns

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

def get_cfbd_pbp_play_types( api_key: str = None, api_key_dir: str = None, return_as_dict: bool = False):
637def get_cfbd_pbp_play_types(
638    api_key: str = None,
639    api_key_dir: str = None,
640    return_as_dict: bool = False
641):
642    """
643    Allows you to get CFBD PBP play types from the CFBD API.
644
645    Parameters
646    ----------
647
648    `api_key` (str, optional):
649        Semi-optional argument.
650        If `api_key` is null, this function will attempt to load a CFBD API key
651        from the python environment, or from a file on this computer.
652        If `api_key` is not null,
653        this function will automatically assume that the
654        inputted `api_key` is a valid CFBD API key.
655
656    `api_key_dir` (str, optional):
657        Optional argument.
658        If `api_key` is set to am empty string, this variable is ignored.
659        If `api_key_dir` is null, and `api_key` is null,
660        this function will try to find
661        a CFBD API key file in this user's home directory.
662        If `api_key_dir` is set to a string, and `api_key` is null,
663        this function will assume that `api_key_dir` is a directory,
664        and will try to find a CFBD API key file in that directory.
665
666    `return_as_dict` (bool, semi-optional):
667        Semi-optional argument.
668        If you want this function to return
669        the data as a dictionary (read: JSON object),
670        instead of a pandas `DataFrame` object,
671        set `return_as_dict` to `True`.
672
673    Usage
674    ----------
675    ```
676    ```
677    Returns
678    ----------
679    A pandas `DataFrame` object with CFBD PBP play types,
680    or (if `return_as_dict` is set to `True`)
681    a dictionary object with CFBD PBP play types.
682
683    """
684    # now = datetime.now()
685    plays_df = pd.DataFrame()
686    plays_df_arr = []
687    row_df = pd.DataFrame()
688    url = "https://api.collegefootballdata.com/play/types"
689
690    # Input validation
691    ##########################################################################
692
693    if api_key is not None:
694        real_api_key = api_key
695        del api_key
696    else:
697        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
698
699    if real_api_key == "tigersAreAwesome":
700        raise ValueError(
701            "You actually need to change `cfbd_key` to your CFBD API key."
702        )
703    elif "Bearer " in real_api_key:
704        pass
705    elif "Bearer" in real_api_key:
706        real_api_key = real_api_key.replace("Bearer", "Bearer ")
707    else:
708        real_api_key = "Bearer " + real_api_key
709
710    headers = {
711        "Authorization": f"{real_api_key}",
712        "accept": "application/json"
713    }
714
715    response = requests.get(url, headers=headers)
716
717    if response.status_code == 200:
718        pass
719    elif response.status_code == 401:
720        raise ConnectionRefusedError(
721            "Could not connect. The connection was refused." +
722            "\nHTTP Status Code 401."
723        )
724    else:
725        raise ConnectionError(
726            f"Could not connect.\nHTTP Status code {response.status_code}"
727        )
728
729    json_data = response.json()
730
731    if return_as_dict is True:
732        return json_data
733
734    for p in json_data:
735        p_id = p["id"]
736        row_df = pd.DataFrame({"play_type_id": p_id}, index=[0])
737        row_df["play_type_text"] = p["text"]
738        row_df["play_type_abv"] = p["abbreviation"]
739        # plays_df = pd.concat([plays_df, row_df], ignore_index=True)
740        plays_df_arr.append(row_df)
741        del row_df
742        del p_id
743
744    plays_df = pd.concat(plays_df_arr, ignore_index=True)
745    return plays_df

Allows you to get CFBD PBP play types from the CFBD API.

Parameters

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.

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


Returns

A pandas DataFrame object with CFBD PBP play types, or (if return_as_dict is set to True) a dictionary object with CFBD PBP play types.

def get_cfbd_pbp_stats( api_key: str = None, api_key_dir: str = None, season: int = None, week: int = None, team: str = None, game_id: int = None, athlete_id: int = None, stat_type_id: int = None, season_type: str = 'both', conference: str = None, return_as_dict: bool = False):
 748def get_cfbd_pbp_stats(
 749    api_key: str = None,
 750    api_key_dir: str = None,
 751    season: int = None,
 752    week: int = None,
 753    team: str = None,
 754    game_id: int = None,
 755    athlete_id: int = None,
 756    stat_type_id: int = None,
 757    season_type: str = "both",  # "regular", "postseason", or "both"
 758    conference: str = None,
 759    return_as_dict: bool = False,
 760):
 761    """
 762    Allows you to get stats for various players
 763    from CFB play-by-play (PBP) data within the CFBD API.
 764
 765    Parameters
 766    ----------
 767
 768    `api_key` (str, optional):
 769        Semi-optional argument.
 770        If `api_key` is null, this function will attempt to load a CFBD API key
 771        from the python environment, or from a file on this computer.
 772        If `api_key` is not null,
 773        this function will automatically assume that the
 774        inputted `api_key` is a valid CFBD API key.
 775
 776    `api_key_dir` (str, optional):
 777        Optional argument.
 778        If `api_key` is set to am empty string, this variable is ignored.
 779        If `api_key_dir` is null, and `api_key` is null,
 780        this function will try to find
 781        a CFBD API key file in this user's home directory.
 782        If `api_key_dir` is set to a string, and `api_key` is null,
 783        this function will assume that `api_key_dir` is a directory,
 784        and will try to find a CFBD API key file in that directory.
 785
 786    `season` (int, optional):
 787        Semi-optional argument.
 788        Specifies the season you want CFB PBP data from.
 789        This must be specified, otherwise this package, and by extension
 790        the CFBD API, will not accept the request to get CFB PBP data.
 791
 792    `week` (int, optional):
 793        Optional argument.
 794        If `week` is set to an integer, this function will attempt
 795        to load CFB poll rankings data from games in that season,
 796        and in that week.
 797
 798    `team` (str, optional):
 799        Optional argument.
 800        If you only want stats for a specific team,
 801        set `team` to the name of that specific team.
 802
 803    `game_id` (int, optional):
 804        Optional argument.
 805        If you only want stats for a specific game,
 806        set `game_id` to the ID of that specific game.
 807
 808    `athlete_id` (int, optional):
 809        Optional argument.
 810        If you only want stats for a specific player,
 811        set `athlete_id` to the ID of the player you want stats for.
 812
 813    `stats_type_id` (int, optional):
 814        Optional argument.
 815        If want to drill down, and only get plays of a specific type,
 816        (like rushing, passing, kicking plays),
 817        set `play_type` to the ID for the play type you want returned.
 818        To retrieve a list of valid play type IDs,
 819        use `cfbd_json_py.plays.get_cfbd_pbp_play_types()`.
 820
 821    `season_type` (str, semi-optional):
 822        Semi-optional argument.
 823        By default, this will be set to "regular", for the CFB regular season.
 824        If you want CFB poll rankings data for non-regular season games,
 825        set `season_type` to "postseason".
 826        If `season_type` is set to anything but "regular" or "postseason",
 827        a `ValueError()` will be raised.
 828
 829    `conference` (str, optional):
 830        Optional argument.
 831        If you only want CFB drive data from games
 832        involving teams from a specific conference,
 833        set `conference` to the abbreviation
 834        of the conference you want CFB drive data from.
 835        For a list of conferences,
 836        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 837        function.
 838
 839    `return_as_dict` (bool, semi-optional):
 840        Semi-optional argument.
 841        If you want this function to return
 842        the data as a dictionary (read: JSON object),
 843        instead of a pandas `DataFrame` object,
 844        set `return_as_dict` to `True`.
 845
 846    Usage
 847    ----------
 848    ```
 849    import time
 850
 851    from cfbd_json_py.plays import get_cfbd_pbp_stats
 852
 853
 854    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 855
 856    if cfbd_key != "tigersAreAwesome":
 857        print(
 858            "Using the user's API key declared in this script " +
 859            "for this example."
 860        )
 861
 862        # Get CFB PBP stats data for the 2020 CFB season.
 863        print("Get CFB PBP stats data for the 2020 CFB season.")
 864        json_data = get_cfbd_pbp_stats(
 865            api_key=cfbd_key,
 866            season=2020
 867        )
 868        print(json_data)
 869        time.sleep(5)
 870
 871        # Get CFB PBP stats data for week 10 of the 2020 CFB season.
 872        print("Get CFB PBP stats data for week 10 of the 2020 CFB season.")
 873        json_data = get_cfbd_pbp_stats(
 874            api_key=cfbd_key,
 875            season=2020,
 876            week=10
 877        )
 878        print(json_data)
 879        time.sleep(5)
 880
 881        # Get CFB PBP stats data for a 2019 game between
 882        # the Ohio State Buckeyes and Clemson Tigers football teams.
 883        print(
 884            "Get CFB PBP stats data for a 2019 game between " +
 885            "the Ohio State Buckeyes and Clemson Tigers football teams."
 886        )
 887        json_data = get_cfbd_pbp_stats(
 888            api_key=cfbd_key,
 889            game_id=401135279
 890        )
 891        print(json_data)
 892        time.sleep(5)
 893
 894        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
 895        # during the 2020 CFB Season.
 896        print("Get CFB PBP stats data for the 2020 CFB season.")
 897        json_data = get_cfbd_pbp_stats(
 898            api_key=cfbd_key,
 899            season=2020,
 900            athlete_id=4360310
 901        )
 902        print(json_data)
 903        time.sleep(5)
 904
 905        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
 906        # during the 2020 CFB Season,
 907        # but only return plays where Lawrence scored a touchdown.
 908        print("Get CFB PBP stats data for the 2020 CFB season.")
 909        json_data = get_cfbd_pbp_stats(
 910            api_key=cfbd_key,
 911            season=2020,
 912            athlete_id=4360310,
 913            stat_type_id=22
 914        )
 915        print(json_data)
 916        time.sleep(5)
 917
 918        # Get CFB PBP stats data for the 2020 CFB season,
 919        # but only for postseason games.
 920        print("Get CFB PBP stats data for the 2020 CFB season.")
 921        json_data = get_cfbd_pbp_stats(
 922            api_key=cfbd_key,
 923            season=2020,
 924            season_type="postseason"
 925        )
 926        print(json_data)
 927        time.sleep(5)
 928
 929        # Get CFB PBP stats data for the 2020 CFB season,
 930        # but only for Big 10 (B1G) games.
 931        print("Get CFB PBP stats data for the 2020 CFB season.")
 932        json_data = get_cfbd_pbp_stats(
 933            api_key=cfbd_key,
 934            season=2020,
 935            conference="B1G"
 936        )
 937        print(json_data)
 938        time.sleep(5)
 939
 940        # Get CFB PBP stats data for the 2020 CFB season.
 941        print("Get CFB PBP stats data for the 2020 CFB season.")
 942        json_data = get_cfbd_pbp_stats(
 943            api_key=cfbd_key,
 944            season=2020
 945        )
 946        print(json_data)
 947        time.sleep(5)
 948
 949        # You can also tell this function to just return the API call as
 950        # a Dictionary (read: JSON) object.
 951        print(
 952            "You can also tell this function to just return the API call " +
 953            "as a Dictionary (read: JSON) object."
 954        )
 955        json_data = get_cfbd_pbp_stats(
 956            api_key=cfbd_key,
 957            season=2020,
 958            week=10,
 959            return_as_dict=True
 960        )
 961        print(json_data)
 962
 963    else:
 964        # Alternatively, if the CFBD API key exists in this python environment,
 965        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 966        # you could just call these functions directly,
 967        # without setting the API key in the script.
 968        print(
 969            "Using the user's API key supposedly loaded " +
 970            "into this python environment for this example."
 971        )
 972
 973        # Get CFB PBP stats data for the 2020 CFB season.
 974        print("Get CFB PBP stats data for the 2020 CFB season.")
 975        json_data = get_cfbd_pbp_stats(
 976            season=2020
 977        )
 978        print(json_data)
 979        time.sleep(5)
 980
 981        # Get CFB PBP stats data for week 10 of the 2020 CFB season.
 982        print("Get CFB PBP stats data for week 10 of the 2020 CFB season.")
 983        json_data = get_cfbd_pbp_stats(
 984            season=2020,
 985            week=10
 986        )
 987        print(json_data)
 988        time.sleep(5)
 989
 990        # Get CFB PBP stats data for a 2019 game between
 991        # the Ohio State Buckeyes and Clemson Tigers football teams.
 992        print(
 993            "Get CFB PBP stats data for a 2019 game between " +
 994            "the Ohio State Buckeyes and Clemson Tigers football teams."
 995        )
 996        json_data = get_cfbd_pbp_stats(
 997            game_id=401135279
 998        )
 999        print(json_data)
1000        time.sleep(5)
1001
1002        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
1003        # during the 2020 CFB Season.
1004        print("Get CFB PBP stats data for the 2020 CFB season.")
1005        json_data = get_cfbd_pbp_stats(
1006            season=2020,
1007            athlete_id=4360310
1008        )
1009        print(json_data)
1010        time.sleep(5)
1011
1012        # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
1013        # during the 2020 CFB Season,
1014        # but only return plays where Lawrence scored a touchdown.
1015        print("Get CFB PBP stats data for the 2020 CFB season.")
1016        json_data = get_cfbd_pbp_stats(
1017            season=2020,
1018            athlete_id=4360310,
1019            stat_type_id=22
1020        )
1021        print(json_data)
1022        time.sleep(5)
1023
1024        # Get CFB PBP stats data for the 2020 CFB season,
1025        # but only for postseason games.
1026        print("Get CFB PBP stats data for the 2020 CFB season.")
1027        json_data = get_cfbd_pbp_stats(
1028            season=2020,
1029            season_type="postseason"
1030        )
1031        print(json_data)
1032        time.sleep(5)
1033
1034        # Get CFB PBP stats data for the 2020 CFB season,
1035        # but only for Big 10 (B1G) games.
1036        print("Get CFB PBP stats data for the 2020 CFB season.")
1037        json_data = get_cfbd_pbp_stats(
1038            season=2020,
1039            conference="B1G"
1040        )
1041        print(json_data)
1042        time.sleep(5)
1043
1044        # You can also tell this function to just return the API call as
1045        # a Dictionary (read: JSON) object.
1046        print(
1047            "You can also tell this function to just return the API call " +
1048            "as a Dictionary (read: JSON) object."
1049        )
1050        json_data = get_cfbd_pbp_stats(
1051            season=2020,
1052            week=10,
1053            return_as_dict=True
1054        )
1055        print(json_data)
1056
1057    ```
1058    Returns
1059    ----------
1060    A pandas `DataFrame` object with CFB PBP data,
1061    or (if `return_as_dict` is set to `True`)
1062    a dictionary object with CFB PBP data.
1063
1064    """
1065    now = datetime.now()
1066    pbp_df = pd.DataFrame()
1067    url = "https://api.collegefootballdata.com/play/stats"
1068
1069    # Input validation
1070    ##########################################################################
1071
1072    if api_key is not None:
1073        real_api_key = api_key
1074        del api_key
1075    else:
1076        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1077
1078    if real_api_key == "tigersAreAwesome":
1079        raise ValueError(
1080            "You actually need to change `cfbd_key` to your CFBD API key."
1081        )
1082    elif "Bearer " in real_api_key:
1083        pass
1084    elif "Bearer" in real_api_key:
1085        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1086    else:
1087        real_api_key = "Bearer " + real_api_key
1088
1089    if season is not None and (season > (now.year + 1)):
1090        raise ValueError(f"`season` cannot be greater than {season}.")
1091    elif season is not None and season < 1869:
1092        raise ValueError("`season` cannot be less than 1869.")
1093
1094    if (
1095        season_type != "regular"
1096        and season_type != "postseason"
1097        and season_type != "both"
1098    ):
1099        raise ValueError(
1100            '`season_type` must be set to either ' +
1101            '"regular", "postseason", or "both" for this function to work.'
1102        )
1103
1104    if season is None and game_id is None:
1105        logging.warning(
1106            "This endpoint only returns the top 1,000 results. "
1107            + "Not setting a value for `season` or `game_id` "
1108            + "is not a recommended practice."
1109        )
1110    elif (
1111        (season is not None) and
1112        (game_id is not None)
1113    ):
1114        logging.warning(
1115            "Setting a value for both `season` and `game_id` "
1116            + "may not yeld the results you want. "
1117            + "If you just want PBP stats for a valid game ID, "
1118            + "just set `game_id` to a valid game ID."
1119        )
1120
1121    # URL builder
1122    ##########################################################################
1123
1124    url_elements = 0
1125
1126    if season_type is not None and url_elements == 0:
1127        url += f"?seasonType={season_type}"
1128        url_elements += 1
1129    elif season_type is not None:
1130        url += f"&seasonType={season_type}"
1131        url_elements += 1
1132
1133    if season is not None and url_elements == 0:
1134        url += f"?year={season}"
1135        url_elements += 1
1136    elif season is not None:
1137        url += f"&year={season}"
1138        url_elements += 1
1139
1140    if week is not None and url_elements == 0:
1141        url += f"?week={week}"
1142        url_elements += 1
1143    elif week is not None:
1144        url += f"&week={week}"
1145        url_elements += 1
1146
1147    if team is not None and url_elements == 0:
1148        url += f"?team={team}"
1149        url_elements += 1
1150    elif team is not None:
1151        url += f"&team={team}"
1152        url_elements += 1
1153
1154    if conference is not None and url_elements == 0:
1155        url += f"&conference={conference}"
1156        url_elements += 1
1157    elif conference is not None:
1158        url += f"&conference={conference}"
1159        url_elements += 1
1160
1161    if game_id is not None and url_elements == 0:
1162        url += f"&gameId={game_id}"
1163        url_elements += 1
1164    elif game_id is not None:
1165        url += f"&gameId={game_id}"
1166        url_elements += 1
1167
1168    if athlete_id is not None and url_elements == 0:
1169        url += f"&athleteId={athlete_id}"
1170        url_elements += 1
1171    elif athlete_id is not None:
1172        url += f"&athleteId={athlete_id}"
1173        url_elements += 1
1174
1175    if stat_type_id is not None and url_elements == 0:
1176        url += f"&statTypeId={stat_type_id}"
1177        url_elements += 1
1178    elif stat_type_id is not None:
1179        url += f"&statTypeId={stat_type_id}"
1180        url_elements += 1
1181
1182    headers = {
1183        "Authorization": f"{real_api_key}",
1184        "accept": "application/json"
1185    }
1186
1187    response = requests.get(url, headers=headers)
1188
1189    if response.status_code == 200:
1190        pass
1191    elif response.status_code == 401:
1192        raise ConnectionRefusedError(
1193            "Could not connect. The connection was refused." +
1194            "\nHTTP Status Code 401."
1195        )
1196    else:
1197        raise ConnectionError(
1198            f"Could not connect.\nHTTP Status code {response.status_code}"
1199        )
1200
1201    json_data = response.json()
1202
1203    if return_as_dict is True:
1204        return json_data
1205
1206    pbp_df = pd.json_normalize(json_data)
1207    pbp_df.rename(
1208        columns={
1209            "gameId": "game_id",
1210            "teamScore": "team_score",
1211            "opponentScore": "opponent_score",
1212            "driveId": "drive_id",
1213            "playId": "play_id",
1214            "yardsToGoal": "yards_to_goal",
1215            "athleteId": "athlete_id",
1216            "athleteName": "athlete_name",
1217            "statType": "stat_type",
1218        },
1219        inplace=True,
1220    )
1221    # TODO: Implement an option to put all stats for
1222    # a specific game on a single line.
1223    return pbp_df

Allows you to get stats for various players from CFB play-by-play (PBP) data within the CFBD API.

Parameters

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.

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

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.

team (str, optional): Optional argument. If you only want stats for a specific team, set team to the name of that specific team.

game_id (int, optional): Optional argument. If you only want stats for a specific game, set game_id to the ID of that specific game.

athlete_id (int, optional): Optional argument. If you only want stats for a specific player, set athlete_id to the ID of the player you want stats for.

stats_type_id (int, optional): Optional argument. If want to drill down, and only get plays of a specific type, (like rushing, passing, kicking plays), set play_type to the ID for the play type you want returned. To retrieve a list of valid play type IDs, use cfbd_json_py.plays.get_cfbd_pbp_play_types().

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.

conference (str, optional): Optional argument. If you only want CFB drive data from games involving teams from a specific conference, set conference to the abbreviation of the conference you want CFB drive data from. For a list of conferences, use the cfbd_json_py.conferences.get_cfbd_conference_info() function.

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.plays import get_cfbd_pbp_stats


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 PBP stats data for the 2020 CFB season.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for week 10 of the 2020 CFB season.
    print("Get CFB PBP stats data for week 10 of the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        season=2020,
        week=10
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for a 2019 game between
    # the Ohio State Buckeyes and Clemson Tigers football teams.
    print(
        "Get CFB PBP stats data for a 2019 game between " +
        "the Ohio State Buckeyes and Clemson Tigers football teams."
    )
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        game_id=401135279
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
    # during the 2020 CFB Season.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        season=2020,
        athlete_id=4360310
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
    # during the 2020 CFB Season,
    # but only return plays where Lawrence scored a touchdown.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        season=2020,
        athlete_id=4360310,
        stat_type_id=22
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for the 2020 CFB season,
    # but only for postseason games.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        season=2020,
        season_type="postseason"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for the 2020 CFB season,
    # but only for Big 10 (B1G) games.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        season=2020,
        conference="B1G"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for the 2020 CFB season.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        api_key=cfbd_key,
        season=2020
    )
    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_pbp_stats(
        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 PBP stats data for the 2020 CFB season.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for week 10 of the 2020 CFB season.
    print("Get CFB PBP stats data for week 10 of the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        season=2020,
        week=10
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for a 2019 game between
    # the Ohio State Buckeyes and Clemson Tigers football teams.
    print(
        "Get CFB PBP stats data for a 2019 game between " +
        "the Ohio State Buckeyes and Clemson Tigers football teams."
    )
    json_data = get_cfbd_pbp_stats(
        game_id=401135279
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
    # during the 2020 CFB Season.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        season=2020,
        athlete_id=4360310
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for Trevor Lawrence (athlete ID #4360310)
    # during the 2020 CFB Season,
    # but only return plays where Lawrence scored a touchdown.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        season=2020,
        athlete_id=4360310,
        stat_type_id=22
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for the 2020 CFB season,
    # but only for postseason games.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        season=2020,
        season_type="postseason"
    )
    print(json_data)
    time.sleep(5)

    # Get CFB PBP stats data for the 2020 CFB season,
    # but only for Big 10 (B1G) games.
    print("Get CFB PBP stats data for the 2020 CFB season.")
    json_data = get_cfbd_pbp_stats(
        season=2020,
        conference="B1G"
    )
    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_pbp_stats(
        season=2020,
        week=10,
        return_as_dict=True
    )
    print(json_data)

Returns

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

def get_cfbd_pbp_stat_types( api_key: str = None, api_key_dir: str = None, return_as_dict: bool = False):
1226def get_cfbd_pbp_stat_types(
1227    api_key: str = None,
1228    api_key_dir: str = None,
1229    return_as_dict: bool = False
1230):
1231    """
1232    Allows you to get CFBD PBP stat types from the CFBD API.
1233
1234    Parameters
1235    ----------
1236
1237    `api_key` (str, optional):
1238        Semi-optional argument.
1239        If `api_key` is null, this function will attempt to load a CFBD API key
1240        from the python environment, or from a file on this computer.
1241        If `api_key` is not null,
1242        this function will automatically assume that the
1243        inputted `api_key` is a valid CFBD API key.
1244
1245    `api_key_dir` (str, optional):
1246        Optional argument.
1247        If `api_key` is set to am empty string, this variable is ignored.
1248        If `api_key_dir` is null, and `api_key` is null,
1249        this function will try to find
1250        a CFBD API key file in this user's home directory.
1251        If `api_key_dir` is set to a string, and `api_key` is null,
1252        this function will assume that `api_key_dir` is a directory,
1253        and will try to find a CFBD API key file in that directory.
1254
1255    `return_as_dict` (bool, semi-optional):
1256        Semi-optional argument.
1257        If you want this function to return
1258        the data as a dictionary (read: JSON object),
1259        instead of a pandas `DataFrame` object,
1260        set `return_as_dict` to `True`.
1261
1262    Usage
1263    ----------
1264    ```
1265    ```
1266    Returns
1267    ----------
1268    A pandas `DataFrame` object with CFBD PBP stat types,
1269    or (if `return_as_dict` is set to `True`)
1270    a dictionary object with CFBD PBP stat types.
1271
1272    """
1273    # now = datetime.now()
1274    plays_df = pd.DataFrame()
1275    plays_df_arr = []
1276    row_df = pd.DataFrame()
1277    url = "https://api.collegefootballdata.com/play/types"
1278
1279    # Input validation
1280    ##########################################################################
1281
1282    if api_key is not None:
1283        real_api_key = api_key
1284        del api_key
1285    else:
1286        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1287
1288    if real_api_key == "tigersAreAwesome":
1289        raise ValueError(
1290            "You actually need to change `cfbd_key` to your CFBD API key."
1291        )
1292    elif "Bearer " in real_api_key:
1293        pass
1294    elif "Bearer" in real_api_key:
1295        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1296    else:
1297        real_api_key = "Bearer " + real_api_key
1298
1299    headers = {
1300        "Authorization": f"{real_api_key}",
1301        "accept": "application/json"
1302    }
1303
1304    response = requests.get(url, headers=headers)
1305
1306    if response.status_code == 200:
1307        pass
1308    elif response.status_code == 401:
1309        raise ConnectionRefusedError(
1310            "Could not connect. The connection was refused." +
1311            "\nHTTP Status Code 401."
1312        )
1313    else:
1314        raise ConnectionError(
1315            f"Could not connect.\nHTTP Status code {response.status_code}"
1316        )
1317
1318    json_data = response.json()
1319
1320    if return_as_dict is True:
1321        return json_data
1322
1323    for p in json_data:
1324        p_id = p["id"]
1325        row_df = pd.DataFrame({"stat_type_id": p_id}, index=[0])
1326        row_df["stat_type_abv"] = p["abbreviation"]
1327        try:
1328            row_df["stat_type_text"] = p["name"]
1329        except KeyError:
1330            row_df["stat_type_text"] = p["text"]
1331        # plays_df = pd.concat([plays_df, row_df], ignore_index=True)
1332        plays_df_arr.append(row_df)
1333
1334        del row_df
1335        del p_id
1336
1337    plays_df = pd.concat(plays_df_arr, ignore_index=True)
1338    return plays_df

Allows you to get CFBD PBP stat types from the CFBD API.

Parameters

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.

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


Returns

A pandas DataFrame object with CFBD PBP stat types, or (if return_as_dict is set to True) a dictionary object with CFBD PBP stat types.

def get_cfbd_live_pbp_data(game_id: int, api_key: str = None, api_key_dir: str = None):
1348def get_cfbd_live_pbp_data(
1349    game_id: int,
1350    api_key: str = None,
1351    api_key_dir: str = None,
1352    # return_as_dict: bool = False,
1353):
1354    """ """
1355    url = f"https://api.collegefootballdata.com/live/plays?id={game_id}"
1356
1357    if api_key is not None:
1358        real_api_key = api_key
1359        del api_key
1360    else:
1361        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1362
1363    if real_api_key == "tigersAreAwesome":
1364        raise ValueError(
1365            "You actually need to change `cfbd_key` to your CFBD API key."
1366        )
1367    elif "Bearer " in real_api_key:
1368        pass
1369    elif "Bearer" in real_api_key:
1370        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1371    else:
1372        real_api_key = "Bearer " + real_api_key
1373
1374    headers = {
1375        "Authorization": f"{real_api_key}",
1376        "accept": "application/json"
1377    }
1378
1379    response = requests.get(url, headers=headers)
1380
1381    if response.status_code == 200:
1382        pass
1383    elif response.status_code == 401:
1384        raise ConnectionRefusedError(
1385            "Could not connect. The connection was refused.\n" +
1386            "HTTP Status Code 401."
1387        )
1388    else:
1389        raise ConnectionError(
1390            f"Could not connect.\nHTTP Status code {response.status_code}"
1391        )
1392
1393    json_data = response.json()
1394    return json_data