cfbd_json_py.stats

   1# Creation Date: 08/30/2023 01:13 PM EDT
   2# Last Updated Date: 09/16/2024 06:10 PM EDT
   3# Author: Joseph Armstrong (armstrongjoseph08@gmail.com)
   4# File Name: stats.py
   5# Purpose: Houses functions pertaining to CFB team/player
   6#    stats data within the CFBD API.
   7###############################################################################
   8
   9import logging
  10from datetime import datetime
  11
  12import pandas as pd
  13import requests
  14from tqdm import tqdm
  15
  16from cfbd_json_py.utls import get_cfbd_api_token
  17
  18
  19def get_cfbd_team_season_stats(
  20    api_key: str = None,
  21    api_key_dir: str = None,
  22    season: int = None,
  23    team: str = None,
  24    # `year` and/or `team` need to be not null for this function to work.
  25    conference: str = None,
  26    start_week: int = None,
  27    end_week: int = None,
  28    return_as_dict: bool = False,
  29    use_original_column_names: bool = False,
  30):
  31    """
  32    Allows you to get CFB team season stats data from the CFBD API.
  33
  34    Parameters
  35    ----------
  36
  37    `api_key` (str, optional):
  38        Semi-optional argument.
  39        If `api_key` is null, this function will attempt to load a CFBD API key
  40        from the python environment, or from a file on this computer.
  41        If `api_key` is not null,
  42        this function will automatically assume that the
  43        inputted `api_key` is a valid CFBD API key.
  44
  45    `api_key_dir` (str, optional):
  46        Optional argument.
  47        If `api_key` is set to am empty string, this variable is ignored.
  48        If `api_key_dir` is null, and `api_key` is null,
  49        this function will try to find
  50        a CFBD API key file in this user's home directory.
  51        If `api_key_dir` is set to a string, and `api_key` is null,
  52        this function will assume that `api_key_dir` is a directory,
  53        and will try to find a CFBD API key file in that directory.
  54
  55    `season` (int, semi-mandatory):
  56        Semi-required argument.
  57        Specifies the season you want CFB team season stats data from.
  58        This must be specified, otherwise this package, and by extension
  59        the CFBD API, will not accept
  60        the request to get CFB team season stats data.
  61        This or `team` must be set
  62        to a valid non-null variable for this to function.
  63
  64    `team` (str, semi-mandatory):
  65        Semi-required argument.
  66        Specifies the season you want CFB team season stats data from.
  67        This must be specified, otherwise this package, and by extension
  68        the CFBD API, will not accept
  69        the request to get CFB team season stats data.
  70        This or `season` must be set
  71        to a valid non-null variable for this to function.
  72
  73    `conference` (str, optional):
  74        Optional argument.
  75        If you only want team season stats from games
  76        involving teams a specific conference,
  77        set `conference` to the abbreviation
  78        of the conference you want stats from.
  79
  80    `start_week` (int, semi-optional):
  81        Optional argument.
  82        If you only want team stats for a range of weeks,
  83        set `start_week` and `end_week` to
  84        the range of weeks you want season-level data for.
  85
  86    `end_week` (int, semi-optional):
  87        Optional argument.
  88        If you only want team stats for a range of weeks,
  89        set `start_week` and `end_week` to
  90        the range of weeks you want season-level data for.
  91
  92    **NOTE**: If the following conditions are `True`, a `ValueError()`
  93    will be raised when calling this function:
  94    - `start_week < 0`
  95    - `end_week < 0`
  96    - `start_week is not None and end_week is None`
  97        (will be changed in a future version)
  98    - `start_week is None and end_week is not None`
  99        (will be changed in a future version)
 100    - `end_week < start_week`
 101    - `end_week = start_week`
 102
 103    `return_as_dict` (bool, semi-optional):
 104        Semi-optional argument.
 105        If you want this function to return
 106        the data as a dictionary (read: JSON object),
 107        instead of a pandas `DataFrame` object,
 108        set `return_as_dict` to `True`.
 109
 110
 111    Usage
 112    ----------
 113    ```
 114    import time
 115
 116    from cfbd_json_py.stats import get_cfbd_team_season_stats
 117
 118
 119    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 120
 121    if cfbd_key != "tigersAreAwesome":
 122        print(
 123            "Using the user's API key declared in this script " +
 124            "for this example."
 125        )
 126
 127        # Get team season stats for the 2020 CFB season.
 128        print("Get team season stats for the 2020 CFB season.")
 129        json_data = get_cfbd_team_season_stats(
 130            api_key=cfbd_key,
 131            season=2020
 132        )
 133        print(json_data)
 134        time.sleep(5)
 135
 136
 137        # Get team season stats for teams competing in
 138        # the Big 10 (B1G) conference the 2020 CFB season.
 139        print(
 140            "Get team season stats for teams competing in " +
 141            "the Big 10 (B1G) conference the 2020 CFB season."
 142        )
 143        json_data = get_cfbd_team_season_stats(
 144            api_key=cfbd_key,
 145            conference="B1G",
 146            season=2020
 147        )
 148        print(json_data)
 149        time.sleep(5)
 150
 151        # Get team season stats for the 2020 CFB season,
 152        # but only between weeks 5 and 10.
 153        print("Get team season stats for the 2020 CFB season.")
 154        json_data = get_cfbd_team_season_stats(
 155            api_key=cfbd_key,
 156            season=2020,
 157            start_week=5,
 158            end_week=10
 159        )
 160        print(json_data)
 161        time.sleep(5)
 162
 163        # You can also tell this function to just return the API call as
 164        # a Dictionary (read: JSON) object.
 165        print(
 166            "You can also tell this function to just return the API call " +
 167            "as a Dictionary (read: JSON) object."
 168        )
 169        json_data = get_cfbd_team_season_stats(
 170            api_key=cfbd_key,
 171            season=2020,
 172            return_as_dict=True
 173        )
 174        print(json_data)
 175
 176    else:
 177        # Alternatively, if the CFBD API key exists in this python environment,
 178        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 179        # you could just call these functions directly,
 180        # without setting the API key in the script.
 181        print(
 182            "Using the user's API key supposedly loaded " +
 183            "into this python environment for this example."
 184        )
 185
 186
 187        # Get team season stats for the 2020 CFB season.
 188        print("Get team season stats for the 2020 CFB season.")
 189        json_data = get_cfbd_team_season_stats(
 190            season=2020
 191        )
 192        print(json_data)
 193        time.sleep(5)
 194
 195
 196        # Get team season stats for teams competing in
 197        # the Big 10 (B1G) conference the 2020 CFB season.
 198        print(
 199            "Get team season stats for teams competing in " +
 200            "the Big 10 (B1G) conference the 2020 CFB season."
 201        )
 202        json_data = get_cfbd_team_season_stats(
 203            conference="B1G",
 204            season=2020
 205        )
 206        print(json_data)
 207        time.sleep(5)
 208
 209        # Get team season stats for the 2020 CFB season,
 210        # but only between weeks 5 and 10.
 211        print("Get team season stats for the 2020 CFB season.")
 212        json_data = get_cfbd_team_season_stats(
 213            season=2020,
 214            start_week=5,
 215            end_week=10
 216        )
 217        print(json_data)
 218        time.sleep(5)
 219
 220        # You can also tell this function to just return the API call as
 221        # a Dictionary (read: JSON) object.
 222        print(
 223            "You can also tell this function to just return the API call " +
 224            "as a Dictionary (read: JSON) object."
 225        )
 226        json_data = get_cfbd_team_season_stats(
 227            season=2020,
 228            return_as_dict=True
 229        )
 230        print(json_data)
 231    ```
 232    Returns
 233    ----------
 234    A pandas `DataFrame` object with team season stats data,
 235    or (if `return_as_dict` is set to `True`)
 236    a dictionary object with a with team season stats data.
 237
 238    """
 239
 240    rebuilt_json = {}
 241    stat_columns = [
 242        "season",
 243        "team_name",
 244        "conference_name",
 245        "games",
 246        # Passing
 247        "passing_COMP",
 248        "passing_ATT",
 249        "passing_NET_YDS",
 250        "passing_TD",
 251        "passing_INT",
 252        # Rushing
 253        "rushing_CAR",
 254        "rushing_YDS",
 255        "rushing_TD",
 256        # Misc. Offense
 257        "total_yards",
 258        # Fumbles
 259        "fumbles_LOST",
 260        "fumbles_REC",
 261        # Defense
 262        "defensive_TFL",
 263        "defensive_SACKS",
 264        # Interceptions
 265        "interceptions_INT",
 266        "interceptions_YDS",
 267        "interceptions_TD",
 268        # Kick Returns
 269        "kickReturns_NO",
 270        "kickReturns_YDS",
 271        "kickReturns_TD",
 272        # Punt Returns
 273        "puntReturns_NO",
 274        "puntReturns_YDS",
 275        "puntReturns_TD",
 276        # Situational
 277        "situational_first_downs",
 278        "situational_third_down_conversions",
 279        "situational_third_downs_attempted",
 280        "situational_fourth_down_conversions",
 281        "situational_fourth_downs_attempted",
 282        "situational_penalties",
 283        "situational_penalty_yards",
 284        "situational_turnovers",
 285        "situational_possession_time",
 286    ]
 287
 288    now = datetime.now()
 289    url = "https://api.collegefootballdata.com/stats/season"
 290    row_df = pd.DataFrame()
 291    final_df = pd.DataFrame()
 292
 293    if api_key is not None:
 294        real_api_key = api_key
 295        del api_key
 296    else:
 297        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
 298
 299    if real_api_key == "tigersAreAwesome":
 300        raise ValueError(
 301            "You actually need to change `cfbd_key` to your CFBD API key."
 302        )
 303    elif "Bearer " in real_api_key:
 304        pass
 305    elif "Bearer" in real_api_key:
 306        real_api_key = real_api_key.replace("Bearer", "Bearer ")
 307    else:
 308        real_api_key = "Bearer " + real_api_key
 309
 310    if season is not None and (season > (now.year + 1)):
 311        raise ValueError(f"`season` cannot be greater than {season}.")
 312    elif season is not None and season < 1869:
 313        raise ValueError("`season` cannot be less than 1869.")
 314
 315    if start_week is not None and end_week is not None:
 316        if start_week > end_week:
 317            raise ValueError("`start_week` cannot be greater than `end_week`.")
 318        elif start_week == end_week:
 319            raise ValueError(
 320                "`start_week` cannot be equal to `end_week`."
 321                + "\n Use " +
 322                "`cfbd_json_py.games.get_cfbd_player_game_stats()` instead "
 323                + "if you want player stats for a specific week in ."
 324            )
 325        elif start_week < 0:
 326            raise ValueError("`start_week` cannot be less than 0.")
 327        elif end_week < 0:
 328            raise ValueError("`end_week` cannot be less than 0.")
 329    # URL builder
 330    ##########################################################################
 331
 332    # Required by the API
 333
 334    if season is not None and team is not None:
 335        url += f"?year={season}&team={team}"
 336    elif season is not None:
 337        url += f"?year={season}"
 338    elif team is not None:
 339        url += f"?team={team}"
 340
 341    if conference is not None:
 342        url += f"&conference={conference}"
 343
 344    if start_week is not None:
 345        url += f"&startWeek={start_week}"
 346
 347    if end_week is not None:
 348        url += f"&endWeek={end_week}"
 349
 350    headers = {
 351        "Authorization": f"{real_api_key}",
 352        "accept": "application/json"
 353    }
 354
 355    response = requests.get(url, headers=headers)
 356
 357    if response.status_code == 200:
 358        pass
 359    elif response.status_code == 401:
 360        raise ConnectionRefusedError(
 361            "Could not connect. The connection was refused." +
 362            "\nHTTP Status Code 401."
 363        )
 364    else:
 365        raise ConnectionError(
 366            f"Could not connect.\nHTTP Status code {response.status_code}"
 367        )
 368
 369    json_data = response.json()
 370
 371    if return_as_dict is True:
 372        return json_data
 373
 374    for stat in tqdm(json_data):
 375        t_season = stat["season"]
 376        t_team_name = stat["team"]
 377        t_conference = stat["conference"]
 378        stat_name = stat["statName"]
 379        stat_value = stat["statValue"]
 380        composite_key = f"{t_season}_{t_team_name}"
 381
 382        if rebuilt_json.get(composite_key) is None:
 383            rebuilt_json[composite_key] = {}
 384
 385        match stat_name:
 386            # General
 387            case "games":
 388                rebuilt_json[composite_key]["season"] = t_season
 389                rebuilt_json[composite_key]["team_name"] = t_team_name
 390                rebuilt_json[composite_key]["conference_name"] = t_conference
 391                rebuilt_json[composite_key]["games"] = stat_value
 392
 393            # Passing
 394            case "passCompletions":
 395                rebuilt_json[composite_key]["season"] = t_season
 396                rebuilt_json[composite_key]["team_name"] = t_team_name
 397                rebuilt_json[composite_key]["conference_name"] = t_conference
 398                rebuilt_json[composite_key]["passing_COMP"] = stat_value
 399
 400            case "passAttempts":
 401                rebuilt_json[composite_key]["season"] = t_season
 402                rebuilt_json[composite_key]["team_name"] = t_team_name
 403                rebuilt_json[composite_key]["conference_name"] = t_conference
 404                rebuilt_json[composite_key]["passing_ATT"] = stat_value
 405
 406            case "netPassingYards":
 407                rebuilt_json[composite_key]["season"] = t_season
 408                rebuilt_json[composite_key]["team_name"] = t_team_name
 409                rebuilt_json[composite_key]["conference_name"] = t_conference
 410                rebuilt_json[composite_key]["passing_NET_YDS"] = stat_value
 411
 412            case "passingTDs":
 413                rebuilt_json[composite_key]["season"] = t_season
 414                rebuilt_json[composite_key]["team_name"] = t_team_name
 415                rebuilt_json[composite_key]["conference_name"] = t_conference
 416                rebuilt_json[composite_key]["passing_TD"] = stat_value
 417
 418            case "passesIntercepted":
 419                rebuilt_json[composite_key]["season"] = t_season
 420                rebuilt_json[composite_key]["team_name"] = t_team_name
 421                rebuilt_json[composite_key]["conference_name"] = t_conference
 422                rebuilt_json[composite_key]["passing_INT"] = stat_value
 423
 424            # Rushing
 425            case "rushingAttempts":
 426                rebuilt_json[composite_key]["season"] = t_season
 427                rebuilt_json[composite_key]["team_name"] = t_team_name
 428                rebuilt_json[composite_key]["conference_name"] = t_conference
 429                rebuilt_json[composite_key]["rushing_CAR"] = stat_value
 430
 431            case "rushingYards":
 432                rebuilt_json[composite_key]["season"] = t_season
 433                rebuilt_json[composite_key]["team_name"] = t_team_name
 434                rebuilt_json[composite_key]["conference_name"] = t_conference
 435                rebuilt_json[composite_key]["rushing_YDS"] = stat_value
 436
 437            case "rushingTDs":
 438                rebuilt_json[composite_key]["season"] = t_season
 439                rebuilt_json[composite_key]["team_name"] = t_team_name
 440                rebuilt_json[composite_key]["conference_name"] = t_conference
 441                rebuilt_json[composite_key]["rushing_TD"] = stat_value
 442
 443            # Misc Offense
 444            case "totalYards":
 445                rebuilt_json[composite_key]["season"] = t_season
 446                rebuilt_json[composite_key]["team_name"] = t_team_name
 447                rebuilt_json[composite_key]["conference_name"] = t_conference
 448                rebuilt_json[composite_key]["total_yards"] = stat_value
 449
 450            # Fumbles
 451            case "fumblesLost":
 452                rebuilt_json[composite_key]["season"] = t_season
 453                rebuilt_json[composite_key]["team_name"] = t_team_name
 454                rebuilt_json[composite_key]["conference_name"] = t_conference
 455                rebuilt_json[composite_key]["fumbles_LOST"] = stat_value
 456
 457            case "fumblesRecovered":
 458                rebuilt_json[composite_key]["season"] = t_season
 459                rebuilt_json[composite_key]["team_name"] = t_team_name
 460                rebuilt_json[composite_key]["conference_name"] = t_conference
 461                rebuilt_json[composite_key]["fumbles_REC"] = stat_value
 462
 463            # Defense
 464            case "tacklesForLoss":
 465                rebuilt_json[composite_key]["season"] = t_season
 466                rebuilt_json[composite_key]["team_name"] = t_team_name
 467                rebuilt_json[composite_key]["conference_name"] = t_conference
 468                rebuilt_json[composite_key]["defensive_TFL"] = stat_value
 469
 470            case "sacks":
 471                rebuilt_json[composite_key]["season"] = t_season
 472                rebuilt_json[composite_key]["team_name"] = t_team_name
 473                rebuilt_json[composite_key]["conference_name"] = t_conference
 474                rebuilt_json[composite_key]["defensive_SACKS"] = stat_value
 475
 476            # Interceptions
 477            case "interceptions":
 478                rebuilt_json[composite_key]["season"] = t_season
 479                rebuilt_json[composite_key]["team_name"] = t_team_name
 480                rebuilt_json[composite_key]["conference_name"] = t_conference
 481                rebuilt_json[composite_key]["interceptions_INT"] = stat_value
 482
 483            case "interceptionYards":
 484                rebuilt_json[composite_key]["season"] = t_season
 485                rebuilt_json[composite_key]["team_name"] = t_team_name
 486                rebuilt_json[composite_key]["conference_name"] = t_conference
 487                rebuilt_json[composite_key]["interceptions_YDS"] = stat_value
 488
 489            case "interceptionTDs":
 490                rebuilt_json[composite_key]["season"] = t_season
 491                rebuilt_json[composite_key]["team_name"] = t_team_name
 492                rebuilt_json[composite_key]["conference_name"] = t_conference
 493                rebuilt_json[composite_key]["interceptions_TD"] = stat_value
 494
 495            # Kick Returns
 496            case "kickReturns":
 497                rebuilt_json[composite_key]["season"] = t_season
 498                rebuilt_json[composite_key]["team_name"] = t_team_name
 499                rebuilt_json[composite_key]["conference_name"] = t_conference
 500                rebuilt_json[composite_key]["kickReturns_NO"] = stat_value
 501
 502            case "kickReturnYards":
 503                rebuilt_json[composite_key]["season"] = t_season
 504                rebuilt_json[composite_key]["team_name"] = t_team_name
 505                rebuilt_json[composite_key]["conference_name"] = t_conference
 506                rebuilt_json[composite_key]["kickReturns_YDS"] = stat_value
 507
 508            case "kickReturnTDs":
 509                rebuilt_json[composite_key]["season"] = t_season
 510                rebuilt_json[composite_key]["team_name"] = t_team_name
 511                rebuilt_json[composite_key]["conference_name"] = t_conference
 512                rebuilt_json[composite_key]["kickReturns_TD"] = stat_value
 513
 514            # Punt Returns
 515            case "puntReturns":
 516                rebuilt_json[composite_key]["season"] = t_season
 517                rebuilt_json[composite_key]["team_name"] = t_team_name
 518                rebuilt_json[composite_key]["conference_name"] = t_conference
 519                rebuilt_json[composite_key]["puntReturns_NO"] = stat_value
 520
 521            case "puntReturnYards":
 522                rebuilt_json[composite_key]["season"] = t_season
 523                rebuilt_json[composite_key]["team_name"] = t_team_name
 524                rebuilt_json[composite_key]["conference_name"] = t_conference
 525                rebuilt_json[composite_key]["puntReturns_YDS"] = stat_value
 526
 527            case "puntReturnTDs":
 528                rebuilt_json[composite_key]["season"] = t_season
 529                rebuilt_json[composite_key]["team_name"] = t_team_name
 530                rebuilt_json[composite_key]["conference_name"] = t_conference
 531                rebuilt_json[composite_key]["puntReturns_TD"] = stat_value
 532
 533            # Situational
 534            case "firstDowns":
 535                rebuilt_json[composite_key]["season"] = t_season
 536                rebuilt_json[composite_key]["team_name"] = t_team_name
 537                rebuilt_json[composite_key]["conference_name"] = t_conference
 538                rebuilt_json[composite_key][
 539                    "situational_first_downs"] = stat_value
 540
 541            case "turnovers":
 542                rebuilt_json[composite_key]["season"] = t_season
 543                rebuilt_json[composite_key]["team_name"] = t_team_name
 544                rebuilt_json[composite_key]["conference_name"] = t_conference
 545                rebuilt_json[composite_key][
 546                    "situational_turnovers"] = stat_value
 547
 548            case "thirdDownConversions":
 549                rebuilt_json[composite_key]["season"] = t_season
 550                rebuilt_json[composite_key]["team_name"] = t_team_name
 551                rebuilt_json[composite_key]["conference_name"] = t_conference
 552                rebuilt_json[composite_key][
 553                    "situational_third_down_conversions"
 554                ] = stat_value
 555
 556            case "thirdDowns":
 557                rebuilt_json[composite_key]["season"] = t_season
 558                rebuilt_json[composite_key]["team_name"] = t_team_name
 559                rebuilt_json[composite_key]["conference_name"] = t_conference
 560                rebuilt_json[composite_key][
 561                    "situational_third_downs_attempted"
 562                ] = stat_value
 563
 564            case "fourthDownConversions":
 565                rebuilt_json[composite_key]["season"] = t_season
 566                rebuilt_json[composite_key]["team_name"] = t_team_name
 567                rebuilt_json[composite_key]["conference_name"] = t_conference
 568                rebuilt_json[composite_key][
 569                    "situational_fourth_down_conversions"
 570                ] = stat_value
 571
 572            case "fourthDowns":
 573                rebuilt_json[composite_key]["season"] = t_season
 574                rebuilt_json[composite_key]["team_name"] = t_team_name
 575                rebuilt_json[composite_key]["conference_name"] = t_conference
 576                rebuilt_json[composite_key][
 577                    "situational_fourth_downs_attempted"
 578                ] = stat_value
 579
 580            case "penalties":
 581                rebuilt_json[composite_key]["season"] = t_season
 582                rebuilt_json[composite_key]["team_name"] = t_team_name
 583                rebuilt_json[composite_key]["conference_name"] = t_conference
 584                rebuilt_json[composite_key][
 585                    "situational_penalties"] = stat_value
 586
 587            case "penaltyYards":
 588                rebuilt_json[composite_key]["season"] = t_season
 589                rebuilt_json[composite_key]["team_name"] = t_team_name
 590                rebuilt_json[composite_key]["conference_name"] = t_conference
 591                rebuilt_json[composite_key][
 592                    "situational_penalty_yards"] = stat_value
 593
 594            case "possessionTime":
 595                rebuilt_json[composite_key]["season"] = t_season
 596                rebuilt_json[composite_key]["team_name"] = t_team_name
 597                rebuilt_json[composite_key]["conference_name"] = t_conference
 598                rebuilt_json[composite_key][
 599                    "situational_possession_time"] = stat_value
 600
 601            case _:
 602                raise ValueError(f"Unhandled stat name `{stat_name}`")
 603
 604        del t_season, t_team_name, t_conference
 605        del (
 606            stat_name,
 607            stat_value,
 608        )
 609        del composite_key
 610
 611    for key, value in tqdm(rebuilt_json.items()):
 612        row_df = pd.DataFrame(value, index=[0])
 613        final_df = pd.concat([final_df, row_df], ignore_index=True)
 614
 615    final_df = final_df[stat_columns]
 616    return final_df
 617
 618
 619def get_cfbd_advanced_team_season_stats(
 620    api_key: str = None,
 621    api_key_dir: str = None,
 622    season: int = None,
 623    team: str = None,
 624    # `year` and/or `team` need to be not null for this function to work.
 625    exclude_garbage_time: bool = False,
 626    start_week: int = None,
 627    end_week: int = None,
 628    return_as_dict: bool = False,
 629):
 630    """
 631    Allows you to get advanced CFB team season stats data from the CFBD API.
 632
 633    Parameters
 634    ----------
 635
 636    `api_key` (str, optional):
 637        Semi-optional argument.
 638        If `api_key` is null, this function will attempt to load a CFBD API key
 639        from the python environment, or from a file on this computer.
 640        If `api_key` is not null,
 641        this function will automatically assume that the
 642        inputted `api_key` is a valid CFBD API key.
 643
 644    `api_key_dir` (str, optional):
 645        Optional argument.
 646        If `api_key` is set to am empty string, this variable is ignored.
 647        If `api_key_dir` is null, and `api_key` is null,
 648        this function will try to find
 649        a CFBD API key file in this user's home directory.
 650        If `api_key_dir` is set to a string, and `api_key` is null,
 651        this function will assume that `api_key_dir` is a directory,
 652        and will try to find a CFBD API key file in that directory.
 653
 654    `season` (int, semi-mandatory):
 655        Semi-required argument.
 656        Specifies the season you want CFB team season stats data from.
 657        This must be specified, otherwise this package, and by extension
 658        the CFBD API, will not accept the request
 659        to get CFB team season stats data.
 660        This or `team` must be set
 661        to a valid non-null variable for this to function.
 662
 663    `team` (str, semi-mandatory):
 664        Semi-required argument.
 665        Specifies the season you want advanced CFB team season stats data from.
 666        This must be specified, otherwise this package, and by extension
 667        the CFBD API, will not accept
 668        the request to get CFB team season stats data.
 669        This or `season` must be set
 670        to a valid non-null variable for this to function.
 671
 672    `exclude_garbage_time` (bool, optional):
 673        Optional argument.
 674        If you want to filter out plays where
 675        the result of the game is largely decided,
 676        set `exclude_garbage_time = True`.
 677        Default behavior is that this variable is set to
 678        `False` when this function is called.
 679
 680    `start_week` (int, semi-optional):
 681        Optional argument.
 682        If you only want team stats for a range of weeks,
 683        set `start_week` and `end_week` to
 684        the range of weeks you want season-level data for.
 685
 686    `end_week` (int, semi-optional):
 687        Optional argument.
 688        If you only want team stats for a range of weeks,
 689        set `start_week` and `end_week` to
 690        the range of weeks you want season-level data for.
 691
 692    **NOTE**: If the following conditions are `True`, a `ValueError()`
 693    will be raised when calling this function:
 694    - `start_week < 0`
 695    - `end_week < 0`
 696    - `start_week is not None and end_week is None`
 697        (will be changed in a future version)
 698    - `start_week is None and end_week is not None`
 699        (will be changed in a future version)
 700    - `end_week < start_week`
 701    - `end_week = start_week`
 702
 703    `return_as_dict` (bool, semi-optional):
 704        Semi-optional argument.
 705        If you want this function to return
 706        the data as a dictionary (read: JSON object),
 707        instead of a pandas `DataFrame` object,
 708        set `return_as_dict` to `True`.
 709
 710
 711    Usage
 712    ----------
 713    ```
 714
 715    import time
 716
 717    from cfbd_json_py.stats import get_cfbd_advanced_team_season_stats
 718
 719
 720    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 721
 722    if cfbd_key != "tigersAreAwesome":
 723        print(
 724            "Using the user's API key declared in this script " +
 725            "for this example."
 726        )
 727
 728        # Get advanced team season stats for the 2020 CFB season.
 729        print("Get team season stats for the 2020 CFB season.")
 730        json_data = get_cfbd_advanced_team_season_stats(
 731            api_key=cfbd_key,
 732            season=2020
 733        )
 734        print(json_data)
 735        time.sleep(5)
 736
 737        # Get advanced team season stats for the 2020 CFB season,
 738        # but remove plays that happen in garbage time.
 739        print(
 740            "Get advanced team season stats for the 2020 CFB season, " +
 741            "but remove plays that happen in garbage time."
 742        )
 743        json_data = get_cfbd_advanced_team_season_stats(
 744            api_key=cfbd_key,
 745            season=2020,
 746            exclude_garbage_time=True
 747        )
 748        print(json_data)
 749        time.sleep(5)
 750
 751        # Get advanced team season stats for the 2020 CFB season,
 752        # but only between weeks 5 and 10.
 753        print(
 754            "Get advanced team season stats for the 2020 CFB season, " +
 755            "but only between weeks 5 and 10."
 756        )
 757        json_data = get_cfbd_advanced_team_season_stats(
 758            api_key=cfbd_key,
 759            season=2020,
 760            start_week=5,
 761            end_week=10
 762        )
 763        print(json_data)
 764        time.sleep(5)
 765
 766        # Get advanced team season stats for just
 767        # the Ohio State Buckeyes Football Team.
 768        print(
 769            "Get advanced team season stats for just" +
 770            " the Ohio State Buckeyes Football Team."
 771        )
 772        json_data = get_cfbd_advanced_team_season_stats(
 773            api_key=cfbd_key,
 774            team="Ohio State"
 775        )
 776        print(json_data)
 777        time.sleep(5)
 778
 779
 780        # You can also tell this function to just return the API call as
 781        # a Dictionary (read: JSON) object.
 782        print(
 783            "You can also tell this function to just return the API call " +
 784            "as a Dictionary (read: JSON) object."
 785        )
 786        json_data = get_cfbd_advanced_team_season_stats(
 787            api_key=cfbd_key,
 788            season=2020,
 789            team="Cincinnati",
 790            return_as_dict=True
 791        )
 792        print(json_data)
 793
 794    else:
 795        # Alternatively, if the CFBD API key exists in this python environment,
 796        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 797        # you could just call these functions directly,
 798        # without setting the API key in the script.
 799        print(
 800            "Using the user's API key supposedly loaded " +
 801            "into this python environment for this example."
 802        )
 803
 804    # Get advanced team season stats for the 2020 CFB season.
 805        print("Get team season stats for the 2020 CFB season.")
 806        json_data = get_cfbd_advanced_team_season_stats(
 807            season=2020
 808        )
 809        print(json_data)
 810        time.sleep(5)
 811
 812        # Get advanced team season stats for the 2020 CFB season,
 813        # but remove plays that happen in garbage time.
 814        print(
 815            "Get advanced team season stats for the 2020 CFB season, " +
 816            "but remove plays that happen in garbage time."
 817        )
 818        json_data = get_cfbd_advanced_team_season_stats(
 819            season=2020,
 820            exclude_garbage_time=True
 821        )
 822        print(json_data)
 823        time.sleep(5)
 824
 825        # Get advanced team season stats for the 2020 CFB season,
 826        # but only between weeks 5 and 10.
 827        print(
 828            "Get advanced team season stats for the 2020 CFB season, " +
 829            "but only between weeks 5 and 10."
 830        )
 831        json_data = get_cfbd_advanced_team_season_stats(
 832            season=2020,
 833            start_week=5,
 834            end_week=10
 835        )
 836        print(json_data)
 837        time.sleep(5)
 838
 839        # Get advanced team season stats for the just
 840        # the Ohio State Buckeyes Football Team.
 841        print(
 842            "Get advanced team season stats for the just " +
 843            "the Ohio State Buckeyes Football Team."
 844        )
 845        json_data = get_cfbd_advanced_team_season_stats(
 846            team="Ohio State"
 847        )
 848        print(json_data)
 849        time.sleep(5)
 850
 851
 852        # You can also tell this function to just return the API call as
 853        # a Dictionary (read: JSON) object.
 854        print(
 855            "You can also tell this function to just return the API call " +
 856            "as a Dictionary (read: JSON) object."
 857        )
 858        json_data = get_cfbd_advanced_team_season_stats(
 859            season=2020,
 860            team="Cincinnati",
 861            return_as_dict=True
 862        )
 863        print(json_data)
 864    ```
 865    Returns
 866    ----------
 867    A pandas `DataFrame` object with advanced team season stats data,
 868    or (if `return_as_dict` is set to `True`)
 869    a dictionary object with a with advanced team season stats data.
 870
 871    """
 872    now = datetime.now()
 873    url = "https://api.collegefootballdata.com/stats/season/advanced"
 874    row_df = pd.DataFrame()
 875    final_df = pd.DataFrame()
 876
 877    if api_key is not None:
 878        real_api_key = api_key
 879        del api_key
 880    else:
 881        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
 882
 883    if real_api_key == "tigersAreAwesome":
 884        raise ValueError(
 885            "You actually need to change `cfbd_key` to your CFBD API key."
 886        )
 887    elif "Bearer " in real_api_key:
 888        pass
 889    elif "Bearer" in real_api_key:
 890        real_api_key = real_api_key.replace("Bearer", "Bearer ")
 891    else:
 892        real_api_key = "Bearer " + real_api_key
 893
 894    if season is not None and (season > (now.year + 1)):
 895        raise ValueError(f"`season` cannot be greater than {season}.")
 896    elif season is not None and season < 1869:
 897        raise ValueError("`season` cannot be less than 1869.")
 898
 899    if start_week is not None and end_week is not None:
 900        if start_week > end_week:
 901            raise ValueError("`start_week` cannot be greater than `end_week`.")
 902        elif start_week == end_week:
 903            raise ValueError(
 904                "`start_week` cannot be equal to `end_week`."
 905                + "\n Use " +
 906                "`cfbd_json_py.games.get_cfbd_player_game_stats()` instead "
 907                + "if you want player stats for a specific week in ."
 908            )
 909        elif start_week < 0:
 910            raise ValueError("`start_week` cannot be less than 0.")
 911        elif end_week < 0:
 912            raise ValueError("`end_week` cannot be less than 0.")
 913
 914    gt_str = ""
 915
 916    # URL builder
 917    ##########################################################################
 918
 919    if exclude_garbage_time is True:
 920        gt_str = "true"
 921    elif exclude_garbage_time is False:
 922        gt_str = "false"
 923
 924    if season is not None and team is not None:
 925        url += f"?year={season}&team={team}"
 926    elif season is not None:
 927        url += f"?year={season}"
 928    elif team is not None:
 929        url += f"?team={team}"
 930
 931    if exclude_garbage_time is not None:
 932        url += f"&excludeGarbageTime={gt_str}"
 933
 934    if start_week is not None:
 935        url += f"&startWeek={start_week}"
 936
 937    if end_week is not None:
 938        url += f"&endWeek={end_week}"
 939
 940    headers = {
 941        "Authorization": f"{real_api_key}",
 942        "accept": "application/json"
 943    }
 944
 945    response = requests.get(url, headers=headers)
 946
 947    if response.status_code == 200:
 948        pass
 949    elif response.status_code == 401:
 950        raise ConnectionRefusedError(
 951            "Could not connect. The connection was refused." +
 952            "\nHTTP Status Code 401."
 953        )
 954    else:
 955        raise ConnectionError(
 956            f"Could not connect.\nHTTP Status code {response.status_code}"
 957        )
 958
 959    json_data = response.json()
 960
 961    if return_as_dict is True:
 962        return json_data
 963
 964    for team in tqdm(json_data):
 965        t_season = team["season"]
 966        t_team = team["team"]
 967        t_conf = team["conference"]
 968        row_df = pd.DataFrame(
 969            {
 970                "season": t_season,
 971                "team": t_team,
 972                "conference": t_conf
 973            },
 974            index=[0]
 975        )
 976
 977        # offense
 978        if "offense" not in team:
 979            logging.debug(
 980                f"Key `[offense]` not found for the {t_season} {t_team}."
 981            )
 982        else:
 983            row_df["offense_plays"] = team["offense"]["plays"]
 984            row_df["offense_drives"] = team["offense"]["drives"]
 985            # row_df["offense_plays"] = team["offense"]["plays"]
 986            row_df["offense_ppa"] = team["offense"]["ppa"]
 987            row_df["offense_total_ppa"] = team["offense"]["totalPPA"]
 988            row_df["offense_success_rate"] = team["offense"]["successRate"]
 989            row_df["offense_explosiveness"] = team["offense"]["explosiveness"]
 990            row_df["offense_power_success"] = team["offense"]["powerSuccess"]
 991            row_df["offense_stuff_rate"] = team["offense"]["stuffRate"]
 992            row_df["offense_line_yards_avg"] = team["offense"]["lineYards"]
 993            row_df["offense_line_yards_total"] = team["offense"][
 994                "lineYardsTotal"
 995            ]
 996            row_df["offense_second_level_yards_avg"] = team["offense"][
 997                "secondLevelYards"
 998            ]
 999            row_df["offense_second_level_yards_total"] = team["offense"][
1000                "secondLevelYardsTotal"
1001            ]
1002            row_df["offense_open_field_yards_avg"] = team["offense"][
1003                "openFieldYards"
1004            ]
1005            row_df["offense_open_field_yards_total"] = team["offense"][
1006                "secondLevelYardsTotal"
1007            ]
1008            row_df["offense_total_opportunities"] = team["offense"][
1009                "totalOpportunies"
1010            ]
1011            row_df["offense_points_per_opportunity"] = team["offense"][
1012                "pointsPerOpportunity"
1013            ]
1014
1015            row_df["offense_field_position_avg_start"] = team["offense"][
1016                "fieldPosition"]["averageStart"]
1017            row_df["offense_field_position_avg_predicted_points"] = team[
1018                "offense"]["fieldPosition"]["averagePredictedPoints"]
1019
1020            row_df["offense_havoc_total"] = team["offense"]["havoc"]["total"]
1021            row_df["offense_havoc_front_7"] = team["offense"]["havoc"][
1022                "frontSeven"
1023            ]
1024            row_df["offense_havoc_db"] = team["offense"]["havoc"]["db"]
1025
1026            row_df["offense_standard_downs_rate"] = team[
1027                "offense"]["standardDowns"]["rate"]
1028            row_df["offense_standard_downs_ppa"] = team[
1029                "offense"]["standardDowns"]["ppa"]
1030            row_df["offense_standard_downs_success_rate"] = team["offense"][
1031                "standardDowns"
1032            ]["successRate"]
1033            row_df["offense_standard_downs_explosiveness"] = team["offense"][
1034                "standardDowns"
1035            ]["explosiveness"]
1036
1037            row_df["offense_passing_downs_rate"] = team[
1038                "offense"]["passingDowns"]["rate"]
1039            row_df["offense_passing_downs_ppa"] = team[
1040                "offense"]["passingDowns"]["ppa"]
1041            row_df["offense_passing_downs_success_rate"] = team["offense"][
1042                "passingDowns"
1043            ]["successRate"]
1044            row_df["offense_passing_downs_explosiveness"] = team["offense"][
1045                "passingDowns"
1046            ]["explosiveness"]
1047
1048            row_df["offense_rushing_plays_rate"] = team[
1049                "offense"]["rushingPlays"]["rate"]
1050            row_df["offense_rushing_plays_ppa"] = team[
1051                "offense"]["rushingPlays"]["ppa"]
1052            row_df["offense_rushing_plays_total_ppa"] = team[
1053                "offense"]["rushingPlays"]["totalPPA"]
1054            row_df["offense_rushing_plays_success_rate"] = team[
1055                "offense"]["rushingPlays"]["successRate"]
1056            row_df["offense_rushing_plays_explosiveness"] = team[
1057                "offense"]["rushingPlays"]["explosiveness"]
1058
1059            row_df["offense_passing_plays_rate"] = team[
1060                "offense"]["passingPlays"]["rate"]
1061            row_df["offense_passing_plays_ppa"] = team[
1062                "offense"]["passingPlays"]["ppa"]
1063            row_df["offense_passing_plays_total_ppa"] = team[
1064                "offense"]["passingPlays"]["totalPPA"]
1065            row_df["offense_passing_plays_success_rate"] = team[
1066                "offense"]["passingPlays"]["successRate"]
1067            row_df["offense_passing_plays_explosiveness"] = team[
1068                "offense"]["rushingPlays"]["explosiveness"]
1069
1070        # defense
1071        if "defense" not in team:
1072            logging.debug(
1073                f"Key `[defense]` not found for the {t_season} {t_team}."
1074            )
1075        else:
1076
1077            row_df["defense_plays"] = team["defense"]["plays"]
1078            row_df["defense_drives"] = team["defense"]["drives"]
1079            # row_df["defense_plays"] = team["defense"]["plays"]
1080            row_df["defense_ppa"] = team["defense"]["ppa"]
1081            row_df["defense_total_ppa"] = team["defense"]["totalPPA"]
1082            row_df["defense_success_rate"] = team["defense"]["successRate"]
1083            row_df["defense_explosiveness"] = team["defense"]["explosiveness"]
1084            row_df["defense_power_success"] = team["defense"]["powerSuccess"]
1085            row_df["defense_stuff_rate"] = team["defense"]["stuffRate"]
1086            row_df["defense_line_yards_avg"] = team["defense"]["lineYards"]
1087            row_df["defense_line_yards_total"] = team["defense"][
1088                "lineYardsTotal"
1089            ]
1090            row_df["defense_second_level_yards_avg"] = team["defense"][
1091                "secondLevelYards"
1092            ]
1093            row_df["defense_second_level_yards_total"] = team["defense"][
1094                "secondLevelYardsTotal"
1095            ]
1096            row_df["defense_open_field_yards_avg"] = team["defense"][
1097                "openFieldYards"
1098            ]
1099            row_df["defense_open_field_yards_total"] = team["defense"][
1100                "secondLevelYardsTotal"
1101            ]
1102            row_df["defense_total_opportunities"] = team["defense"][
1103                "totalOpportunies"
1104            ]
1105            row_df["defense_points_per_opportunity"] = team["defense"][
1106                "pointsPerOpportunity"
1107            ]
1108
1109            row_df["defense_field_position_avg_start"] = team["defense"][
1110                "fieldPosition"
1111            ]["averageStart"]
1112            row_df["defense_field_position_avg_predicted_points"] = team[
1113                "defense"]["fieldPosition"]["averagePredictedPoints"]
1114
1115            row_df["defense_havoc_total"] = team["defense"]["havoc"]["total"]
1116            row_df["defense_havoc_front_7"] = team["defense"]["havoc"][
1117                "frontSeven"
1118            ]
1119            row_df["defense_havoc_db"] = team["defense"]["havoc"]["db"]
1120
1121            row_df["defense_standard_downs_rate"] = team[
1122                "defense"]["standardDowns"]["rate"]
1123            row_df["defense_standard_downs_ppa"] = team[
1124                "defense"]["standardDowns"]["ppa"]
1125            row_df["defense_standard_downs_success_rate"] = team["defense"][
1126                "standardDowns"
1127            ]["successRate"]
1128            row_df["defense_standard_downs_explosiveness"] = team["defense"][
1129                "standardDowns"
1130            ]["explosiveness"]
1131
1132            row_df["defense_passing_downs_rate"] = team[
1133                "defense"]["passingDowns"]["rate"]
1134            row_df["defense_passing_downs_ppa"] = team[
1135                "defense"]["passingDowns"]["ppa"]
1136            row_df["defense_passing_downs_success_rate"] = team["defense"][
1137                "passingDowns"
1138            ]["successRate"]
1139            row_df["defense_passing_downs_explosiveness"] = team["defense"][
1140                "passingDowns"
1141            ]["explosiveness"]
1142
1143            row_df["defense_rushing_plays_rate"] = team[
1144                "defense"]["rushingPlays"]["rate"]
1145            row_df["defense_rushing_plays_ppa"] = team[
1146                "defense"]["rushingPlays"]["ppa"]
1147            row_df["defense_rushing_plays_total_ppa"] = team[
1148                "defense"]["rushingPlays"]["totalPPA"]
1149            row_df["defense_rushing_plays_success_rate"] = team["defense"][
1150                "rushingPlays"
1151            ]["successRate"]
1152            row_df["defense_rushing_plays_explosiveness"] = team["defense"][
1153                "rushingPlays"
1154            ]["explosiveness"]
1155
1156            row_df["defense_passing_plays_rate"] = team[
1157                "defense"]["passingPlays"]["rate"]
1158            row_df["defense_passing_plays_ppa"] = team[
1159                "defense"]["passingPlays"]["ppa"]
1160            row_df["defense_passing_plays_total_ppa"] = team[
1161                "defense"]["passingPlays"]["totalPPA"]
1162            row_df["defense_passing_plays_success_rate"] = team["defense"][
1163                "passingPlays"
1164            ]["successRate"]
1165            row_df["defense_passing_plays_explosiveness"] = team["defense"][
1166                "rushingPlays"
1167            ]["explosiveness"]
1168
1169        final_df = pd.concat([final_df, row_df], ignore_index=True)
1170        del row_df
1171        del t_season, t_conf, t_team
1172
1173    return final_df
1174
1175
1176def get_cfbd_advanced_team_game_stats(
1177    api_key: str = None,
1178    api_key_dir: str = None,
1179    season: int = None,
1180    team: str = None,
1181    # `year` and/or `team` need to be not null for this function to work.
1182    week: int = None,
1183    opponent: str = None,
1184    exclude_garbage_time: bool = False,
1185    season_type: str = "both",  # "regular", "postseason", or "both"
1186    return_as_dict: bool = False,
1187):
1188    """
1189    Allows you to get advanced CFB team game stats data from the CFBD API.
1190
1191    Parameters
1192    ----------
1193
1194    `api_key` (str, optional):
1195        Semi-optional argument.
1196        If `api_key` is null, this function will attempt to load a CFBD API key
1197        from the python environment, or from a file on this computer.
1198        If `api_key` is not null,
1199        this function will automatically assume that the
1200        inputted `api_key` is a valid CFBD API key.
1201
1202    `api_key_dir` (str, optional):
1203        Optional argument.
1204        If `api_key` is set to am empty string, this variable is ignored.
1205        If `api_key_dir` is null, and `api_key` is null,
1206        this function will try to find
1207        a CFBD API key file in this user's home directory.
1208        If `api_key_dir` is set to a string, and `api_key` is null,
1209        this function will assume that `api_key_dir` is a directory,
1210        and will try to find a CFBD API key file in that directory.
1211
1212    `season` (int, semi-mandatory):
1213        Semi-required argument.
1214        Specifies the season you want CFB team game stats data from.
1215        This must be specified, otherwise this package, and by extension
1216        the CFBD API, will not accept the request
1217        to get CFB team season stats data.
1218        This or `team` must be set
1219        to a valid non-null variable for this to function.
1220
1221    `team` (str, semi-mandatory):
1222        Semi-required argument.
1223        Specifies the season you want advanced CFB team game stats data from.
1224        This must be specified, otherwise this package, and by extension
1225        the CFBD API, will not accept
1226        the request to get CFB team season stats data.
1227        This or `season` must be set
1228        to a valid non-null variable for this to function.
1229
1230    `week` (int, optional):
1231        Optional argument.
1232        If `week` is set to an integer, this function will attempt
1233        to load CFB team game from games in that season, and that week.
1234
1235    `opponent` (str, optional):
1236        Optional argument.
1237        If you only want games from a specific opponent,
1238        set `opponent` to the name of that team.
1239
1240
1241    `exclude_garbage_time` (bool, optional):
1242        Optional argument.
1243        If you want to filter out plays where
1244        the result of the game is largely decided,
1245        set `exclude_garbage_time = True`.
1246        Default behavior is that this variable is set to
1247        `False` when this function is called.
1248
1249    `season_type` (str, semi-optional):
1250        Semi-optional argument.
1251        By default, this will be set to "regular", for the CFB regular season.
1252        If you want CFB team game stats, set `season_type` to "postseason".
1253        If `season_type` is set to anything but "regular" or "postseason",
1254        a `ValueError()` will be raised.
1255
1256    `return_as_dict` (bool, semi-optional):
1257        Semi-optional argument.
1258        If you want this function to return
1259        the data as a dictionary (read: JSON object),
1260        instead of a pandas `DataFrame` object,
1261        set `return_as_dict` to `True`.
1262
1263
1264    Usage
1265    ----------
1266    ```
1267    import time
1268
1269    from cfbd_json_py.stats import get_cfbd_advanced_team_game_stats
1270
1271
1272    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
1273
1274    if cfbd_key != "tigersAreAwesome":
1275        print(
1276            "Using the user's API key declared in this script " +
1277            "for this example."
1278        )
1279
1280        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season.
1281        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1282        json_data = get_cfbd_advanced_team_game_stats(
1283            api_key=cfbd_key,
1284            season=2020,
1285            week=10
1286        )
1287        print(json_data)
1288        time.sleep(5)
1289
1290        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season,
1291        # but exclude plays that happen in garbage time.
1292        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1293        json_data = get_cfbd_advanced_team_game_stats(
1294            api_key=cfbd_key,
1295            season=2020,
1296            week=10,
1297            exclude_garbage_time=True
1298        )
1299        print(json_data)
1300        time.sleep(5)
1301
1302        # Get advanced CFBD team game stats for the 2020 CFB season.
1303        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1304        json_data = get_cfbd_advanced_team_game_stats(
1305            api_key=cfbd_key,
1306            season=2020
1307        )
1308        print(json_data)
1309        time.sleep(5)
1310
1311        # Get advanced CFBD team game stats for
1312        # the University of Cincinnati Football Team in the 2020 CFB season.
1313        print(
1314            "Get advanced CFBD team game stats for " +
1315            "the University of Cincinnati Football Team " +
1316            "in the 2020 CFB season."
1317        )
1318        json_data = get_cfbd_advanced_team_game_stats(
1319            api_key=cfbd_key,
1320            season=2020,
1321            opponent="Ohio"
1322        )
1323        print(json_data)
1324        time.sleep(5)
1325
1326        # Get advanced CFBD team game stats for teams that faced off
1327        # against the Ohio Bobcats Football Team in the 2020 CFB season.
1328        print(
1329            "Get advanced CFBD team game stats for teams that " +
1330            "faced off against the Ohio Bobcats Football Team " +
1331            "in the 2020 CFB season."
1332        )
1333        json_data = get_cfbd_advanced_team_game_stats(
1334            api_key=cfbd_key,
1335            season=2020,
1336            opponent="Ohio"
1337        )
1338        print(json_data)
1339        time.sleep(5)
1340
1341        # Get advanced CFBD team game stats for just
1342        # postseason games in the 2020 CFB season.
1343        print(
1344            "Get advanced CFBD team game stats for just postseason games " +
1345            "in the 2020 CFB season."
1346        )
1347        json_data = get_cfbd_advanced_team_game_stats(
1348            api_key=cfbd_key,
1349            season=2020,
1350            week=10
1351        )
1352        print(json_data)
1353        time.sleep(5)
1354
1355
1356        # You can also tell this function to just return the API call as
1357        # a Dictionary (read: JSON) object.
1358        print(
1359            "You can also tell this function to just return the API call " +
1360            "as a Dictionary (read: JSON) object."
1361        )
1362        json_data = get_cfbd_advanced_team_game_stats(
1363            api_key=cfbd_key,
1364            season=2020,
1365            week=10,
1366            return_as_dict=True
1367        )
1368        print(json_data)
1369
1370    else:
1371        # Alternatively, if the CFBD API key exists in this python environment,
1372        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
1373        # you could just call these functions directly,
1374        # without setting the API key in the script.
1375        print(
1376            "Using the user's API key supposedly loaded " +
1377            "into this python environment for this example."
1378        )
1379
1380        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season.
1381        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1382        json_data = get_cfbd_advanced_team_game_stats(
1383            season=2020,
1384            week=10
1385        )
1386        print(json_data)
1387        time.sleep(5)
1388
1389        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season,
1390        # but exclude plays that happen in garbage time.
1391        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1392        json_data = get_cfbd_advanced_team_game_stats(
1393            season=2020,
1394            week=10,
1395            exclude_garbage_time=True
1396        )
1397        print(json_data)
1398        time.sleep(5)
1399
1400        # Get advanced CFBD team game stats for the 2020 CFB season.
1401        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1402        json_data = get_cfbd_advanced_team_game_stats(
1403            season=2020
1404        )
1405        print(json_data)
1406        time.sleep(5)
1407
1408        # Get advanced CFBD team game stats for
1409        # the University of Cincinnati Football Team in the 2020 CFB season.
1410        print(
1411            "Get advanced CFBD team game stats for " +
1412            "the University of Cincinnati Football Team " +
1413            "in the 2020 CFB season."
1414        )
1415        json_data = get_cfbd_advanced_team_game_stats(
1416            season=2020,
1417            opponent="Ohio"
1418        )
1419        print(json_data)
1420        time.sleep(5)
1421
1422        # Get advanced CFBD team game stats for teams that faced off
1423        # against the Ohio Bobcats Football Team in the 2020 CFB season.
1424        print(
1425            "Get advanced CFBD team game stats for teams that " +
1426            "faced off against the Ohio Bobcats Football Team " +
1427            "in the 2020 CFB season."
1428        )
1429        json_data = get_cfbd_advanced_team_game_stats(
1430            season=2020,
1431            opponent="Ohio"
1432        )
1433        print(json_data)
1434        time.sleep(5)
1435
1436        # Get advanced CFBD team game stats for just
1437        # postseason games in the 2020 CFB season.
1438        print(
1439            "Get advanced CFBD team game stats for just postseason games " +
1440            "in the 2020 CFB season."
1441        )
1442        json_data = get_cfbd_advanced_team_game_stats(
1443            season=2020,
1444            week=10
1445        )
1446        print(json_data)
1447        time.sleep(5)
1448
1449
1450        # You can also tell this function to just return the API call as
1451        # a Dictionary (read: JSON) object.
1452        print(
1453            "You can also tell this function to just return the API call " +
1454            "as a Dictionary (read: JSON) object."
1455        )
1456        json_data = get_cfbd_advanced_team_game_stats(
1457            season=2020,
1458            week=10,
1459            return_as_dict=True
1460        )
1461        print(json_data)
1462
1463    ```
1464    Returns
1465    ----------
1466    A pandas `DataFrame` object with advanced team season stats data,
1467    or (if `return_as_dict` is set to `True`)
1468    a dictionary object with a with advanced team season stats data.
1469    """
1470    now = datetime.now()
1471    url = "https://api.collegefootballdata.com/stats/game/advanced"
1472    row_df = pd.DataFrame()
1473    final_df = pd.DataFrame()
1474
1475    if api_key is not None:
1476        real_api_key = api_key
1477        del api_key
1478    else:
1479        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1480
1481    if real_api_key == "tigersAreAwesome":
1482        raise ValueError(
1483            "You actually need to change `cfbd_key` to your CFBD API key."
1484        )
1485    elif "Bearer " in real_api_key:
1486        pass
1487    elif "Bearer" in real_api_key:
1488        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1489    else:
1490        real_api_key = "Bearer " + real_api_key
1491
1492    if season is not None and (season > (now.year + 1)):
1493        raise ValueError(f"`season` cannot be greater than {season}.")
1494    elif season is not None and season < 1869:
1495        raise ValueError("`season` cannot be less than 1869.")
1496
1497    if season_type == "regular" or season_type == "postseason" \
1498            or season_type == "both":
1499        pass
1500    else:
1501        raise ValueError(
1502            '`season_type` must be set to either ' +
1503            '"regular","postseason", or "both".'
1504        )
1505
1506    gt_str = ""
1507
1508    # URL builder
1509    ##########################################################################
1510
1511    if exclude_garbage_time is True:
1512        gt_str = "true"
1513    elif exclude_garbage_time is False:
1514        gt_str = "false"
1515
1516    if season is not None and team is not None:
1517        url += f"?year={season}&team={team}"
1518    elif season is not None:
1519        url += f"?year={season}"
1520    elif team is not None:
1521        url += f"?team={team}"
1522
1523    if exclude_garbage_time is not None:
1524        url += f"&excludeGarbageTime={gt_str}"
1525
1526    if week is not None:
1527        url += f"&week={week}"
1528
1529    if opponent is not None:
1530        url += f"&opponent={opponent}"
1531
1532    headers = {
1533        "Authorization": f"{real_api_key}",
1534        "accept": "application/json"
1535    }
1536
1537    response = requests.get(url, headers=headers)
1538
1539    if response.status_code == 200:
1540        pass
1541    elif response.status_code == 401:
1542        raise ConnectionRefusedError(
1543            "Could not connect. The connection was refused." +
1544            "\nHTTP Status Code 401."
1545        )
1546    else:
1547        raise ConnectionError(
1548            f"Could not connect.\nHTTP Status code {response.status_code}"
1549        )
1550
1551    json_data = response.json()
1552
1553    if return_as_dict is True:
1554        return json_data
1555
1556    for team in tqdm(json_data):
1557        t_game_id = team["gameId"]
1558        t_week = team["week"]
1559        t_team = team["team"]
1560        t_opponent = team["opponent"]
1561
1562        if season is not None:
1563            row_df = pd.DataFrame(
1564                {
1565                    "season": season,
1566                    "game_id": t_game_id,
1567                    "week": t_week,
1568                    "team_name": t_team,
1569                    "opponent_name": t_opponent,
1570                },
1571                index=[0],
1572            )
1573        else:
1574
1575            row_df = pd.DataFrame(
1576                {
1577                    "game_id": t_game_id,
1578                    "week": t_week,
1579                    "team_name": t_team,
1580                    "opponent_name": t_opponent,
1581                },
1582                index=[0],
1583            )
1584
1585        # offense
1586        if "offense" not in team:
1587            logging.debug(
1588                "Key `[offense]` not found for " +
1589                f"Game ID #{t_game_id} and {t_team}, "
1590                + f"which happened in week {t_week}."
1591            )
1592        else:
1593            row_df["offense_plays"] = team["offense"]["plays"]
1594            row_df["offense_drives"] = team["offense"]["drives"]
1595            row_df["offense_ppa"] = team["offense"]["ppa"]
1596            row_df["offense_total_ppa"] = team["offense"]["totalPPA"]
1597            row_df["offense_success_rate"] = team["offense"]["successRate"]
1598            row_df["offense_explosiveness"] = team["offense"]["explosiveness"]
1599            row_df["offense_power_success"] = team["offense"]["powerSuccess"]
1600            row_df["offense_stuff_rate"] = team["offense"]["stuffRate"]
1601            row_df["offense_line_yards_avg"] = team["offense"]["lineYards"]
1602            row_df["offense_line_yards_total"] = team["offense"][
1603                "lineYardsTotal"
1604            ]
1605            row_df["offense_second_level_yards_avg"] = team["offense"][
1606                "secondLevelYards"
1607            ]
1608            row_df["offense_second_level_yards_total"] = team["offense"][
1609                "secondLevelYardsTotal"
1610            ]
1611            row_df["offense_open_field_yards_avg"] = team["offense"][
1612                "openFieldYards"
1613            ]
1614            row_df["offense_open_field_yards_total"] = team["offense"][
1615                "secondLevelYardsTotal"
1616            ]
1617
1618            row_df["offense_standard_downs_ppa"] = team[
1619                "offense"]["standardDowns"]["ppa"]
1620            row_df["offense_standard_downs_success_rate"] = team[
1621                "offense"]["standardDowns"]["successRate"]
1622            row_df["offense_standard_downs_explosiveness"] = team["offense"][
1623                "standardDowns"
1624            ]["explosiveness"]
1625
1626            row_df["offense_passing_downs_ppa"] = team[
1627                "offense"]["passingDowns"]["ppa"]
1628            row_df["offense_passing_downs_success_rate"] = team[
1629                "offense"]["passingDowns"]["successRate"]
1630            row_df["offense_passing_downs_explosiveness"] = team["offense"][
1631                "passingDowns"
1632            ]["explosiveness"]
1633
1634            row_df["offense_rushing_plays_ppa"] = team[
1635                "offense"]["rushingPlays"]["ppa"]
1636            row_df["offense_rushing_plays_total_ppa"] = team[
1637                "offense"]["rushingPlays"]["totalPPA"]
1638            row_df["offense_rushing_plays_success_rate"] = team[
1639                "offense"]["rushingPlays"]["successRate"]
1640            row_df["offense_rushing_plays_explosiveness"] = team[
1641                "offense"]["rushingPlays"]["explosiveness"]
1642
1643            row_df["offense_passing_plays_ppa"] = team[
1644                "offense"]["passingPlays"]["ppa"]
1645            row_df["offense_passing_plays_total_ppa"] = team[
1646                "offense"]["passingPlays"]["totalPPA"]
1647            row_df["offense_passing_plays_success_rate"] = team[
1648                "offense"]["passingPlays"]["successRate"]
1649            row_df["offense_passing_plays_explosiveness"] = team[
1650                "offense"]["rushingPlays"]["explosiveness"]
1651
1652        # defense
1653        if "defense" not in team:
1654            logging.debug(
1655                "Key `[defense]` not found for " +
1656                f"Game ID #{t_game_id} and {t_team}, "
1657                + f"which happened in week {t_week}."
1658            )
1659        else:
1660            row_df["defense_plays"] = team["defense"]["plays"]
1661            row_df["defense_drives"] = team["defense"]["drives"]
1662            row_df["defense_ppa"] = team["defense"]["ppa"]
1663            row_df["defense_total_ppa"] = team["defense"]["totalPPA"]
1664            row_df["defense_success_rate"] = team["defense"]["successRate"]
1665            row_df["defense_explosiveness"] = team["defense"]["explosiveness"]
1666            row_df["defense_power_success"] = team["defense"]["powerSuccess"]
1667            row_df["defense_stuff_rate"] = team["defense"]["stuffRate"]
1668            row_df["defense_line_yards_avg"] = team["defense"]["lineYards"]
1669            row_df["defense_line_yards_total"] = team["defense"][
1670                "lineYardsTotal"
1671            ]
1672            row_df["defense_second_level_yards_avg"] = team["defense"][
1673                "secondLevelYards"
1674            ]
1675            row_df["defense_second_level_yards_total"] = team["defense"][
1676                "secondLevelYardsTotal"
1677            ]
1678            row_df["defense_open_field_yards_avg"] = team["defense"][
1679                "openFieldYards"
1680            ]
1681            row_df["defense_open_field_yards_total"] = team["defense"][
1682                "secondLevelYardsTotal"
1683            ]
1684            row_df["defense_total_opportunities"] = team["defense"][
1685                "totalOpportunies"
1686            ]
1687            row_df["defense_points_per_opportunity"] = team["defense"][
1688                "pointsPerOpportunity"
1689            ]
1690
1691            row_df["defense_standard_downs_ppa"] = team[
1692                "defense"]["standardDowns"]["ppa"]
1693            row_df["defense_standard_downs_success_rate"] = team["defense"][
1694                "standardDowns"
1695            ]["successRate"]
1696            row_df["defense_standard_downs_explosiveness"] = team["defense"][
1697                "standardDowns"
1698            ]["explosiveness"]
1699
1700            row_df["defense_passing_downs_ppa"] = team[
1701                "defense"]["passingDowns"]["ppa"]
1702            row_df["defense_passing_downs_success_rate"] = team["defense"][
1703                "passingDowns"
1704            ]["successRate"]
1705            row_df["defense_passing_downs_explosiveness"] = team["defense"][
1706                "passingDowns"
1707            ]["explosiveness"]
1708
1709            row_df["defense_rushing_plays_ppa"] = team[
1710                "defense"]["rushingPlays"]["ppa"]
1711            row_df["defense_rushing_plays_total_ppa"] = team[
1712                "defense"]["rushingPlays"]["totalPPA"]
1713            row_df["defense_rushing_plays_success_rate"] = team["defense"][
1714                "rushingPlays"
1715            ]["successRate"]
1716            row_df["defense_rushing_plays_explosiveness"] = team["defense"][
1717                "rushingPlays"
1718            ]["explosiveness"]
1719
1720            row_df["defense_passing_plays_ppa"] = team[
1721                "defense"]["passingPlays"]["ppa"]
1722            row_df["defense_passing_plays_total_ppa"] = team[
1723                "defense"]["passingPlays"]["totalPPA"]
1724            row_df["defense_passing_plays_success_rate"] = team["defense"][
1725                "passingPlays"
1726            ]["successRate"]
1727            row_df["defense_passing_plays_explosiveness"] = team["defense"][
1728                "rushingPlays"
1729            ]["explosiveness"]
1730
1731        final_df = pd.concat([final_df, row_df], ignore_index=True)
1732        del row_df
1733        del t_game_id, t_week, t_team, t_opponent
1734
1735    return final_df
1736
1737
1738def get_cfbd_team_stat_categories(
1739    api_key: str = None, api_key_dir: str = None, return_as_dict: bool = False
1740):
1741    """
1742    Returns a list of stat categories
1743    for team stats directly from the CFBD API.
1744
1745    Parameters
1746    ----------
1747
1748    `api_key` (str, optional):
1749        Semi-optional argument.
1750        If `api_key` is null, this function will attempt to load a CFBD API key
1751        from the python environment, or from a file on this computer.
1752        If `api_key` is not null,
1753        this function will automatically assume that the
1754        inputted `api_key` is a valid CFBD API key.
1755
1756    `api_key_dir` (str, optional):
1757        Optional argument.
1758        If `api_key` is set to am empty string, this variable is ignored.
1759        If `api_key_dir` is null, and `api_key` is null,
1760        this function will try to find
1761        a CFBD API key file in this user's home directory.
1762        If `api_key_dir` is set to a string, and `api_key` is null,
1763        this function will assume that `api_key_dir` is a directory,
1764        and will try to find a CFBD API key file in that directory.
1765
1766    `return_as_dict` (bool, semi-optional):
1767        Semi-optional argument.
1768        If you want this function to return the data
1769        as a dictionary (read: JSON object),
1770        instead of a pandas `DataFrame` object,
1771        set `return_as_dict` to `True`.
1772
1773    Usage
1774    ----------
1775    ```
1776    import time
1777
1778    from cfbd_json_py.stats import get_cfbd_team_stat_categories
1779
1780
1781    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
1782
1783    if cfbd_key != "tigersAreAwesome":
1784        print(
1785            "Using the user's API key declared in this script " +
1786            "for this example."
1787        )
1788
1789        # Get a list of CFBD stat categories for team stats.
1790        print("Get a list of CFBD stat categories for team stats.")
1791        json_data = get_cfbd_team_stat_categories(
1792            api_key=cfbd_key
1793        )
1794        print(json_data)
1795        time.sleep(5)
1796
1797        # You can also tell this function to just return the API call as
1798        # a Dictionary (read: JSON) object.
1799        print(
1800            "You can also tell this function to just return the API call " +
1801            "as a Dictionary (read: JSON) object."
1802        )
1803        json_data = get_cfbd_team_stat_categories(
1804            api_key=cfbd_key,
1805            return_as_dict=True
1806        )
1807        print(json_data)
1808
1809    else:
1810        # Alternatively, if the CFBD API key exists in this python environment,
1811        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
1812        # you could just call these functions directly,
1813        # without setting the API key in the script.
1814        print(
1815            "Using the user's API key supposedly loaded " +
1816            "into this python environment for this example."
1817        )
1818
1819        # Get a list of CFBD stat categories for team stats.
1820        print("Get a list of CFBD stat categories for team stats.")
1821        json_data = get_cfbd_team_stat_categories()
1822        print(json_data)
1823        time.sleep(5)
1824
1825        # You can also tell this function to just return the API call as
1826        # a Dictionary (read: JSON) object.
1827        print(
1828            "You can also tell this function to just return the API call " +
1829            "as a Dictionary (read: JSON) object."
1830        )
1831        json_data = get_cfbd_team_stat_categories(
1832            return_as_dict=True
1833        )
1834        print(json_data)
1835
1836    ```
1837    Returns
1838    ----------
1839    A pandas `DataFrame` object with CFBD stat categories,
1840    or (if `return_as_dict` is set to `True`)
1841    a dictionary object with CFBD stat categories.
1842
1843    """
1844    url = "https://api.collegefootballdata.com/stats/categories"
1845
1846    if api_key is not None:
1847        real_api_key = api_key
1848        del api_key
1849    else:
1850        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1851
1852    if real_api_key == "tigersAreAwesome":
1853        raise ValueError(
1854            "You actually need to change `cfbd_key` to your CFBD API key."
1855        )
1856    elif "Bearer " in real_api_key:
1857        pass
1858    elif "Bearer" in real_api_key:
1859        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1860    else:
1861        real_api_key = "Bearer " + real_api_key
1862
1863    headers = {
1864        "Authorization": f"{real_api_key}",
1865        "accept": "application/json"
1866    }
1867
1868    response = requests.get(url, headers=headers)
1869
1870    if response.status_code == 200:
1871        pass
1872    elif response.status_code == 401:
1873        raise ConnectionRefusedError(
1874            "Could not connect. The connection was refused." +
1875            "\nHTTP Status Code 401."
1876        )
1877    else:
1878        raise ConnectionError(
1879            f"Could not connect.\nHTTP Status code {response.status_code}"
1880        )
1881
1882    json_data = response.json()
1883
1884    if return_as_dict is True:
1885        return json_data
1886
1887    return pd.DataFrame(json_data, columns=["stat_category"])
def get_cfbd_team_season_stats( api_key: str = None, api_key_dir: str = None, season: int = None, team: str = None, conference: str = None, start_week: int = None, end_week: int = None, return_as_dict: bool = False, use_original_column_names: bool = False):
 20def get_cfbd_team_season_stats(
 21    api_key: str = None,
 22    api_key_dir: str = None,
 23    season: int = None,
 24    team: str = None,
 25    # `year` and/or `team` need to be not null for this function to work.
 26    conference: str = None,
 27    start_week: int = None,
 28    end_week: int = None,
 29    return_as_dict: bool = False,
 30    use_original_column_names: bool = False,
 31):
 32    """
 33    Allows you to get CFB team season stats data from the CFBD API.
 34
 35    Parameters
 36    ----------
 37
 38    `api_key` (str, optional):
 39        Semi-optional argument.
 40        If `api_key` is null, this function will attempt to load a CFBD API key
 41        from the python environment, or from a file on this computer.
 42        If `api_key` is not null,
 43        this function will automatically assume that the
 44        inputted `api_key` is a valid CFBD API key.
 45
 46    `api_key_dir` (str, optional):
 47        Optional argument.
 48        If `api_key` is set to am empty string, this variable is ignored.
 49        If `api_key_dir` is null, and `api_key` is null,
 50        this function will try to find
 51        a CFBD API key file in this user's home directory.
 52        If `api_key_dir` is set to a string, and `api_key` is null,
 53        this function will assume that `api_key_dir` is a directory,
 54        and will try to find a CFBD API key file in that directory.
 55
 56    `season` (int, semi-mandatory):
 57        Semi-required argument.
 58        Specifies the season you want CFB team season stats data from.
 59        This must be specified, otherwise this package, and by extension
 60        the CFBD API, will not accept
 61        the request to get CFB team season stats data.
 62        This or `team` must be set
 63        to a valid non-null variable for this to function.
 64
 65    `team` (str, semi-mandatory):
 66        Semi-required argument.
 67        Specifies the season you want CFB team season stats data from.
 68        This must be specified, otherwise this package, and by extension
 69        the CFBD API, will not accept
 70        the request to get CFB team season stats data.
 71        This or `season` must be set
 72        to a valid non-null variable for this to function.
 73
 74    `conference` (str, optional):
 75        Optional argument.
 76        If you only want team season stats from games
 77        involving teams a specific conference,
 78        set `conference` to the abbreviation
 79        of the conference you want stats from.
 80
 81    `start_week` (int, semi-optional):
 82        Optional argument.
 83        If you only want team stats for a range of weeks,
 84        set `start_week` and `end_week` to
 85        the range of weeks you want season-level data for.
 86
 87    `end_week` (int, semi-optional):
 88        Optional argument.
 89        If you only want team stats for a range of weeks,
 90        set `start_week` and `end_week` to
 91        the range of weeks you want season-level data for.
 92
 93    **NOTE**: If the following conditions are `True`, a `ValueError()`
 94    will be raised when calling this function:
 95    - `start_week < 0`
 96    - `end_week < 0`
 97    - `start_week is not None and end_week is None`
 98        (will be changed in a future version)
 99    - `start_week is None and end_week is not None`
100        (will be changed in a future version)
101    - `end_week < start_week`
102    - `end_week = start_week`
103
104    `return_as_dict` (bool, semi-optional):
105        Semi-optional argument.
106        If you want this function to return
107        the data as a dictionary (read: JSON object),
108        instead of a pandas `DataFrame` object,
109        set `return_as_dict` to `True`.
110
111
112    Usage
113    ----------
114    ```
115    import time
116
117    from cfbd_json_py.stats import get_cfbd_team_season_stats
118
119
120    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
121
122    if cfbd_key != "tigersAreAwesome":
123        print(
124            "Using the user's API key declared in this script " +
125            "for this example."
126        )
127
128        # Get team season stats for the 2020 CFB season.
129        print("Get team season stats for the 2020 CFB season.")
130        json_data = get_cfbd_team_season_stats(
131            api_key=cfbd_key,
132            season=2020
133        )
134        print(json_data)
135        time.sleep(5)
136
137
138        # Get team season stats for teams competing in
139        # the Big 10 (B1G) conference the 2020 CFB season.
140        print(
141            "Get team season stats for teams competing in " +
142            "the Big 10 (B1G) conference the 2020 CFB season."
143        )
144        json_data = get_cfbd_team_season_stats(
145            api_key=cfbd_key,
146            conference="B1G",
147            season=2020
148        )
149        print(json_data)
150        time.sleep(5)
151
152        # Get team season stats for the 2020 CFB season,
153        # but only between weeks 5 and 10.
154        print("Get team season stats for the 2020 CFB season.")
155        json_data = get_cfbd_team_season_stats(
156            api_key=cfbd_key,
157            season=2020,
158            start_week=5,
159            end_week=10
160        )
161        print(json_data)
162        time.sleep(5)
163
164        # You can also tell this function to just return the API call as
165        # a Dictionary (read: JSON) object.
166        print(
167            "You can also tell this function to just return the API call " +
168            "as a Dictionary (read: JSON) object."
169        )
170        json_data = get_cfbd_team_season_stats(
171            api_key=cfbd_key,
172            season=2020,
173            return_as_dict=True
174        )
175        print(json_data)
176
177    else:
178        # Alternatively, if the CFBD API key exists in this python environment,
179        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
180        # you could just call these functions directly,
181        # without setting the API key in the script.
182        print(
183            "Using the user's API key supposedly loaded " +
184            "into this python environment for this example."
185        )
186
187
188        # Get team season stats for the 2020 CFB season.
189        print("Get team season stats for the 2020 CFB season.")
190        json_data = get_cfbd_team_season_stats(
191            season=2020
192        )
193        print(json_data)
194        time.sleep(5)
195
196
197        # Get team season stats for teams competing in
198        # the Big 10 (B1G) conference the 2020 CFB season.
199        print(
200            "Get team season stats for teams competing in " +
201            "the Big 10 (B1G) conference the 2020 CFB season."
202        )
203        json_data = get_cfbd_team_season_stats(
204            conference="B1G",
205            season=2020
206        )
207        print(json_data)
208        time.sleep(5)
209
210        # Get team season stats for the 2020 CFB season,
211        # but only between weeks 5 and 10.
212        print("Get team season stats for the 2020 CFB season.")
213        json_data = get_cfbd_team_season_stats(
214            season=2020,
215            start_week=5,
216            end_week=10
217        )
218        print(json_data)
219        time.sleep(5)
220
221        # You can also tell this function to just return the API call as
222        # a Dictionary (read: JSON) object.
223        print(
224            "You can also tell this function to just return the API call " +
225            "as a Dictionary (read: JSON) object."
226        )
227        json_data = get_cfbd_team_season_stats(
228            season=2020,
229            return_as_dict=True
230        )
231        print(json_data)
232    ```
233    Returns
234    ----------
235    A pandas `DataFrame` object with team season stats data,
236    or (if `return_as_dict` is set to `True`)
237    a dictionary object with a with team season stats data.
238
239    """
240
241    rebuilt_json = {}
242    stat_columns = [
243        "season",
244        "team_name",
245        "conference_name",
246        "games",
247        # Passing
248        "passing_COMP",
249        "passing_ATT",
250        "passing_NET_YDS",
251        "passing_TD",
252        "passing_INT",
253        # Rushing
254        "rushing_CAR",
255        "rushing_YDS",
256        "rushing_TD",
257        # Misc. Offense
258        "total_yards",
259        # Fumbles
260        "fumbles_LOST",
261        "fumbles_REC",
262        # Defense
263        "defensive_TFL",
264        "defensive_SACKS",
265        # Interceptions
266        "interceptions_INT",
267        "interceptions_YDS",
268        "interceptions_TD",
269        # Kick Returns
270        "kickReturns_NO",
271        "kickReturns_YDS",
272        "kickReturns_TD",
273        # Punt Returns
274        "puntReturns_NO",
275        "puntReturns_YDS",
276        "puntReturns_TD",
277        # Situational
278        "situational_first_downs",
279        "situational_third_down_conversions",
280        "situational_third_downs_attempted",
281        "situational_fourth_down_conversions",
282        "situational_fourth_downs_attempted",
283        "situational_penalties",
284        "situational_penalty_yards",
285        "situational_turnovers",
286        "situational_possession_time",
287    ]
288
289    now = datetime.now()
290    url = "https://api.collegefootballdata.com/stats/season"
291    row_df = pd.DataFrame()
292    final_df = pd.DataFrame()
293
294    if api_key is not None:
295        real_api_key = api_key
296        del api_key
297    else:
298        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
299
300    if real_api_key == "tigersAreAwesome":
301        raise ValueError(
302            "You actually need to change `cfbd_key` to your CFBD API key."
303        )
304    elif "Bearer " in real_api_key:
305        pass
306    elif "Bearer" in real_api_key:
307        real_api_key = real_api_key.replace("Bearer", "Bearer ")
308    else:
309        real_api_key = "Bearer " + real_api_key
310
311    if season is not None and (season > (now.year + 1)):
312        raise ValueError(f"`season` cannot be greater than {season}.")
313    elif season is not None and season < 1869:
314        raise ValueError("`season` cannot be less than 1869.")
315
316    if start_week is not None and end_week is not None:
317        if start_week > end_week:
318            raise ValueError("`start_week` cannot be greater than `end_week`.")
319        elif start_week == end_week:
320            raise ValueError(
321                "`start_week` cannot be equal to `end_week`."
322                + "\n Use " +
323                "`cfbd_json_py.games.get_cfbd_player_game_stats()` instead "
324                + "if you want player stats for a specific week in ."
325            )
326        elif start_week < 0:
327            raise ValueError("`start_week` cannot be less than 0.")
328        elif end_week < 0:
329            raise ValueError("`end_week` cannot be less than 0.")
330    # URL builder
331    ##########################################################################
332
333    # Required by the API
334
335    if season is not None and team is not None:
336        url += f"?year={season}&team={team}"
337    elif season is not None:
338        url += f"?year={season}"
339    elif team is not None:
340        url += f"?team={team}"
341
342    if conference is not None:
343        url += f"&conference={conference}"
344
345    if start_week is not None:
346        url += f"&startWeek={start_week}"
347
348    if end_week is not None:
349        url += f"&endWeek={end_week}"
350
351    headers = {
352        "Authorization": f"{real_api_key}",
353        "accept": "application/json"
354    }
355
356    response = requests.get(url, headers=headers)
357
358    if response.status_code == 200:
359        pass
360    elif response.status_code == 401:
361        raise ConnectionRefusedError(
362            "Could not connect. The connection was refused." +
363            "\nHTTP Status Code 401."
364        )
365    else:
366        raise ConnectionError(
367            f"Could not connect.\nHTTP Status code {response.status_code}"
368        )
369
370    json_data = response.json()
371
372    if return_as_dict is True:
373        return json_data
374
375    for stat in tqdm(json_data):
376        t_season = stat["season"]
377        t_team_name = stat["team"]
378        t_conference = stat["conference"]
379        stat_name = stat["statName"]
380        stat_value = stat["statValue"]
381        composite_key = f"{t_season}_{t_team_name}"
382
383        if rebuilt_json.get(composite_key) is None:
384            rebuilt_json[composite_key] = {}
385
386        match stat_name:
387            # General
388            case "games":
389                rebuilt_json[composite_key]["season"] = t_season
390                rebuilt_json[composite_key]["team_name"] = t_team_name
391                rebuilt_json[composite_key]["conference_name"] = t_conference
392                rebuilt_json[composite_key]["games"] = stat_value
393
394            # Passing
395            case "passCompletions":
396                rebuilt_json[composite_key]["season"] = t_season
397                rebuilt_json[composite_key]["team_name"] = t_team_name
398                rebuilt_json[composite_key]["conference_name"] = t_conference
399                rebuilt_json[composite_key]["passing_COMP"] = stat_value
400
401            case "passAttempts":
402                rebuilt_json[composite_key]["season"] = t_season
403                rebuilt_json[composite_key]["team_name"] = t_team_name
404                rebuilt_json[composite_key]["conference_name"] = t_conference
405                rebuilt_json[composite_key]["passing_ATT"] = stat_value
406
407            case "netPassingYards":
408                rebuilt_json[composite_key]["season"] = t_season
409                rebuilt_json[composite_key]["team_name"] = t_team_name
410                rebuilt_json[composite_key]["conference_name"] = t_conference
411                rebuilt_json[composite_key]["passing_NET_YDS"] = stat_value
412
413            case "passingTDs":
414                rebuilt_json[composite_key]["season"] = t_season
415                rebuilt_json[composite_key]["team_name"] = t_team_name
416                rebuilt_json[composite_key]["conference_name"] = t_conference
417                rebuilt_json[composite_key]["passing_TD"] = stat_value
418
419            case "passesIntercepted":
420                rebuilt_json[composite_key]["season"] = t_season
421                rebuilt_json[composite_key]["team_name"] = t_team_name
422                rebuilt_json[composite_key]["conference_name"] = t_conference
423                rebuilt_json[composite_key]["passing_INT"] = stat_value
424
425            # Rushing
426            case "rushingAttempts":
427                rebuilt_json[composite_key]["season"] = t_season
428                rebuilt_json[composite_key]["team_name"] = t_team_name
429                rebuilt_json[composite_key]["conference_name"] = t_conference
430                rebuilt_json[composite_key]["rushing_CAR"] = stat_value
431
432            case "rushingYards":
433                rebuilt_json[composite_key]["season"] = t_season
434                rebuilt_json[composite_key]["team_name"] = t_team_name
435                rebuilt_json[composite_key]["conference_name"] = t_conference
436                rebuilt_json[composite_key]["rushing_YDS"] = stat_value
437
438            case "rushingTDs":
439                rebuilt_json[composite_key]["season"] = t_season
440                rebuilt_json[composite_key]["team_name"] = t_team_name
441                rebuilt_json[composite_key]["conference_name"] = t_conference
442                rebuilt_json[composite_key]["rushing_TD"] = stat_value
443
444            # Misc Offense
445            case "totalYards":
446                rebuilt_json[composite_key]["season"] = t_season
447                rebuilt_json[composite_key]["team_name"] = t_team_name
448                rebuilt_json[composite_key]["conference_name"] = t_conference
449                rebuilt_json[composite_key]["total_yards"] = stat_value
450
451            # Fumbles
452            case "fumblesLost":
453                rebuilt_json[composite_key]["season"] = t_season
454                rebuilt_json[composite_key]["team_name"] = t_team_name
455                rebuilt_json[composite_key]["conference_name"] = t_conference
456                rebuilt_json[composite_key]["fumbles_LOST"] = stat_value
457
458            case "fumblesRecovered":
459                rebuilt_json[composite_key]["season"] = t_season
460                rebuilt_json[composite_key]["team_name"] = t_team_name
461                rebuilt_json[composite_key]["conference_name"] = t_conference
462                rebuilt_json[composite_key]["fumbles_REC"] = stat_value
463
464            # Defense
465            case "tacklesForLoss":
466                rebuilt_json[composite_key]["season"] = t_season
467                rebuilt_json[composite_key]["team_name"] = t_team_name
468                rebuilt_json[composite_key]["conference_name"] = t_conference
469                rebuilt_json[composite_key]["defensive_TFL"] = stat_value
470
471            case "sacks":
472                rebuilt_json[composite_key]["season"] = t_season
473                rebuilt_json[composite_key]["team_name"] = t_team_name
474                rebuilt_json[composite_key]["conference_name"] = t_conference
475                rebuilt_json[composite_key]["defensive_SACKS"] = stat_value
476
477            # Interceptions
478            case "interceptions":
479                rebuilt_json[composite_key]["season"] = t_season
480                rebuilt_json[composite_key]["team_name"] = t_team_name
481                rebuilt_json[composite_key]["conference_name"] = t_conference
482                rebuilt_json[composite_key]["interceptions_INT"] = stat_value
483
484            case "interceptionYards":
485                rebuilt_json[composite_key]["season"] = t_season
486                rebuilt_json[composite_key]["team_name"] = t_team_name
487                rebuilt_json[composite_key]["conference_name"] = t_conference
488                rebuilt_json[composite_key]["interceptions_YDS"] = stat_value
489
490            case "interceptionTDs":
491                rebuilt_json[composite_key]["season"] = t_season
492                rebuilt_json[composite_key]["team_name"] = t_team_name
493                rebuilt_json[composite_key]["conference_name"] = t_conference
494                rebuilt_json[composite_key]["interceptions_TD"] = stat_value
495
496            # Kick Returns
497            case "kickReturns":
498                rebuilt_json[composite_key]["season"] = t_season
499                rebuilt_json[composite_key]["team_name"] = t_team_name
500                rebuilt_json[composite_key]["conference_name"] = t_conference
501                rebuilt_json[composite_key]["kickReturns_NO"] = stat_value
502
503            case "kickReturnYards":
504                rebuilt_json[composite_key]["season"] = t_season
505                rebuilt_json[composite_key]["team_name"] = t_team_name
506                rebuilt_json[composite_key]["conference_name"] = t_conference
507                rebuilt_json[composite_key]["kickReturns_YDS"] = stat_value
508
509            case "kickReturnTDs":
510                rebuilt_json[composite_key]["season"] = t_season
511                rebuilt_json[composite_key]["team_name"] = t_team_name
512                rebuilt_json[composite_key]["conference_name"] = t_conference
513                rebuilt_json[composite_key]["kickReturns_TD"] = stat_value
514
515            # Punt Returns
516            case "puntReturns":
517                rebuilt_json[composite_key]["season"] = t_season
518                rebuilt_json[composite_key]["team_name"] = t_team_name
519                rebuilt_json[composite_key]["conference_name"] = t_conference
520                rebuilt_json[composite_key]["puntReturns_NO"] = stat_value
521
522            case "puntReturnYards":
523                rebuilt_json[composite_key]["season"] = t_season
524                rebuilt_json[composite_key]["team_name"] = t_team_name
525                rebuilt_json[composite_key]["conference_name"] = t_conference
526                rebuilt_json[composite_key]["puntReturns_YDS"] = stat_value
527
528            case "puntReturnTDs":
529                rebuilt_json[composite_key]["season"] = t_season
530                rebuilt_json[composite_key]["team_name"] = t_team_name
531                rebuilt_json[composite_key]["conference_name"] = t_conference
532                rebuilt_json[composite_key]["puntReturns_TD"] = stat_value
533
534            # Situational
535            case "firstDowns":
536                rebuilt_json[composite_key]["season"] = t_season
537                rebuilt_json[composite_key]["team_name"] = t_team_name
538                rebuilt_json[composite_key]["conference_name"] = t_conference
539                rebuilt_json[composite_key][
540                    "situational_first_downs"] = stat_value
541
542            case "turnovers":
543                rebuilt_json[composite_key]["season"] = t_season
544                rebuilt_json[composite_key]["team_name"] = t_team_name
545                rebuilt_json[composite_key]["conference_name"] = t_conference
546                rebuilt_json[composite_key][
547                    "situational_turnovers"] = stat_value
548
549            case "thirdDownConversions":
550                rebuilt_json[composite_key]["season"] = t_season
551                rebuilt_json[composite_key]["team_name"] = t_team_name
552                rebuilt_json[composite_key]["conference_name"] = t_conference
553                rebuilt_json[composite_key][
554                    "situational_third_down_conversions"
555                ] = stat_value
556
557            case "thirdDowns":
558                rebuilt_json[composite_key]["season"] = t_season
559                rebuilt_json[composite_key]["team_name"] = t_team_name
560                rebuilt_json[composite_key]["conference_name"] = t_conference
561                rebuilt_json[composite_key][
562                    "situational_third_downs_attempted"
563                ] = stat_value
564
565            case "fourthDownConversions":
566                rebuilt_json[composite_key]["season"] = t_season
567                rebuilt_json[composite_key]["team_name"] = t_team_name
568                rebuilt_json[composite_key]["conference_name"] = t_conference
569                rebuilt_json[composite_key][
570                    "situational_fourth_down_conversions"
571                ] = stat_value
572
573            case "fourthDowns":
574                rebuilt_json[composite_key]["season"] = t_season
575                rebuilt_json[composite_key]["team_name"] = t_team_name
576                rebuilt_json[composite_key]["conference_name"] = t_conference
577                rebuilt_json[composite_key][
578                    "situational_fourth_downs_attempted"
579                ] = stat_value
580
581            case "penalties":
582                rebuilt_json[composite_key]["season"] = t_season
583                rebuilt_json[composite_key]["team_name"] = t_team_name
584                rebuilt_json[composite_key]["conference_name"] = t_conference
585                rebuilt_json[composite_key][
586                    "situational_penalties"] = stat_value
587
588            case "penaltyYards":
589                rebuilt_json[composite_key]["season"] = t_season
590                rebuilt_json[composite_key]["team_name"] = t_team_name
591                rebuilt_json[composite_key]["conference_name"] = t_conference
592                rebuilt_json[composite_key][
593                    "situational_penalty_yards"] = stat_value
594
595            case "possessionTime":
596                rebuilt_json[composite_key]["season"] = t_season
597                rebuilt_json[composite_key]["team_name"] = t_team_name
598                rebuilt_json[composite_key]["conference_name"] = t_conference
599                rebuilt_json[composite_key][
600                    "situational_possession_time"] = stat_value
601
602            case _:
603                raise ValueError(f"Unhandled stat name `{stat_name}`")
604
605        del t_season, t_team_name, t_conference
606        del (
607            stat_name,
608            stat_value,
609        )
610        del composite_key
611
612    for key, value in tqdm(rebuilt_json.items()):
613        row_df = pd.DataFrame(value, index=[0])
614        final_df = pd.concat([final_df, row_df], ignore_index=True)
615
616    final_df = final_df[stat_columns]
617    return final_df

Allows you to get CFB team season stats data 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.

season (int, semi-mandatory): Semi-required argument. Specifies the season you want CFB team season stats data from. This must be specified, otherwise this package, and by extension the CFBD API, will not accept the request to get CFB team season stats data. This or team must be set to a valid non-null variable for this to function.

team (str, semi-mandatory): Semi-required argument. Specifies the season you want CFB team season stats data from. This must be specified, otherwise this package, and by extension the CFBD API, will not accept the request to get CFB team season stats data. This or season must be set to a valid non-null variable for this to function.

conference (str, optional): Optional argument. If you only want team season stats from games involving teams a specific conference, set conference to the abbreviation of the conference you want stats from.

start_week (int, semi-optional): Optional argument. If you only want team stats for a range of weeks, set start_week and end_week to the range of weeks you want season-level data for.

end_week (int, semi-optional): Optional argument. If you only want team stats for a range of weeks, set start_week and end_week to the range of weeks you want season-level data for.

NOTE: If the following conditions are True, a ValueError() will be raised when calling this function:

  • start_week < 0
  • end_week < 0
  • start_week is not None and end_week is None (will be changed in a future version)
  • start_week is None and end_week is not None (will be changed in a future version)
  • end_week < start_week
  • end_week = start_week

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


    # Get team season stats for teams competing in
    # the Big 10 (B1G) conference the 2020 CFB season.
    print(
        "Get team season stats for teams competing in " +
        "the Big 10 (B1G) conference the 2020 CFB season."
    )
    json_data = get_cfbd_team_season_stats(
        api_key=cfbd_key,
        conference="B1G",
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get team season stats for the 2020 CFB season,
    # but only between weeks 5 and 10.
    print("Get team season stats for the 2020 CFB season.")
    json_data = get_cfbd_team_season_stats(
        api_key=cfbd_key,
        season=2020,
        start_week=5,
        end_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_team_season_stats(
        api_key=cfbd_key,
        season=2020,
        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 team season stats for the 2020 CFB season.
    print("Get team season stats for the 2020 CFB season.")
    json_data = get_cfbd_team_season_stats(
        season=2020
    )
    print(json_data)
    time.sleep(5)


    # Get team season stats for teams competing in
    # the Big 10 (B1G) conference the 2020 CFB season.
    print(
        "Get team season stats for teams competing in " +
        "the Big 10 (B1G) conference the 2020 CFB season."
    )
    json_data = get_cfbd_team_season_stats(
        conference="B1G",
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get team season stats for the 2020 CFB season,
    # but only between weeks 5 and 10.
    print("Get team season stats for the 2020 CFB season.")
    json_data = get_cfbd_team_season_stats(
        season=2020,
        start_week=5,
        end_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_team_season_stats(
        season=2020,
        return_as_dict=True
    )
    print(json_data)

Returns

A pandas DataFrame object with team season stats data, or (if return_as_dict is set to True) a dictionary object with a with team season stats data.

def get_cfbd_advanced_team_season_stats( api_key: str = None, api_key_dir: str = None, season: int = None, team: str = None, exclude_garbage_time: bool = False, start_week: int = None, end_week: int = None, return_as_dict: bool = False):
 620def get_cfbd_advanced_team_season_stats(
 621    api_key: str = None,
 622    api_key_dir: str = None,
 623    season: int = None,
 624    team: str = None,
 625    # `year` and/or `team` need to be not null for this function to work.
 626    exclude_garbage_time: bool = False,
 627    start_week: int = None,
 628    end_week: int = None,
 629    return_as_dict: bool = False,
 630):
 631    """
 632    Allows you to get advanced CFB team season stats data from the CFBD API.
 633
 634    Parameters
 635    ----------
 636
 637    `api_key` (str, optional):
 638        Semi-optional argument.
 639        If `api_key` is null, this function will attempt to load a CFBD API key
 640        from the python environment, or from a file on this computer.
 641        If `api_key` is not null,
 642        this function will automatically assume that the
 643        inputted `api_key` is a valid CFBD API key.
 644
 645    `api_key_dir` (str, optional):
 646        Optional argument.
 647        If `api_key` is set to am empty string, this variable is ignored.
 648        If `api_key_dir` is null, and `api_key` is null,
 649        this function will try to find
 650        a CFBD API key file in this user's home directory.
 651        If `api_key_dir` is set to a string, and `api_key` is null,
 652        this function will assume that `api_key_dir` is a directory,
 653        and will try to find a CFBD API key file in that directory.
 654
 655    `season` (int, semi-mandatory):
 656        Semi-required argument.
 657        Specifies the season you want CFB team season stats data from.
 658        This must be specified, otherwise this package, and by extension
 659        the CFBD API, will not accept the request
 660        to get CFB team season stats data.
 661        This or `team` must be set
 662        to a valid non-null variable for this to function.
 663
 664    `team` (str, semi-mandatory):
 665        Semi-required argument.
 666        Specifies the season you want advanced CFB team season stats data from.
 667        This must be specified, otherwise this package, and by extension
 668        the CFBD API, will not accept
 669        the request to get CFB team season stats data.
 670        This or `season` must be set
 671        to a valid non-null variable for this to function.
 672
 673    `exclude_garbage_time` (bool, optional):
 674        Optional argument.
 675        If you want to filter out plays where
 676        the result of the game is largely decided,
 677        set `exclude_garbage_time = True`.
 678        Default behavior is that this variable is set to
 679        `False` when this function is called.
 680
 681    `start_week` (int, semi-optional):
 682        Optional argument.
 683        If you only want team stats for a range of weeks,
 684        set `start_week` and `end_week` to
 685        the range of weeks you want season-level data for.
 686
 687    `end_week` (int, semi-optional):
 688        Optional argument.
 689        If you only want team stats for a range of weeks,
 690        set `start_week` and `end_week` to
 691        the range of weeks you want season-level data for.
 692
 693    **NOTE**: If the following conditions are `True`, a `ValueError()`
 694    will be raised when calling this function:
 695    - `start_week < 0`
 696    - `end_week < 0`
 697    - `start_week is not None and end_week is None`
 698        (will be changed in a future version)
 699    - `start_week is None and end_week is not None`
 700        (will be changed in a future version)
 701    - `end_week < start_week`
 702    - `end_week = start_week`
 703
 704    `return_as_dict` (bool, semi-optional):
 705        Semi-optional argument.
 706        If you want this function to return
 707        the data as a dictionary (read: JSON object),
 708        instead of a pandas `DataFrame` object,
 709        set `return_as_dict` to `True`.
 710
 711
 712    Usage
 713    ----------
 714    ```
 715
 716    import time
 717
 718    from cfbd_json_py.stats import get_cfbd_advanced_team_season_stats
 719
 720
 721    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 722
 723    if cfbd_key != "tigersAreAwesome":
 724        print(
 725            "Using the user's API key declared in this script " +
 726            "for this example."
 727        )
 728
 729        # Get advanced team season stats for the 2020 CFB season.
 730        print("Get team season stats for the 2020 CFB season.")
 731        json_data = get_cfbd_advanced_team_season_stats(
 732            api_key=cfbd_key,
 733            season=2020
 734        )
 735        print(json_data)
 736        time.sleep(5)
 737
 738        # Get advanced team season stats for the 2020 CFB season,
 739        # but remove plays that happen in garbage time.
 740        print(
 741            "Get advanced team season stats for the 2020 CFB season, " +
 742            "but remove plays that happen in garbage time."
 743        )
 744        json_data = get_cfbd_advanced_team_season_stats(
 745            api_key=cfbd_key,
 746            season=2020,
 747            exclude_garbage_time=True
 748        )
 749        print(json_data)
 750        time.sleep(5)
 751
 752        # Get advanced team season stats for the 2020 CFB season,
 753        # but only between weeks 5 and 10.
 754        print(
 755            "Get advanced team season stats for the 2020 CFB season, " +
 756            "but only between weeks 5 and 10."
 757        )
 758        json_data = get_cfbd_advanced_team_season_stats(
 759            api_key=cfbd_key,
 760            season=2020,
 761            start_week=5,
 762            end_week=10
 763        )
 764        print(json_data)
 765        time.sleep(5)
 766
 767        # Get advanced team season stats for just
 768        # the Ohio State Buckeyes Football Team.
 769        print(
 770            "Get advanced team season stats for just" +
 771            " the Ohio State Buckeyes Football Team."
 772        )
 773        json_data = get_cfbd_advanced_team_season_stats(
 774            api_key=cfbd_key,
 775            team="Ohio State"
 776        )
 777        print(json_data)
 778        time.sleep(5)
 779
 780
 781        # You can also tell this function to just return the API call as
 782        # a Dictionary (read: JSON) object.
 783        print(
 784            "You can also tell this function to just return the API call " +
 785            "as a Dictionary (read: JSON) object."
 786        )
 787        json_data = get_cfbd_advanced_team_season_stats(
 788            api_key=cfbd_key,
 789            season=2020,
 790            team="Cincinnati",
 791            return_as_dict=True
 792        )
 793        print(json_data)
 794
 795    else:
 796        # Alternatively, if the CFBD API key exists in this python environment,
 797        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 798        # you could just call these functions directly,
 799        # without setting the API key in the script.
 800        print(
 801            "Using the user's API key supposedly loaded " +
 802            "into this python environment for this example."
 803        )
 804
 805    # Get advanced team season stats for the 2020 CFB season.
 806        print("Get team season stats for the 2020 CFB season.")
 807        json_data = get_cfbd_advanced_team_season_stats(
 808            season=2020
 809        )
 810        print(json_data)
 811        time.sleep(5)
 812
 813        # Get advanced team season stats for the 2020 CFB season,
 814        # but remove plays that happen in garbage time.
 815        print(
 816            "Get advanced team season stats for the 2020 CFB season, " +
 817            "but remove plays that happen in garbage time."
 818        )
 819        json_data = get_cfbd_advanced_team_season_stats(
 820            season=2020,
 821            exclude_garbage_time=True
 822        )
 823        print(json_data)
 824        time.sleep(5)
 825
 826        # Get advanced team season stats for the 2020 CFB season,
 827        # but only between weeks 5 and 10.
 828        print(
 829            "Get advanced team season stats for the 2020 CFB season, " +
 830            "but only between weeks 5 and 10."
 831        )
 832        json_data = get_cfbd_advanced_team_season_stats(
 833            season=2020,
 834            start_week=5,
 835            end_week=10
 836        )
 837        print(json_data)
 838        time.sleep(5)
 839
 840        # Get advanced team season stats for the just
 841        # the Ohio State Buckeyes Football Team.
 842        print(
 843            "Get advanced team season stats for the just " +
 844            "the Ohio State Buckeyes Football Team."
 845        )
 846        json_data = get_cfbd_advanced_team_season_stats(
 847            team="Ohio State"
 848        )
 849        print(json_data)
 850        time.sleep(5)
 851
 852
 853        # You can also tell this function to just return the API call as
 854        # a Dictionary (read: JSON) object.
 855        print(
 856            "You can also tell this function to just return the API call " +
 857            "as a Dictionary (read: JSON) object."
 858        )
 859        json_data = get_cfbd_advanced_team_season_stats(
 860            season=2020,
 861            team="Cincinnati",
 862            return_as_dict=True
 863        )
 864        print(json_data)
 865    ```
 866    Returns
 867    ----------
 868    A pandas `DataFrame` object with advanced team season stats data,
 869    or (if `return_as_dict` is set to `True`)
 870    a dictionary object with a with advanced team season stats data.
 871
 872    """
 873    now = datetime.now()
 874    url = "https://api.collegefootballdata.com/stats/season/advanced"
 875    row_df = pd.DataFrame()
 876    final_df = pd.DataFrame()
 877
 878    if api_key is not None:
 879        real_api_key = api_key
 880        del api_key
 881    else:
 882        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
 883
 884    if real_api_key == "tigersAreAwesome":
 885        raise ValueError(
 886            "You actually need to change `cfbd_key` to your CFBD API key."
 887        )
 888    elif "Bearer " in real_api_key:
 889        pass
 890    elif "Bearer" in real_api_key:
 891        real_api_key = real_api_key.replace("Bearer", "Bearer ")
 892    else:
 893        real_api_key = "Bearer " + real_api_key
 894
 895    if season is not None and (season > (now.year + 1)):
 896        raise ValueError(f"`season` cannot be greater than {season}.")
 897    elif season is not None and season < 1869:
 898        raise ValueError("`season` cannot be less than 1869.")
 899
 900    if start_week is not None and end_week is not None:
 901        if start_week > end_week:
 902            raise ValueError("`start_week` cannot be greater than `end_week`.")
 903        elif start_week == end_week:
 904            raise ValueError(
 905                "`start_week` cannot be equal to `end_week`."
 906                + "\n Use " +
 907                "`cfbd_json_py.games.get_cfbd_player_game_stats()` instead "
 908                + "if you want player stats for a specific week in ."
 909            )
 910        elif start_week < 0:
 911            raise ValueError("`start_week` cannot be less than 0.")
 912        elif end_week < 0:
 913            raise ValueError("`end_week` cannot be less than 0.")
 914
 915    gt_str = ""
 916
 917    # URL builder
 918    ##########################################################################
 919
 920    if exclude_garbage_time is True:
 921        gt_str = "true"
 922    elif exclude_garbage_time is False:
 923        gt_str = "false"
 924
 925    if season is not None and team is not None:
 926        url += f"?year={season}&team={team}"
 927    elif season is not None:
 928        url += f"?year={season}"
 929    elif team is not None:
 930        url += f"?team={team}"
 931
 932    if exclude_garbage_time is not None:
 933        url += f"&excludeGarbageTime={gt_str}"
 934
 935    if start_week is not None:
 936        url += f"&startWeek={start_week}"
 937
 938    if end_week is not None:
 939        url += f"&endWeek={end_week}"
 940
 941    headers = {
 942        "Authorization": f"{real_api_key}",
 943        "accept": "application/json"
 944    }
 945
 946    response = requests.get(url, headers=headers)
 947
 948    if response.status_code == 200:
 949        pass
 950    elif response.status_code == 401:
 951        raise ConnectionRefusedError(
 952            "Could not connect. The connection was refused." +
 953            "\nHTTP Status Code 401."
 954        )
 955    else:
 956        raise ConnectionError(
 957            f"Could not connect.\nHTTP Status code {response.status_code}"
 958        )
 959
 960    json_data = response.json()
 961
 962    if return_as_dict is True:
 963        return json_data
 964
 965    for team in tqdm(json_data):
 966        t_season = team["season"]
 967        t_team = team["team"]
 968        t_conf = team["conference"]
 969        row_df = pd.DataFrame(
 970            {
 971                "season": t_season,
 972                "team": t_team,
 973                "conference": t_conf
 974            },
 975            index=[0]
 976        )
 977
 978        # offense
 979        if "offense" not in team:
 980            logging.debug(
 981                f"Key `[offense]` not found for the {t_season} {t_team}."
 982            )
 983        else:
 984            row_df["offense_plays"] = team["offense"]["plays"]
 985            row_df["offense_drives"] = team["offense"]["drives"]
 986            # row_df["offense_plays"] = team["offense"]["plays"]
 987            row_df["offense_ppa"] = team["offense"]["ppa"]
 988            row_df["offense_total_ppa"] = team["offense"]["totalPPA"]
 989            row_df["offense_success_rate"] = team["offense"]["successRate"]
 990            row_df["offense_explosiveness"] = team["offense"]["explosiveness"]
 991            row_df["offense_power_success"] = team["offense"]["powerSuccess"]
 992            row_df["offense_stuff_rate"] = team["offense"]["stuffRate"]
 993            row_df["offense_line_yards_avg"] = team["offense"]["lineYards"]
 994            row_df["offense_line_yards_total"] = team["offense"][
 995                "lineYardsTotal"
 996            ]
 997            row_df["offense_second_level_yards_avg"] = team["offense"][
 998                "secondLevelYards"
 999            ]
1000            row_df["offense_second_level_yards_total"] = team["offense"][
1001                "secondLevelYardsTotal"
1002            ]
1003            row_df["offense_open_field_yards_avg"] = team["offense"][
1004                "openFieldYards"
1005            ]
1006            row_df["offense_open_field_yards_total"] = team["offense"][
1007                "secondLevelYardsTotal"
1008            ]
1009            row_df["offense_total_opportunities"] = team["offense"][
1010                "totalOpportunies"
1011            ]
1012            row_df["offense_points_per_opportunity"] = team["offense"][
1013                "pointsPerOpportunity"
1014            ]
1015
1016            row_df["offense_field_position_avg_start"] = team["offense"][
1017                "fieldPosition"]["averageStart"]
1018            row_df["offense_field_position_avg_predicted_points"] = team[
1019                "offense"]["fieldPosition"]["averagePredictedPoints"]
1020
1021            row_df["offense_havoc_total"] = team["offense"]["havoc"]["total"]
1022            row_df["offense_havoc_front_7"] = team["offense"]["havoc"][
1023                "frontSeven"
1024            ]
1025            row_df["offense_havoc_db"] = team["offense"]["havoc"]["db"]
1026
1027            row_df["offense_standard_downs_rate"] = team[
1028                "offense"]["standardDowns"]["rate"]
1029            row_df["offense_standard_downs_ppa"] = team[
1030                "offense"]["standardDowns"]["ppa"]
1031            row_df["offense_standard_downs_success_rate"] = team["offense"][
1032                "standardDowns"
1033            ]["successRate"]
1034            row_df["offense_standard_downs_explosiveness"] = team["offense"][
1035                "standardDowns"
1036            ]["explosiveness"]
1037
1038            row_df["offense_passing_downs_rate"] = team[
1039                "offense"]["passingDowns"]["rate"]
1040            row_df["offense_passing_downs_ppa"] = team[
1041                "offense"]["passingDowns"]["ppa"]
1042            row_df["offense_passing_downs_success_rate"] = team["offense"][
1043                "passingDowns"
1044            ]["successRate"]
1045            row_df["offense_passing_downs_explosiveness"] = team["offense"][
1046                "passingDowns"
1047            ]["explosiveness"]
1048
1049            row_df["offense_rushing_plays_rate"] = team[
1050                "offense"]["rushingPlays"]["rate"]
1051            row_df["offense_rushing_plays_ppa"] = team[
1052                "offense"]["rushingPlays"]["ppa"]
1053            row_df["offense_rushing_plays_total_ppa"] = team[
1054                "offense"]["rushingPlays"]["totalPPA"]
1055            row_df["offense_rushing_plays_success_rate"] = team[
1056                "offense"]["rushingPlays"]["successRate"]
1057            row_df["offense_rushing_plays_explosiveness"] = team[
1058                "offense"]["rushingPlays"]["explosiveness"]
1059
1060            row_df["offense_passing_plays_rate"] = team[
1061                "offense"]["passingPlays"]["rate"]
1062            row_df["offense_passing_plays_ppa"] = team[
1063                "offense"]["passingPlays"]["ppa"]
1064            row_df["offense_passing_plays_total_ppa"] = team[
1065                "offense"]["passingPlays"]["totalPPA"]
1066            row_df["offense_passing_plays_success_rate"] = team[
1067                "offense"]["passingPlays"]["successRate"]
1068            row_df["offense_passing_plays_explosiveness"] = team[
1069                "offense"]["rushingPlays"]["explosiveness"]
1070
1071        # defense
1072        if "defense" not in team:
1073            logging.debug(
1074                f"Key `[defense]` not found for the {t_season} {t_team}."
1075            )
1076        else:
1077
1078            row_df["defense_plays"] = team["defense"]["plays"]
1079            row_df["defense_drives"] = team["defense"]["drives"]
1080            # row_df["defense_plays"] = team["defense"]["plays"]
1081            row_df["defense_ppa"] = team["defense"]["ppa"]
1082            row_df["defense_total_ppa"] = team["defense"]["totalPPA"]
1083            row_df["defense_success_rate"] = team["defense"]["successRate"]
1084            row_df["defense_explosiveness"] = team["defense"]["explosiveness"]
1085            row_df["defense_power_success"] = team["defense"]["powerSuccess"]
1086            row_df["defense_stuff_rate"] = team["defense"]["stuffRate"]
1087            row_df["defense_line_yards_avg"] = team["defense"]["lineYards"]
1088            row_df["defense_line_yards_total"] = team["defense"][
1089                "lineYardsTotal"
1090            ]
1091            row_df["defense_second_level_yards_avg"] = team["defense"][
1092                "secondLevelYards"
1093            ]
1094            row_df["defense_second_level_yards_total"] = team["defense"][
1095                "secondLevelYardsTotal"
1096            ]
1097            row_df["defense_open_field_yards_avg"] = team["defense"][
1098                "openFieldYards"
1099            ]
1100            row_df["defense_open_field_yards_total"] = team["defense"][
1101                "secondLevelYardsTotal"
1102            ]
1103            row_df["defense_total_opportunities"] = team["defense"][
1104                "totalOpportunies"
1105            ]
1106            row_df["defense_points_per_opportunity"] = team["defense"][
1107                "pointsPerOpportunity"
1108            ]
1109
1110            row_df["defense_field_position_avg_start"] = team["defense"][
1111                "fieldPosition"
1112            ]["averageStart"]
1113            row_df["defense_field_position_avg_predicted_points"] = team[
1114                "defense"]["fieldPosition"]["averagePredictedPoints"]
1115
1116            row_df["defense_havoc_total"] = team["defense"]["havoc"]["total"]
1117            row_df["defense_havoc_front_7"] = team["defense"]["havoc"][
1118                "frontSeven"
1119            ]
1120            row_df["defense_havoc_db"] = team["defense"]["havoc"]["db"]
1121
1122            row_df["defense_standard_downs_rate"] = team[
1123                "defense"]["standardDowns"]["rate"]
1124            row_df["defense_standard_downs_ppa"] = team[
1125                "defense"]["standardDowns"]["ppa"]
1126            row_df["defense_standard_downs_success_rate"] = team["defense"][
1127                "standardDowns"
1128            ]["successRate"]
1129            row_df["defense_standard_downs_explosiveness"] = team["defense"][
1130                "standardDowns"
1131            ]["explosiveness"]
1132
1133            row_df["defense_passing_downs_rate"] = team[
1134                "defense"]["passingDowns"]["rate"]
1135            row_df["defense_passing_downs_ppa"] = team[
1136                "defense"]["passingDowns"]["ppa"]
1137            row_df["defense_passing_downs_success_rate"] = team["defense"][
1138                "passingDowns"
1139            ]["successRate"]
1140            row_df["defense_passing_downs_explosiveness"] = team["defense"][
1141                "passingDowns"
1142            ]["explosiveness"]
1143
1144            row_df["defense_rushing_plays_rate"] = team[
1145                "defense"]["rushingPlays"]["rate"]
1146            row_df["defense_rushing_plays_ppa"] = team[
1147                "defense"]["rushingPlays"]["ppa"]
1148            row_df["defense_rushing_plays_total_ppa"] = team[
1149                "defense"]["rushingPlays"]["totalPPA"]
1150            row_df["defense_rushing_plays_success_rate"] = team["defense"][
1151                "rushingPlays"
1152            ]["successRate"]
1153            row_df["defense_rushing_plays_explosiveness"] = team["defense"][
1154                "rushingPlays"
1155            ]["explosiveness"]
1156
1157            row_df["defense_passing_plays_rate"] = team[
1158                "defense"]["passingPlays"]["rate"]
1159            row_df["defense_passing_plays_ppa"] = team[
1160                "defense"]["passingPlays"]["ppa"]
1161            row_df["defense_passing_plays_total_ppa"] = team[
1162                "defense"]["passingPlays"]["totalPPA"]
1163            row_df["defense_passing_plays_success_rate"] = team["defense"][
1164                "passingPlays"
1165            ]["successRate"]
1166            row_df["defense_passing_plays_explosiveness"] = team["defense"][
1167                "rushingPlays"
1168            ]["explosiveness"]
1169
1170        final_df = pd.concat([final_df, row_df], ignore_index=True)
1171        del row_df
1172        del t_season, t_conf, t_team
1173
1174    return final_df

Allows you to get advanced CFB team season stats data 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.

season (int, semi-mandatory): Semi-required argument. Specifies the season you want CFB team season stats data from. This must be specified, otherwise this package, and by extension the CFBD API, will not accept the request to get CFB team season stats data. This or team must be set to a valid non-null variable for this to function.

team (str, semi-mandatory): Semi-required argument. Specifies the season you want advanced CFB team season stats data from. This must be specified, otherwise this package, and by extension the CFBD API, will not accept the request to get CFB team season stats data. This or season must be set to a valid non-null variable for this to function.

exclude_garbage_time (bool, optional): Optional argument. If you want to filter out plays where the result of the game is largely decided, set exclude_garbage_time = True. Default behavior is that this variable is set to False when this function is called.

start_week (int, semi-optional): Optional argument. If you only want team stats for a range of weeks, set start_week and end_week to the range of weeks you want season-level data for.

end_week (int, semi-optional): Optional argument. If you only want team stats for a range of weeks, set start_week and end_week to the range of weeks you want season-level data for.

NOTE: If the following conditions are True, a ValueError() will be raised when calling this function:

  • start_week < 0
  • end_week < 0
  • start_week is not None and end_week is None (will be changed in a future version)
  • start_week is None and end_week is not None (will be changed in a future version)
  • end_week < start_week
  • end_week = start_week

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.stats import get_cfbd_advanced_team_season_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 advanced team season stats for the 2020 CFB season.
    print("Get team season stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_season_stats(
        api_key=cfbd_key,
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get advanced team season stats for the 2020 CFB season,
    # but remove plays that happen in garbage time.
    print(
        "Get advanced team season stats for the 2020 CFB season, " +
        "but remove plays that happen in garbage time."
    )
    json_data = get_cfbd_advanced_team_season_stats(
        api_key=cfbd_key,
        season=2020,
        exclude_garbage_time=True
    )
    print(json_data)
    time.sleep(5)

    # Get advanced team season stats for the 2020 CFB season,
    # but only between weeks 5 and 10.
    print(
        "Get advanced team season stats for the 2020 CFB season, " +
        "but only between weeks 5 and 10."
    )
    json_data = get_cfbd_advanced_team_season_stats(
        api_key=cfbd_key,
        season=2020,
        start_week=5,
        end_week=10
    )
    print(json_data)
    time.sleep(5)

    # Get advanced team season stats for just
    # the Ohio State Buckeyes Football Team.
    print(
        "Get advanced team season stats for just" +
        " the Ohio State Buckeyes Football Team."
    )
    json_data = get_cfbd_advanced_team_season_stats(
        api_key=cfbd_key,
        team="Ohio State"
    )
    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_advanced_team_season_stats(
        api_key=cfbd_key,
        season=2020,
        team="Cincinnati",
        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 advanced team season stats for the 2020 CFB season.
    print("Get team season stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_season_stats(
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get advanced team season stats for the 2020 CFB season,
    # but remove plays that happen in garbage time.
    print(
        "Get advanced team season stats for the 2020 CFB season, " +
        "but remove plays that happen in garbage time."
    )
    json_data = get_cfbd_advanced_team_season_stats(
        season=2020,
        exclude_garbage_time=True
    )
    print(json_data)
    time.sleep(5)

    # Get advanced team season stats for the 2020 CFB season,
    # but only between weeks 5 and 10.
    print(
        "Get advanced team season stats for the 2020 CFB season, " +
        "but only between weeks 5 and 10."
    )
    json_data = get_cfbd_advanced_team_season_stats(
        season=2020,
        start_week=5,
        end_week=10
    )
    print(json_data)
    time.sleep(5)

    # Get advanced team season stats for the just
    # the Ohio State Buckeyes Football Team.
    print(
        "Get advanced team season stats for the just " +
        "the Ohio State Buckeyes Football Team."
    )
    json_data = get_cfbd_advanced_team_season_stats(
        team="Ohio State"
    )
    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_advanced_team_season_stats(
        season=2020,
        team="Cincinnati",
        return_as_dict=True
    )
    print(json_data)

Returns

A pandas DataFrame object with advanced team season stats data, or (if return_as_dict is set to True) a dictionary object with a with advanced team season stats data.

def get_cfbd_advanced_team_game_stats( api_key: str = None, api_key_dir: str = None, season: int = None, team: str = None, week: int = None, opponent: str = None, exclude_garbage_time: bool = False, season_type: str = 'both', return_as_dict: bool = False):
1177def get_cfbd_advanced_team_game_stats(
1178    api_key: str = None,
1179    api_key_dir: str = None,
1180    season: int = None,
1181    team: str = None,
1182    # `year` and/or `team` need to be not null for this function to work.
1183    week: int = None,
1184    opponent: str = None,
1185    exclude_garbage_time: bool = False,
1186    season_type: str = "both",  # "regular", "postseason", or "both"
1187    return_as_dict: bool = False,
1188):
1189    """
1190    Allows you to get advanced CFB team game stats data from the CFBD API.
1191
1192    Parameters
1193    ----------
1194
1195    `api_key` (str, optional):
1196        Semi-optional argument.
1197        If `api_key` is null, this function will attempt to load a CFBD API key
1198        from the python environment, or from a file on this computer.
1199        If `api_key` is not null,
1200        this function will automatically assume that the
1201        inputted `api_key` is a valid CFBD API key.
1202
1203    `api_key_dir` (str, optional):
1204        Optional argument.
1205        If `api_key` is set to am empty string, this variable is ignored.
1206        If `api_key_dir` is null, and `api_key` is null,
1207        this function will try to find
1208        a CFBD API key file in this user's home directory.
1209        If `api_key_dir` is set to a string, and `api_key` is null,
1210        this function will assume that `api_key_dir` is a directory,
1211        and will try to find a CFBD API key file in that directory.
1212
1213    `season` (int, semi-mandatory):
1214        Semi-required argument.
1215        Specifies the season you want CFB team game stats data from.
1216        This must be specified, otherwise this package, and by extension
1217        the CFBD API, will not accept the request
1218        to get CFB team season stats data.
1219        This or `team` must be set
1220        to a valid non-null variable for this to function.
1221
1222    `team` (str, semi-mandatory):
1223        Semi-required argument.
1224        Specifies the season you want advanced CFB team game stats data from.
1225        This must be specified, otherwise this package, and by extension
1226        the CFBD API, will not accept
1227        the request to get CFB team season stats data.
1228        This or `season` must be set
1229        to a valid non-null variable for this to function.
1230
1231    `week` (int, optional):
1232        Optional argument.
1233        If `week` is set to an integer, this function will attempt
1234        to load CFB team game from games in that season, and that week.
1235
1236    `opponent` (str, optional):
1237        Optional argument.
1238        If you only want games from a specific opponent,
1239        set `opponent` to the name of that team.
1240
1241
1242    `exclude_garbage_time` (bool, optional):
1243        Optional argument.
1244        If you want to filter out plays where
1245        the result of the game is largely decided,
1246        set `exclude_garbage_time = True`.
1247        Default behavior is that this variable is set to
1248        `False` when this function is called.
1249
1250    `season_type` (str, semi-optional):
1251        Semi-optional argument.
1252        By default, this will be set to "regular", for the CFB regular season.
1253        If you want CFB team game stats, set `season_type` to "postseason".
1254        If `season_type` is set to anything but "regular" or "postseason",
1255        a `ValueError()` will be raised.
1256
1257    `return_as_dict` (bool, semi-optional):
1258        Semi-optional argument.
1259        If you want this function to return
1260        the data as a dictionary (read: JSON object),
1261        instead of a pandas `DataFrame` object,
1262        set `return_as_dict` to `True`.
1263
1264
1265    Usage
1266    ----------
1267    ```
1268    import time
1269
1270    from cfbd_json_py.stats import get_cfbd_advanced_team_game_stats
1271
1272
1273    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
1274
1275    if cfbd_key != "tigersAreAwesome":
1276        print(
1277            "Using the user's API key declared in this script " +
1278            "for this example."
1279        )
1280
1281        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season.
1282        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1283        json_data = get_cfbd_advanced_team_game_stats(
1284            api_key=cfbd_key,
1285            season=2020,
1286            week=10
1287        )
1288        print(json_data)
1289        time.sleep(5)
1290
1291        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season,
1292        # but exclude plays that happen in garbage time.
1293        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1294        json_data = get_cfbd_advanced_team_game_stats(
1295            api_key=cfbd_key,
1296            season=2020,
1297            week=10,
1298            exclude_garbage_time=True
1299        )
1300        print(json_data)
1301        time.sleep(5)
1302
1303        # Get advanced CFBD team game stats for the 2020 CFB season.
1304        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1305        json_data = get_cfbd_advanced_team_game_stats(
1306            api_key=cfbd_key,
1307            season=2020
1308        )
1309        print(json_data)
1310        time.sleep(5)
1311
1312        # Get advanced CFBD team game stats for
1313        # the University of Cincinnati Football Team in the 2020 CFB season.
1314        print(
1315            "Get advanced CFBD team game stats for " +
1316            "the University of Cincinnati Football Team " +
1317            "in the 2020 CFB season."
1318        )
1319        json_data = get_cfbd_advanced_team_game_stats(
1320            api_key=cfbd_key,
1321            season=2020,
1322            opponent="Ohio"
1323        )
1324        print(json_data)
1325        time.sleep(5)
1326
1327        # Get advanced CFBD team game stats for teams that faced off
1328        # against the Ohio Bobcats Football Team in the 2020 CFB season.
1329        print(
1330            "Get advanced CFBD team game stats for teams that " +
1331            "faced off against the Ohio Bobcats Football Team " +
1332            "in the 2020 CFB season."
1333        )
1334        json_data = get_cfbd_advanced_team_game_stats(
1335            api_key=cfbd_key,
1336            season=2020,
1337            opponent="Ohio"
1338        )
1339        print(json_data)
1340        time.sleep(5)
1341
1342        # Get advanced CFBD team game stats for just
1343        # postseason games in the 2020 CFB season.
1344        print(
1345            "Get advanced CFBD team game stats for just postseason games " +
1346            "in the 2020 CFB season."
1347        )
1348        json_data = get_cfbd_advanced_team_game_stats(
1349            api_key=cfbd_key,
1350            season=2020,
1351            week=10
1352        )
1353        print(json_data)
1354        time.sleep(5)
1355
1356
1357        # You can also tell this function to just return the API call as
1358        # a Dictionary (read: JSON) object.
1359        print(
1360            "You can also tell this function to just return the API call " +
1361            "as a Dictionary (read: JSON) object."
1362        )
1363        json_data = get_cfbd_advanced_team_game_stats(
1364            api_key=cfbd_key,
1365            season=2020,
1366            week=10,
1367            return_as_dict=True
1368        )
1369        print(json_data)
1370
1371    else:
1372        # Alternatively, if the CFBD API key exists in this python environment,
1373        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
1374        # you could just call these functions directly,
1375        # without setting the API key in the script.
1376        print(
1377            "Using the user's API key supposedly loaded " +
1378            "into this python environment for this example."
1379        )
1380
1381        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season.
1382        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1383        json_data = get_cfbd_advanced_team_game_stats(
1384            season=2020,
1385            week=10
1386        )
1387        print(json_data)
1388        time.sleep(5)
1389
1390        # Get advanced CFBD team game stats for week 10 of the 2020 CFB season,
1391        # but exclude plays that happen in garbage time.
1392        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1393        json_data = get_cfbd_advanced_team_game_stats(
1394            season=2020,
1395            week=10,
1396            exclude_garbage_time=True
1397        )
1398        print(json_data)
1399        time.sleep(5)
1400
1401        # Get advanced CFBD team game stats for the 2020 CFB season.
1402        print("Get advanced CFBD team game stats for the 2020 CFB season.")
1403        json_data = get_cfbd_advanced_team_game_stats(
1404            season=2020
1405        )
1406        print(json_data)
1407        time.sleep(5)
1408
1409        # Get advanced CFBD team game stats for
1410        # the University of Cincinnati Football Team in the 2020 CFB season.
1411        print(
1412            "Get advanced CFBD team game stats for " +
1413            "the University of Cincinnati Football Team " +
1414            "in the 2020 CFB season."
1415        )
1416        json_data = get_cfbd_advanced_team_game_stats(
1417            season=2020,
1418            opponent="Ohio"
1419        )
1420        print(json_data)
1421        time.sleep(5)
1422
1423        # Get advanced CFBD team game stats for teams that faced off
1424        # against the Ohio Bobcats Football Team in the 2020 CFB season.
1425        print(
1426            "Get advanced CFBD team game stats for teams that " +
1427            "faced off against the Ohio Bobcats Football Team " +
1428            "in the 2020 CFB season."
1429        )
1430        json_data = get_cfbd_advanced_team_game_stats(
1431            season=2020,
1432            opponent="Ohio"
1433        )
1434        print(json_data)
1435        time.sleep(5)
1436
1437        # Get advanced CFBD team game stats for just
1438        # postseason games in the 2020 CFB season.
1439        print(
1440            "Get advanced CFBD team game stats for just postseason games " +
1441            "in the 2020 CFB season."
1442        )
1443        json_data = get_cfbd_advanced_team_game_stats(
1444            season=2020,
1445            week=10
1446        )
1447        print(json_data)
1448        time.sleep(5)
1449
1450
1451        # You can also tell this function to just return the API call as
1452        # a Dictionary (read: JSON) object.
1453        print(
1454            "You can also tell this function to just return the API call " +
1455            "as a Dictionary (read: JSON) object."
1456        )
1457        json_data = get_cfbd_advanced_team_game_stats(
1458            season=2020,
1459            week=10,
1460            return_as_dict=True
1461        )
1462        print(json_data)
1463
1464    ```
1465    Returns
1466    ----------
1467    A pandas `DataFrame` object with advanced team season stats data,
1468    or (if `return_as_dict` is set to `True`)
1469    a dictionary object with a with advanced team season stats data.
1470    """
1471    now = datetime.now()
1472    url = "https://api.collegefootballdata.com/stats/game/advanced"
1473    row_df = pd.DataFrame()
1474    final_df = pd.DataFrame()
1475
1476    if api_key is not None:
1477        real_api_key = api_key
1478        del api_key
1479    else:
1480        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1481
1482    if real_api_key == "tigersAreAwesome":
1483        raise ValueError(
1484            "You actually need to change `cfbd_key` to your CFBD API key."
1485        )
1486    elif "Bearer " in real_api_key:
1487        pass
1488    elif "Bearer" in real_api_key:
1489        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1490    else:
1491        real_api_key = "Bearer " + real_api_key
1492
1493    if season is not None and (season > (now.year + 1)):
1494        raise ValueError(f"`season` cannot be greater than {season}.")
1495    elif season is not None and season < 1869:
1496        raise ValueError("`season` cannot be less than 1869.")
1497
1498    if season_type == "regular" or season_type == "postseason" \
1499            or season_type == "both":
1500        pass
1501    else:
1502        raise ValueError(
1503            '`season_type` must be set to either ' +
1504            '"regular","postseason", or "both".'
1505        )
1506
1507    gt_str = ""
1508
1509    # URL builder
1510    ##########################################################################
1511
1512    if exclude_garbage_time is True:
1513        gt_str = "true"
1514    elif exclude_garbage_time is False:
1515        gt_str = "false"
1516
1517    if season is not None and team is not None:
1518        url += f"?year={season}&team={team}"
1519    elif season is not None:
1520        url += f"?year={season}"
1521    elif team is not None:
1522        url += f"?team={team}"
1523
1524    if exclude_garbage_time is not None:
1525        url += f"&excludeGarbageTime={gt_str}"
1526
1527    if week is not None:
1528        url += f"&week={week}"
1529
1530    if opponent is not None:
1531        url += f"&opponent={opponent}"
1532
1533    headers = {
1534        "Authorization": f"{real_api_key}",
1535        "accept": "application/json"
1536    }
1537
1538    response = requests.get(url, headers=headers)
1539
1540    if response.status_code == 200:
1541        pass
1542    elif response.status_code == 401:
1543        raise ConnectionRefusedError(
1544            "Could not connect. The connection was refused." +
1545            "\nHTTP Status Code 401."
1546        )
1547    else:
1548        raise ConnectionError(
1549            f"Could not connect.\nHTTP Status code {response.status_code}"
1550        )
1551
1552    json_data = response.json()
1553
1554    if return_as_dict is True:
1555        return json_data
1556
1557    for team in tqdm(json_data):
1558        t_game_id = team["gameId"]
1559        t_week = team["week"]
1560        t_team = team["team"]
1561        t_opponent = team["opponent"]
1562
1563        if season is not None:
1564            row_df = pd.DataFrame(
1565                {
1566                    "season": season,
1567                    "game_id": t_game_id,
1568                    "week": t_week,
1569                    "team_name": t_team,
1570                    "opponent_name": t_opponent,
1571                },
1572                index=[0],
1573            )
1574        else:
1575
1576            row_df = pd.DataFrame(
1577                {
1578                    "game_id": t_game_id,
1579                    "week": t_week,
1580                    "team_name": t_team,
1581                    "opponent_name": t_opponent,
1582                },
1583                index=[0],
1584            )
1585
1586        # offense
1587        if "offense" not in team:
1588            logging.debug(
1589                "Key `[offense]` not found for " +
1590                f"Game ID #{t_game_id} and {t_team}, "
1591                + f"which happened in week {t_week}."
1592            )
1593        else:
1594            row_df["offense_plays"] = team["offense"]["plays"]
1595            row_df["offense_drives"] = team["offense"]["drives"]
1596            row_df["offense_ppa"] = team["offense"]["ppa"]
1597            row_df["offense_total_ppa"] = team["offense"]["totalPPA"]
1598            row_df["offense_success_rate"] = team["offense"]["successRate"]
1599            row_df["offense_explosiveness"] = team["offense"]["explosiveness"]
1600            row_df["offense_power_success"] = team["offense"]["powerSuccess"]
1601            row_df["offense_stuff_rate"] = team["offense"]["stuffRate"]
1602            row_df["offense_line_yards_avg"] = team["offense"]["lineYards"]
1603            row_df["offense_line_yards_total"] = team["offense"][
1604                "lineYardsTotal"
1605            ]
1606            row_df["offense_second_level_yards_avg"] = team["offense"][
1607                "secondLevelYards"
1608            ]
1609            row_df["offense_second_level_yards_total"] = team["offense"][
1610                "secondLevelYardsTotal"
1611            ]
1612            row_df["offense_open_field_yards_avg"] = team["offense"][
1613                "openFieldYards"
1614            ]
1615            row_df["offense_open_field_yards_total"] = team["offense"][
1616                "secondLevelYardsTotal"
1617            ]
1618
1619            row_df["offense_standard_downs_ppa"] = team[
1620                "offense"]["standardDowns"]["ppa"]
1621            row_df["offense_standard_downs_success_rate"] = team[
1622                "offense"]["standardDowns"]["successRate"]
1623            row_df["offense_standard_downs_explosiveness"] = team["offense"][
1624                "standardDowns"
1625            ]["explosiveness"]
1626
1627            row_df["offense_passing_downs_ppa"] = team[
1628                "offense"]["passingDowns"]["ppa"]
1629            row_df["offense_passing_downs_success_rate"] = team[
1630                "offense"]["passingDowns"]["successRate"]
1631            row_df["offense_passing_downs_explosiveness"] = team["offense"][
1632                "passingDowns"
1633            ]["explosiveness"]
1634
1635            row_df["offense_rushing_plays_ppa"] = team[
1636                "offense"]["rushingPlays"]["ppa"]
1637            row_df["offense_rushing_plays_total_ppa"] = team[
1638                "offense"]["rushingPlays"]["totalPPA"]
1639            row_df["offense_rushing_plays_success_rate"] = team[
1640                "offense"]["rushingPlays"]["successRate"]
1641            row_df["offense_rushing_plays_explosiveness"] = team[
1642                "offense"]["rushingPlays"]["explosiveness"]
1643
1644            row_df["offense_passing_plays_ppa"] = team[
1645                "offense"]["passingPlays"]["ppa"]
1646            row_df["offense_passing_plays_total_ppa"] = team[
1647                "offense"]["passingPlays"]["totalPPA"]
1648            row_df["offense_passing_plays_success_rate"] = team[
1649                "offense"]["passingPlays"]["successRate"]
1650            row_df["offense_passing_plays_explosiveness"] = team[
1651                "offense"]["rushingPlays"]["explosiveness"]
1652
1653        # defense
1654        if "defense" not in team:
1655            logging.debug(
1656                "Key `[defense]` not found for " +
1657                f"Game ID #{t_game_id} and {t_team}, "
1658                + f"which happened in week {t_week}."
1659            )
1660        else:
1661            row_df["defense_plays"] = team["defense"]["plays"]
1662            row_df["defense_drives"] = team["defense"]["drives"]
1663            row_df["defense_ppa"] = team["defense"]["ppa"]
1664            row_df["defense_total_ppa"] = team["defense"]["totalPPA"]
1665            row_df["defense_success_rate"] = team["defense"]["successRate"]
1666            row_df["defense_explosiveness"] = team["defense"]["explosiveness"]
1667            row_df["defense_power_success"] = team["defense"]["powerSuccess"]
1668            row_df["defense_stuff_rate"] = team["defense"]["stuffRate"]
1669            row_df["defense_line_yards_avg"] = team["defense"]["lineYards"]
1670            row_df["defense_line_yards_total"] = team["defense"][
1671                "lineYardsTotal"
1672            ]
1673            row_df["defense_second_level_yards_avg"] = team["defense"][
1674                "secondLevelYards"
1675            ]
1676            row_df["defense_second_level_yards_total"] = team["defense"][
1677                "secondLevelYardsTotal"
1678            ]
1679            row_df["defense_open_field_yards_avg"] = team["defense"][
1680                "openFieldYards"
1681            ]
1682            row_df["defense_open_field_yards_total"] = team["defense"][
1683                "secondLevelYardsTotal"
1684            ]
1685            row_df["defense_total_opportunities"] = team["defense"][
1686                "totalOpportunies"
1687            ]
1688            row_df["defense_points_per_opportunity"] = team["defense"][
1689                "pointsPerOpportunity"
1690            ]
1691
1692            row_df["defense_standard_downs_ppa"] = team[
1693                "defense"]["standardDowns"]["ppa"]
1694            row_df["defense_standard_downs_success_rate"] = team["defense"][
1695                "standardDowns"
1696            ]["successRate"]
1697            row_df["defense_standard_downs_explosiveness"] = team["defense"][
1698                "standardDowns"
1699            ]["explosiveness"]
1700
1701            row_df["defense_passing_downs_ppa"] = team[
1702                "defense"]["passingDowns"]["ppa"]
1703            row_df["defense_passing_downs_success_rate"] = team["defense"][
1704                "passingDowns"
1705            ]["successRate"]
1706            row_df["defense_passing_downs_explosiveness"] = team["defense"][
1707                "passingDowns"
1708            ]["explosiveness"]
1709
1710            row_df["defense_rushing_plays_ppa"] = team[
1711                "defense"]["rushingPlays"]["ppa"]
1712            row_df["defense_rushing_plays_total_ppa"] = team[
1713                "defense"]["rushingPlays"]["totalPPA"]
1714            row_df["defense_rushing_plays_success_rate"] = team["defense"][
1715                "rushingPlays"
1716            ]["successRate"]
1717            row_df["defense_rushing_plays_explosiveness"] = team["defense"][
1718                "rushingPlays"
1719            ]["explosiveness"]
1720
1721            row_df["defense_passing_plays_ppa"] = team[
1722                "defense"]["passingPlays"]["ppa"]
1723            row_df["defense_passing_plays_total_ppa"] = team[
1724                "defense"]["passingPlays"]["totalPPA"]
1725            row_df["defense_passing_plays_success_rate"] = team["defense"][
1726                "passingPlays"
1727            ]["successRate"]
1728            row_df["defense_passing_plays_explosiveness"] = team["defense"][
1729                "rushingPlays"
1730            ]["explosiveness"]
1731
1732        final_df = pd.concat([final_df, row_df], ignore_index=True)
1733        del row_df
1734        del t_game_id, t_week, t_team, t_opponent
1735
1736    return final_df

Allows you to get advanced CFB team game stats data 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.

season (int, semi-mandatory): Semi-required argument. Specifies the season you want CFB team game stats data from. This must be specified, otherwise this package, and by extension the CFBD API, will not accept the request to get CFB team season stats data. This or team must be set to a valid non-null variable for this to function.

team (str, semi-mandatory): Semi-required argument. Specifies the season you want advanced CFB team game stats data from. This must be specified, otherwise this package, and by extension the CFBD API, will not accept the request to get CFB team season stats data. This or season must be set to a valid non-null variable for this to function.

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

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

exclude_garbage_time (bool, optional): Optional argument. If you want to filter out plays where the result of the game is largely decided, set exclude_garbage_time = True. Default behavior is that this variable is set to False when this function is called.

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 team game stats, set season_type to "postseason". If season_type is set to anything but "regular" or "postseason", a ValueError() will be raised.

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

Usage

import time

from cfbd_json_py.stats import get_cfbd_advanced_team_game_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 advanced CFBD team game stats for week 10 of the 2020 CFB season.
    print("Get advanced CFBD team game stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_game_stats(
        api_key=cfbd_key,
        season=2020,
        week=10
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for week 10 of the 2020 CFB season,
    # but exclude plays that happen in garbage time.
    print("Get advanced CFBD team game stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_game_stats(
        api_key=cfbd_key,
        season=2020,
        week=10,
        exclude_garbage_time=True
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for the 2020 CFB season.
    print("Get advanced CFBD team game stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_game_stats(
        api_key=cfbd_key,
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for
    # the University of Cincinnati Football Team in the 2020 CFB season.
    print(
        "Get advanced CFBD team game stats for " +
        "the University of Cincinnati Football Team " +
        "in the 2020 CFB season."
    )
    json_data = get_cfbd_advanced_team_game_stats(
        api_key=cfbd_key,
        season=2020,
        opponent="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for teams that faced off
    # against the Ohio Bobcats Football Team in the 2020 CFB season.
    print(
        "Get advanced CFBD team game stats for teams that " +
        "faced off against the Ohio Bobcats Football Team " +
        "in the 2020 CFB season."
    )
    json_data = get_cfbd_advanced_team_game_stats(
        api_key=cfbd_key,
        season=2020,
        opponent="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for just
    # postseason games in the 2020 CFB season.
    print(
        "Get advanced CFBD team game stats for just postseason games " +
        "in the 2020 CFB season."
    )
    json_data = get_cfbd_advanced_team_game_stats(
        api_key=cfbd_key,
        season=2020,
        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_advanced_team_game_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 advanced CFBD team game stats for week 10 of the 2020 CFB season.
    print("Get advanced CFBD team game stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_game_stats(
        season=2020,
        week=10
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for week 10 of the 2020 CFB season,
    # but exclude plays that happen in garbage time.
    print("Get advanced CFBD team game stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_game_stats(
        season=2020,
        week=10,
        exclude_garbage_time=True
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for the 2020 CFB season.
    print("Get advanced CFBD team game stats for the 2020 CFB season.")
    json_data = get_cfbd_advanced_team_game_stats(
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for
    # the University of Cincinnati Football Team in the 2020 CFB season.
    print(
        "Get advanced CFBD team game stats for " +
        "the University of Cincinnati Football Team " +
        "in the 2020 CFB season."
    )
    json_data = get_cfbd_advanced_team_game_stats(
        season=2020,
        opponent="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for teams that faced off
    # against the Ohio Bobcats Football Team in the 2020 CFB season.
    print(
        "Get advanced CFBD team game stats for teams that " +
        "faced off against the Ohio Bobcats Football Team " +
        "in the 2020 CFB season."
    )
    json_data = get_cfbd_advanced_team_game_stats(
        season=2020,
        opponent="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get advanced CFBD team game stats for just
    # postseason games in the 2020 CFB season.
    print(
        "Get advanced CFBD team game stats for just postseason games " +
        "in the 2020 CFB season."
    )
    json_data = get_cfbd_advanced_team_game_stats(
        season=2020,
        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_advanced_team_game_stats(
        season=2020,
        week=10,
        return_as_dict=True
    )
    print(json_data)

Returns

A pandas DataFrame object with advanced team season stats data, or (if return_as_dict is set to True) a dictionary object with a with advanced team season stats data.

def get_cfbd_team_stat_categories( api_key: str = None, api_key_dir: str = None, return_as_dict: bool = False):
1739def get_cfbd_team_stat_categories(
1740    api_key: str = None, api_key_dir: str = None, return_as_dict: bool = False
1741):
1742    """
1743    Returns a list of stat categories
1744    for team stats directly from the CFBD API.
1745
1746    Parameters
1747    ----------
1748
1749    `api_key` (str, optional):
1750        Semi-optional argument.
1751        If `api_key` is null, this function will attempt to load a CFBD API key
1752        from the python environment, or from a file on this computer.
1753        If `api_key` is not null,
1754        this function will automatically assume that the
1755        inputted `api_key` is a valid CFBD API key.
1756
1757    `api_key_dir` (str, optional):
1758        Optional argument.
1759        If `api_key` is set to am empty string, this variable is ignored.
1760        If `api_key_dir` is null, and `api_key` is null,
1761        this function will try to find
1762        a CFBD API key file in this user's home directory.
1763        If `api_key_dir` is set to a string, and `api_key` is null,
1764        this function will assume that `api_key_dir` is a directory,
1765        and will try to find a CFBD API key file in that directory.
1766
1767    `return_as_dict` (bool, semi-optional):
1768        Semi-optional argument.
1769        If you want this function to return the data
1770        as a dictionary (read: JSON object),
1771        instead of a pandas `DataFrame` object,
1772        set `return_as_dict` to `True`.
1773
1774    Usage
1775    ----------
1776    ```
1777    import time
1778
1779    from cfbd_json_py.stats import get_cfbd_team_stat_categories
1780
1781
1782    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
1783
1784    if cfbd_key != "tigersAreAwesome":
1785        print(
1786            "Using the user's API key declared in this script " +
1787            "for this example."
1788        )
1789
1790        # Get a list of CFBD stat categories for team stats.
1791        print("Get a list of CFBD stat categories for team stats.")
1792        json_data = get_cfbd_team_stat_categories(
1793            api_key=cfbd_key
1794        )
1795        print(json_data)
1796        time.sleep(5)
1797
1798        # You can also tell this function to just return the API call as
1799        # a Dictionary (read: JSON) object.
1800        print(
1801            "You can also tell this function to just return the API call " +
1802            "as a Dictionary (read: JSON) object."
1803        )
1804        json_data = get_cfbd_team_stat_categories(
1805            api_key=cfbd_key,
1806            return_as_dict=True
1807        )
1808        print(json_data)
1809
1810    else:
1811        # Alternatively, if the CFBD API key exists in this python environment,
1812        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
1813        # you could just call these functions directly,
1814        # without setting the API key in the script.
1815        print(
1816            "Using the user's API key supposedly loaded " +
1817            "into this python environment for this example."
1818        )
1819
1820        # Get a list of CFBD stat categories for team stats.
1821        print("Get a list of CFBD stat categories for team stats.")
1822        json_data = get_cfbd_team_stat_categories()
1823        print(json_data)
1824        time.sleep(5)
1825
1826        # You can also tell this function to just return the API call as
1827        # a Dictionary (read: JSON) object.
1828        print(
1829            "You can also tell this function to just return the API call " +
1830            "as a Dictionary (read: JSON) object."
1831        )
1832        json_data = get_cfbd_team_stat_categories(
1833            return_as_dict=True
1834        )
1835        print(json_data)
1836
1837    ```
1838    Returns
1839    ----------
1840    A pandas `DataFrame` object with CFBD stat categories,
1841    or (if `return_as_dict` is set to `True`)
1842    a dictionary object with CFBD stat categories.
1843
1844    """
1845    url = "https://api.collegefootballdata.com/stats/categories"
1846
1847    if api_key is not None:
1848        real_api_key = api_key
1849        del api_key
1850    else:
1851        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1852
1853    if real_api_key == "tigersAreAwesome":
1854        raise ValueError(
1855            "You actually need to change `cfbd_key` to your CFBD API key."
1856        )
1857    elif "Bearer " in real_api_key:
1858        pass
1859    elif "Bearer" in real_api_key:
1860        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1861    else:
1862        real_api_key = "Bearer " + real_api_key
1863
1864    headers = {
1865        "Authorization": f"{real_api_key}",
1866        "accept": "application/json"
1867    }
1868
1869    response = requests.get(url, headers=headers)
1870
1871    if response.status_code == 200:
1872        pass
1873    elif response.status_code == 401:
1874        raise ConnectionRefusedError(
1875            "Could not connect. The connection was refused." +
1876            "\nHTTP Status Code 401."
1877        )
1878    else:
1879        raise ConnectionError(
1880            f"Could not connect.\nHTTP Status code {response.status_code}"
1881        )
1882
1883    json_data = response.json()
1884
1885    if return_as_dict is True:
1886        return json_data
1887
1888    return pd.DataFrame(json_data, columns=["stat_category"])

Returns a list of stat categories for team stats directly 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

import time

from cfbd_json_py.stats import get_cfbd_team_stat_categories


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 a list of CFBD stat categories for team stats.
    print("Get a list of CFBD stat categories for team stats.")
    json_data = get_cfbd_team_stat_categories(
        api_key=cfbd_key
    )
    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_team_stat_categories(
        api_key=cfbd_key,
        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 a list of CFBD stat categories for team stats.
    print("Get a list of CFBD stat categories for team stats.")
    json_data = get_cfbd_team_stat_categories()
    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_team_stat_categories(
        return_as_dict=True
    )
    print(json_data)

Returns

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