cfbd_json_py.players

   1# Creation Date: 08/30/2023 01:13 EDT
   2# Last Updated Date: 09/16/2024 06:10 PM EDT
   3# Author: Joseph Armstrong (armstrongjoseph08@gmail.com)
   4# File Name: players.py
   5# Purpose: Houses functions pertaining to CFB player data within the CFBD API.
   6###############################################################################
   7
   8# import logging
   9from datetime import datetime
  10
  11import pandas as pd
  12import requests
  13# from tqdm import tqdm
  14
  15# from cfbd_json_py.games import get_cfbd_player_game_stats
  16from cfbd_json_py.utls import get_cfbd_api_token
  17
  18
  19def cfbd_player_search(
  20    search_str: str,
  21    api_key: str = None,
  22    api_key_dir: str = None,
  23    position: str = None,
  24    team: str = None,
  25    season: int = None,
  26    return_as_dict: bool = False,
  27):
  28    """
  29    Given a string, search for players who's
  30    name matches that string in some capacity.
  31
  32    Parameters
  33    ----------
  34    `search_str` (int, mandatory):
  35        Mandatory argument.
  36        This is the name of the player you are trying to find.
  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    `position` (bool, semi-optional):
  57        Semi-optional argument.
  58        If you only want players from a specific position,
  59        set `position` to the position you want to find players from.
  60
  61    `team` (bool, semi-optional):
  62        Semi-optional argument.
  63        If you only want players from a specific team,
  64        set `team` to the name of the team you want to find players from.
  65
  66    `season` (bool, semi-optional):
  67        Semi-optional argument.
  68        If you only want players from a specific CFB season,
  69        set `season` to the season you want to find players from.
  70
  71    `return_as_dict` (bool, semi-optional):
  72        Semi-optional argument.
  73        If you want this function to return
  74        the data as a dictionary (read: JSON object),
  75        instead of a pandas `DataFrame` object,
  76        set `return_as_dict` to `True`.
  77
  78    Usage
  79    ----------
  80    ```
  81    import time
  82
  83    from cfbd_json_py.players import cfbd_player_search
  84
  85
  86    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
  87
  88    if cfbd_key != "tigersAreAwesome":
  89        print(
  90            "Using the user's API key declared in this script " +
  91            "for this example."
  92        )
  93
  94        # Get a list of every known "Joe" in the CFBD API.
  95        print("Get a list of every known \"Joe\" in the CFBD API.")
  96        json_data = cfbd_player_search(
  97            api_key=cfbd_key,
  98            search_str="Joe"
  99        )
 100        print(json_data)
 101        time.sleep(5)
 102
 103        # Get a list of every known "Joe" in the CFBD API,
 104        # who's last name starts with "B".
 105        print(
 106            "Get a list of every known \"Joe\" in the CFBD API, " +
 107            "who's last name starts with \"B\"."
 108        )
 109        json_data = cfbd_player_search(
 110            api_key=cfbd_key,
 111            search_str="Joe B"
 112        )
 113        print(json_data)
 114        time.sleep(5)
 115
 116        # Get a list of every known "Jim" in the CFBD API,
 117        # who happened to play with the University of Cincinnati Football Team
 118        # at some point in their career.
 119        print(
 120            "Get a list of every known \"Jim\" in the CFBD API, " +
 121            "who happened to play with the University of Cincinnati Football" +
 122            " Team at some point in their career."
 123        )
 124        json_data = cfbd_player_search(
 125            api_key=cfbd_key,
 126            search_str="Jim",
 127            position="QB"
 128        )
 129        print(json_data)
 130        time.sleep(5)
 131
 132
 133        # Get a list of every known player of
 134        # the University of Cincinnati Football Team,
 135        # that had the letter "A" in their name.
 136        print(
 137            "Get a list of every known player of " +
 138            "the University of Cincinnati Football Team, " +
 139            "that had the letter \"A\" in their name."
 140        )
 141        json_data = cfbd_player_search(
 142            api_key=cfbd_key,
 143            search_str="A",
 144            team="Cincinnati"
 145        )
 146        print(json_data)
 147        time.sleep(5)
 148
 149
 150        # Get a list of every known "Jim" in the CFBD API,
 151        # who happened to play QB at some point in their career.
 152        print(
 153            "Get a list of every known \"Jim\" in the CFBD API," +
 154            " who happened to play QB at some point in their career."
 155        )
 156        json_data = cfbd_player_search(
 157            api_key=cfbd_key,
 158            search_str="Jim",
 159            position="QB"
 160        )
 161        print(json_data)
 162        time.sleep(5)
 163
 164        # Get a list of every known "Joe" in the CFBD API,
 165        # who happened to play in the 2020 CFB season.
 166        print(
 167            "Get a list of every known \"Joe\" in the CFBD API," +
 168            " who happened to play in the 2020 CFB season."
 169        )
 170        json_data = cfbd_player_search(
 171            api_key=cfbd_key,
 172            search_str="Joe",
 173            season=2020
 174        )
 175        print(json_data)
 176        time.sleep(5)
 177
 178
 179        # You can also tell this function to just return the API call as
 180        # a Dictionary (read: JSON) object.
 181        print(
 182            "You can also tell this function to just return the API call " +
 183            "as a Dictionary (read: JSON) object."
 184        )
 185        json_data = cfbd_player_search(
 186            api_key=cfbd_key,
 187            search_str="Justin F",
 188            season=2020,
 189            return_as_dict=True
 190        )
 191        print(json_data)
 192
 193    else:
 194        # Alternatively, if the CFBD API key exists in this python environment,
 195        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 196        # you could just call these functions directly,
 197        # without setting the API key in the script.
 198        print(
 199            "Using the user's API key supposedly loaded " +
 200            "into this python environment for this example."
 201        )
 202
 203        # Get a list of every known "Joe" in the CFBD API.
 204        print("Get a list of every known \"Joe\" in the CFBD API.")
 205        json_data = cfbd_player_search(
 206            search_str="Joe"
 207        )
 208        print(json_data)
 209        time.sleep(5)
 210
 211        # Get a list of every known "Joe" in the CFBD API,
 212        # who's last name starts with "B".
 213        print(
 214            "Get a list of every known \"Joe\" in the CFBD API, " +
 215            "who's last name starts with \"B\"."
 216        )
 217        json_data = cfbd_player_search(
 218            search_str="Joe B"
 219        )
 220        print(json_data)
 221        time.sleep(5)
 222
 223        # Get a list of every known "Jim" in the CFBD API,
 224        # who happened to play with the University of Cincinnati Football Team
 225        # at some point in their career.
 226        print(
 227            "Get a list of every known \"Jim\" in the CFBD API, " +
 228            "who happened to play with the University of Cincinnati " +
 229            "Football Team at some point in their career."
 230        )
 231        json_data = cfbd_player_search(
 232            search_str="Jim",
 233            position="QB"
 234        )
 235        print(json_data)
 236        time.sleep(5)
 237
 238
 239        # Get a list of every known player of
 240        # the University of Cincinnati Football Team,
 241        # that had the letter "A" in their name.
 242        print(
 243            "Get a list of every known player of " +
 244            "the University of Cincinnati Football Team, " +
 245            "that had the letter \"A\" in their name."
 246        )
 247        json_data = cfbd_player_search(
 248            search_str="A",
 249            team="Cincinnati"
 250        )
 251        print(json_data)
 252        time.sleep(5)
 253
 254
 255        # Get a list of every known "Jim" in the CFBD API,
 256        # who happened to play QB at some point in their career.
 257        print(
 258            "Get a list of every known \"Jim\" in the CFBD API, " +
 259            "who happened to play QB at some point in their career."
 260        )
 261        json_data = cfbd_player_search(
 262            search_str="Jim",
 263            position="QB"
 264        )
 265        print(json_data)
 266        time.sleep(5)
 267
 268        # Get a list of every known "Joe" in the CFBD API,
 269        # who happened to play in the 2020 CFB season.
 270        print(
 271            "Get a list of every known \"Joe\" in the CFBD API, " +
 272            "who happened to play in the 2020 CFB season."
 273        )
 274        json_data = cfbd_player_search(
 275            search_str="Joe",
 276            season=2020
 277        )
 278        print(json_data)
 279        time.sleep(5)
 280
 281
 282        # You can also tell this function to just return the API call as
 283        # a Dictionary (read: JSON) object.
 284        print(
 285            "You can also tell this function to just return the API call " +
 286            "as a Dictionary (read: JSON) object."
 287        )
 288        json_data = cfbd_player_search(
 289            search_str="Justin F",
 290            season=2020,
 291            return_as_dict=True
 292        )
 293        print(json_data)
 294
 295    ```
 296    Returns
 297    ----------
 298    A pandas `DataFrame` object with
 299    a list of players who matched the search string,
 300    or (if `return_as_dict` is set to `True`)
 301    a dictionary object with a list of players who matched the search string.
 302
 303    """
 304    now = datetime.now()
 305    players_df = pd.DataFrame()
 306    # row_df = pd.DataFrame()
 307    url = "https://api.collegefootballdata.com/player/search"
 308
 309    ##########################################################################
 310
 311    if api_key is not None:
 312        real_api_key = api_key
 313        del api_key
 314    else:
 315        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
 316
 317    if real_api_key == "tigersAreAwesome":
 318        raise ValueError(
 319            "You actually need to change `cfbd_key` to your CFBD API key."
 320        )
 321    elif "Bearer " in real_api_key:
 322        pass
 323    elif "Bearer" in real_api_key:
 324        real_api_key = real_api_key.replace("Bearer", "Bearer ")
 325    else:
 326        real_api_key = "Bearer " + real_api_key
 327
 328    if season is None:
 329        # Rare, but in this endpoint,
 330        # you don't need to input the season.
 331        pass
 332    elif season > (now.year + 1):
 333        raise ValueError(f"`season` cannot be greater than {season}.")
 334    elif season < 1869:
 335        raise ValueError("`season` cannot be less than 1869.")
 336
 337    # URL builder
 338    ##########################################################################
 339
 340    # Required by API
 341    url += f"?searchTerm={search_str}"
 342
 343    url = url.replace(" ", "%20")  # For sanity reasons with URLs.
 344
 345    if position is not None:
 346        url += f"&position={position}"
 347
 348    if team is not None:
 349        url += f"&team={team}"
 350
 351    if season is not None:
 352        url += f"&year={season}"
 353
 354    headers = {
 355        "Authorization": f"{real_api_key}",
 356        "accept": "application/json"
 357    }
 358
 359    response = requests.get(url, headers=headers)
 360
 361    if response.status_code == 200:
 362        pass
 363    elif response.status_code == 401:
 364        raise ConnectionRefusedError(
 365            "Could not connect. The connection was refused." +
 366            "\nHTTP Status Code 401."
 367        )
 368    else:
 369        raise ConnectionError(
 370            f"Could not connect.\nHTTP Status code {response.status_code}"
 371        )
 372
 373    json_data = response.json()
 374
 375    if return_as_dict is True:
 376        return json_data
 377
 378    players_df = pd.json_normalize(json_data)
 379    players_df.rename(
 380        columns={
 381            "id": "player_id",
 382            "team": "team_name",
 383            "name": "player_name",
 384            "firstName": "first_name",
 385            "lastName": "last_name",
 386            "weight": "weight_lbs",
 387            "height": "height_in",
 388            "jersey": "jersey_num",
 389            "position": "position_abv",
 390            "teamColor": "team_color",
 391            "teamColorSecondary": "team_secondary_color",
 392        },
 393        inplace=True,
 394    )
 395    return players_df
 396
 397
 398def get_cfbd_player_usage(
 399    season: int,
 400    api_key: str = None,
 401    api_key_dir: str = None,
 402    team: str = None,
 403    conference: str = None,
 404    position: str = None,
 405    player_id: int = None,
 406    exclude_garbage_time: bool = False,
 407    return_as_dict: bool = False,
 408):
 409    """
 410    Get player usage data
 411    (A.K.A., the percentages for how often a player touched the ball),
 412    for a given season, at the season level, from the CFBD API.
 413
 414    Parameters
 415    ----------
 416    `season` (int, optional):
 417        Mandatory argument.
 418        Specifies the season you want player usage data from.
 419        You MUST set `season` or `team` to a non-null value for
 420        this function to work. If you don't, a `ValueError()`
 421        will be raised.
 422
 423    `api_key` (str, optional):
 424        Semi-optional argument.
 425        If `api_key` is null, this function will attempt to load a CFBD API key
 426        from the python environment, or from a file on this computer.
 427        If `api_key` is not null,
 428        this function will automatically assume that the
 429        inputted `api_key` is a valid CFBD API key.
 430
 431    `api_key_dir` (str, optional):
 432        Optional argument.
 433        If `api_key` is set to am empty string, this variable is ignored.
 434        If `api_key_dir` is null, and `api_key` is null,
 435        this function will try to find
 436        a CFBD API key file in this user's home directory.
 437        If `api_key_dir` is set to a string, and `api_key` is null,
 438        this function will assume that `api_key_dir` is a directory,
 439        and will try to find a CFBD API key file in that directory.
 440
 441    `team` (str, optional):
 442        Semi-optional argument.
 443        If you only want player usage data for a specific team,
 444        set `team` to the name of the team you want player usage data from.
 445        You MUST set `season` or `team` to a non-null value for
 446        this function to work. If you don't, a `ValueError()`
 447        will be raised.
 448
 449    `position` (str, optional):
 450        Semi-Optional argument.
 451        If you only want player usage data
 452        for players who played a specific position,
 453        set `position` to that position's abbreviation.
 454        A list of CFBD API positions can be found
 455        in the `position_abbreviation` column from
 456        the pandas DataFrame that is returned
 457        by calling `cfbd_json_py.draft.get_cfbd_nfl_positions()`.
 458
 459    `conference` (str, optional):
 460        Optional argument.
 461        If you only want player usage data from games
 462        involving teams from a specific conference,
 463        set `conference` to the abbreviation
 464        of the conference you want player usage data from.
 465        For a list of conferences,
 466        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 467        function.
 468
 469    `player_id` (int, optional):
 470        Optional argument.
 471        If you only want player usage data for a specific player ID,
 472        set this variable to the player ID
 473        of the player you want player usage data from.
 474
 475    `exclude_garbage_time` (bool, optional):
 476        Optional argument.
 477        If you want to filter out plays
 478        where the result of the game is largely decided,
 479        set `exclude_garbage_time = True`.
 480        Default behavior is that this variable is set to
 481        `False` when this function is called.
 482
 483    `return_as_dict` (bool, semi-optional):
 484        Semi-optional argument.
 485        If you want this function to return
 486        the data as a dictionary (read: JSON object),
 487        instead of a pandas `DataFrame` object,
 488        set `return_as_dict` to `True`.
 489
 490    Usage
 491    ----------
 492    ```
 493    import time
 494
 495    from cfbd_json_py.players import get_cfbd_player_usage
 496
 497
 498    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 499
 500    if cfbd_key != "tigersAreAwesome":
 501        print(
 502            "Using the user's API key declared in this script " +
 503            "for this example."
 504        )
 505
 506        # Get player usage data from the 2020 CFB season.
 507        print("Get player usage data from the 2020 CFB season.")
 508        json_data = get_cfbd_player_usage(
 509            api_key=cfbd_key,
 510            season=2020
 511        )
 512        print(json_data)
 513        time.sleep(5)
 514
 515        # Get player usage data for the
 516        # University of Cincinnati Bearcats Football Team,
 517        # during the 2020 CFB season.
 518        print(
 519            "Get player usage data for " +
 520            "the University of Cincinnati Bearcats Football Team, " +
 521            "during the 2020 CFB season."
 522        )
 523        json_data = get_cfbd_player_usage(
 524            api_key=cfbd_key,
 525            season=2020,
 526            team="Cincinnati"
 527        )
 528        print(json_data)
 529        time.sleep(5)
 530
 531        # Get player usage data from players who
 532        # primarily played running back (RB) in the 2020 CFB season.
 533        print(
 534            "Get player usage data from players " +
 535            "who primarily played running back (RB) in the 2020 CFB season."
 536        )
 537        json_data = get_cfbd_player_usage(
 538            api_key=cfbd_key,
 539            season=2020,
 540            position="RB"
 541        )
 542        print(json_data)
 543        time.sleep(5)
 544
 545        # Get player usage data from players who played on
 546        # Big 10 conference (B1G) teams during the 2020 CFB Season.
 547        print(
 548            "Get player usage data from players who played " +
 549            "on Big 10 conference (B1G) teams during the 2020 CFB Season."
 550        )
 551        json_data = get_cfbd_player_usage(
 552            api_key=cfbd_key,
 553            season=2020,
 554            conference="B1G"
 555        )
 556        print(json_data)
 557        time.sleep(5)
 558
 559        # Get player usage data from
 560        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
 561        # during the 2019 CFB season.
 562        print(
 563            "Get player usage data " +
 564            "from former LSU Tigers quarterback Joe Burrow " +
 565            "(player ID #3915511), during the 2019 CFB season."
 566        )
 567        json_data = get_cfbd_player_usage(
 568            api_key=cfbd_key,
 569            season=2019,
 570            player_id=3915511
 571        )
 572        print(json_data)
 573        time.sleep(5)
 574
 575        # Get player usage data from
 576        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
 577        # during the 2019 CFB season,
 578        # but filter out plays that occurred in garbage time.
 579        print(
 580            "Get player usage data from " +
 581            "former LSU Tigers quarterback Joe Burrow " +
 582            "(player ID #3915511), during the 2019 CFB season."
 583        )
 584        json_data = get_cfbd_player_usage(
 585            api_key=cfbd_key,
 586            season=2019,
 587            player_id=3915511,
 588            exclude_garbage_time=True
 589        )
 590        print(json_data)
 591        time.sleep(5)
 592
 593        # You can also tell this function to just return the API call as
 594        # a Dictionary (read: JSON) object.
 595        print(
 596            "You can also tell this function to just return the API call " +
 597            "as a Dictionary (read: JSON) object."
 598        )
 599        json_data = get_cfbd_player_usage(
 600            api_key=cfbd_key,
 601            season=2020,
 602            team="LSU",
 603            return_as_dict=True
 604        )
 605        print(json_data)
 606
 607    else:
 608        # Alternatively, if the CFBD API key exists in this python environment,
 609        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 610        # you could just call these functions directly,
 611        # without setting the API key in the script.
 612        print(
 613            "Using the user's API key supposedly loaded " +
 614            "into this python environment for this example."
 615        )
 616
 617        # Get player usage data from the 2020 CFB season.
 618        print("Get player usage data from the 2020 CFB season.")
 619        json_data = get_cfbd_player_usage(
 620            season=2020
 621        )
 622        print(json_data)
 623        time.sleep(5)
 624
 625        # Get player usage data for the
 626        # University of Cincinnati Bearcats Football Team,
 627        # during the 2020 CFB season.
 628        print(
 629            "Get player usage data for " +
 630            "the University of Cincinnati Bearcats Football Team, " +
 631            "during the 2020 CFB season."
 632        )
 633        json_data = get_cfbd_player_usage(
 634            season=2020,
 635            team="Cincinnati"
 636        )
 637        print(json_data)
 638        time.sleep(5)
 639
 640        # Get player usage data from players who
 641        # primarily played running back (RB) in the 2020 CFB season.
 642        print(
 643            "Get player usage data from players " +
 644            "who primarily played running back (RB) in the 2020 CFB season."
 645        )
 646        json_data = get_cfbd_player_usage(
 647            season=2020,
 648            position="RB"
 649        )
 650        print(json_data)
 651        time.sleep(5)
 652
 653        # Get player usage data from players who played on
 654        # Big 10 conference (B1G) teams during the 2020 CFB Season.
 655        print(
 656            "Get player usage data from players " +
 657            "who played on Big 10 conference (B1G) teams " +
 658            "during the 2020 CFB Season."
 659        )
 660        json_data = get_cfbd_player_usage(
 661            season=2020,
 662            conference="B1G"
 663        )
 664        print(json_data)
 665        time.sleep(5)
 666
 667        # Get player usage data from
 668        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
 669        # during the 2019 CFB season.
 670        print(
 671            "Get player usage data from " +
 672            "former LSU Tigers quarterback Joe Burrow " +
 673            "(player ID #3915511), during the 2019 CFB season."
 674        )
 675        json_data = get_cfbd_player_usage(
 676            season=2019,
 677            player_id=3915511
 678        )
 679        print(json_data)
 680        time.sleep(5)
 681
 682        # Get player usage data from
 683        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
 684        # during the 2019 CFB season,
 685        # but filter out plays that occurred in garbage time.
 686        print(
 687            "Get player usage data from " +
 688            "former LSU Tigers quarterback Joe Burrow " +
 689            "(player ID #3915511), during the 2019 CFB season."
 690        )
 691        json_data = get_cfbd_player_usage(
 692            season=2019,
 693            player_id=3915511,
 694            exclude_garbage_time=True
 695        )
 696        print(json_data)
 697        time.sleep(5)
 698
 699        # You can also tell this function to just return the API call as
 700        # a Dictionary (read: JSON) object.
 701        print(
 702            "You can also tell this function to just return the API call " +
 703            "as a Dictionary (read: JSON) object."
 704        )
 705        json_data = get_cfbd_player_usage(
 706            season=2020,
 707            team="LSU",
 708            return_as_dict=True
 709        )
 710        print(json_data)
 711
 712    ```
 713    Returns
 714    ----------
 715    A pandas `DataFrame` object with player usage data,
 716    or (if `return_as_dict` is set to `True`)
 717    a dictionary object with player usage data.
 718
 719    """
 720
 721    now = datetime.now()
 722    players_df = pd.DataFrame()
 723    # row_df = pd.DataFrame()
 724    url = "https://api.collegefootballdata.com/player/usage"
 725
 726    ##########################################################################
 727
 728    if api_key is not None:
 729        real_api_key = api_key
 730        del api_key
 731    else:
 732        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
 733
 734    if real_api_key == "tigersAreAwesome":
 735        raise ValueError(
 736            "You actually need to change `cfbd_key` to your CFBD API key."
 737        )
 738    elif "Bearer " in real_api_key:
 739        pass
 740    elif "Bearer" in real_api_key:
 741        real_api_key = real_api_key.replace("Bearer", "Bearer ")
 742    else:
 743        real_api_key = "Bearer " + real_api_key
 744
 745    if season is None:
 746        # This should never happen without user tampering, but if it does,
 747        # we need to raise an error,
 748        # because the CFBD API will refuse this call without a valid season.
 749        raise SystemError(
 750            "I don't know how, I don't know why, "
 751            + "but you managed to call this function "
 752            + "while `season` was `None` (NULL),"
 753            + " and the function got to this point in the code."
 754            + "\nIf you have a GitHub account, "
 755            + "please raise an issue on this python package's GitHub page:\n"
 756            + "https://github.com/armstjc/cfbd-json-py/issues"
 757        )
 758    elif season > (now.year + 1):
 759        raise ValueError(f"`season` cannot be greater than {season}.")
 760    elif season < 1869:
 761        raise ValueError("`season` cannot be less than 1869.")
 762
 763    gt_str = ""
 764    if exclude_garbage_time is True:
 765        gt_str = "true"
 766    elif exclude_garbage_time is False:
 767        gt_str = "false"
 768
 769    # URL builder
 770    ##########################################################################
 771
 772    url += f"?year={season}"
 773
 774    if team is not None:
 775        url += f"&team={team}"
 776
 777    if conference is not None:
 778        url += f"&conference={conference}"
 779
 780    if position is not None:
 781        url += f"&position={position}"
 782
 783    if player_id is not None:
 784        url += f"&playerId={player_id}"
 785    if exclude_garbage_time is not None:
 786        url += f"&excludeGarbageTime={gt_str}"
 787
 788    headers = {
 789        "Authorization": f"{real_api_key}",
 790        "accept": "application/json"
 791    }
 792
 793    response = requests.get(url, headers=headers)
 794
 795    if response.status_code == 200:
 796        pass
 797    elif response.status_code == 401:
 798        raise ConnectionRefusedError(
 799            "Could not connect. The connection was refused." +
 800            "\nHTTP Status Code 401."
 801        )
 802    else:
 803        raise ConnectionError(
 804            f"Could not connect.\nHTTP Status code {response.status_code}"
 805        )
 806
 807    json_data = response.json()
 808
 809    if return_as_dict is True:
 810        return json_data
 811
 812    players_df = pd.json_normalize(json_data)
 813    players_df.rename(
 814        columns={
 815            "id": "player_id",
 816            "name": "player_name",
 817            "position": "position_abv",
 818            "team": "team_name",
 819            "conference": "conference_name",
 820            "usage.overall": "usage_overall",
 821            "usage.pass": "usage_pass",
 822            "usage.rush": "usage_rush",
 823            "usage.firstDown": "usage_first_down",
 824            "usage.secondDown": "usage_second_down",
 825            "usage.thirdDown": "usage_third_down",
 826            "usage.standardDowns": "usage_standard_downs",
 827            "usage.passingDowns": "usage_passing_downs",
 828        },
 829        inplace=True,
 830    )
 831    return players_df
 832
 833
 834def get_cfbd_returning_production(
 835    api_key: str = None,
 836    api_key_dir: str = None,
 837    season: int = None,
 838    team: str = None,
 839    # `season` or `team` must be specified.
 840    conference: str = None,
 841    return_as_dict: bool = False,
 842):
 843    """
 844    Get data from the CFBD API
 845    on how much returning production a team has going into a CFB season.
 846
 847    Parameters
 848    ----------
 849
 850    `api_key` (str, optional):
 851        Semi-optional argument.
 852        If `api_key` is null, this function will attempt to load a CFBD API key
 853        from the python environment, or from a file on this computer.
 854        If `api_key` is not null,
 855        this function will automatically assume that the
 856        inputted `api_key` is a valid CFBD API key.
 857
 858    `api_key_dir` (str, optional):
 859        Optional argument.
 860        If `api_key` is set to am empty string, this variable is ignored.
 861        If `api_key_dir` is null, and `api_key` is null,
 862        this function will try to find
 863        a CFBD API key file in this user's home directory.
 864        If `api_key_dir` is set to a string, and `api_key` is null,
 865        this function will assume that `api_key_dir` is a directory,
 866        and will try to find a CFBD API key file in that directory.
 867
 868    `season` (int, optional):
 869        Semi-optional argument.
 870        Specifies the season you want team PPA data from.
 871        You MUST set `season` or `team` to a non-null value for
 872        this function to work. If you don't, a `ValueError()`
 873        will be raised.
 874
 875    `team` (str, optional):
 876        Semi-optional argument.
 877        If you only want team PPA data for a specific team,
 878        set `team` to the name of the team you want team PPA data from.
 879        You MUST set `season` or `team` to a non-null value for
 880        this function to work. If you don't, a `ValueError()`
 881        will be raised.
 882
 883    `conference` (str, optional):
 884        Optional argument.
 885        If you only want team PPA data from games
 886        involving teams from a specific conference,
 887        set `conference` to the abbreviation
 888        of the conference you want team PPA data from.
 889        For a list of conferences,
 890        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 891        function.
 892
 893    `return_as_dict` (bool, semi-optional):
 894        Semi-optional argument.
 895        If you want this function to return
 896        the data as a dictionary (read: JSON object),
 897        instead of a pandas `DataFrame` object,
 898        set `return_as_dict` to `True`.
 899
 900    Usage
 901    ----------
 902    ```
 903    import time
 904
 905    from cfbd_json_py.players import get_cfbd_returning_production
 906
 907
 908    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 909
 910    if cfbd_key != "tigersAreAwesome":
 911        print(
 912            "Using the user's API key declared in this script " +
 913            "for this example."
 914        )
 915
 916        # Get returning production
 917        # for teams who competed in the 2020 CFB season.
 918        print(
 919            "Get returning production for teams " +
 920            "who competed in the 2020 CFB season."
 921        )
 922        json_data = get_cfbd_returning_production(
 923            api_key=cfbd_key,
 924            season=2020
 925        )
 926        print(json_data)
 927        time.sleep(5)
 928
 929        # Get historical returning production
 930        # for the Ohio Bobcats Football Team.
 931        print(
 932            "Get historical returning production " +
 933            "for the Ohio Bobcats Football Team."
 934        )
 935        json_data = get_cfbd_returning_production(
 936            api_key=cfbd_key,
 937            team="Ohio"
 938        )
 939        print(json_data)
 940        time.sleep(5)
 941
 942        # Get returning production for the 2019 LSU Tigers.
 943        print("Get returning production for the 2019 LSU Tigers.")
 944        json_data = get_cfbd_returning_production(
 945            api_key=cfbd_key,
 946            season=2019,
 947            team="LSU"
 948        )
 949        print(json_data)
 950        time.sleep(5)
 951
 952        # Get returning production for Maryland,
 953        # for seasons where Maryland is a member
 954        # of the Big 10 (B1G) Conference.
 955        print(
 956            "Get returning production for Maryland, " +
 957            "for seasons where Maryland is a member " +
 958            "of the Big 10 (B1G) Conference."
 959        )
 960        json_data = get_cfbd_returning_production(
 961            api_key=cfbd_key,
 962            team="Maryland",
 963            conference="B1G"
 964        )
 965        print(json_data)
 966        time.sleep(5)
 967
 968        # You can also tell this function to just return the API call as
 969        # a Dictionary (read: JSON) object.
 970        print(
 971            "You can also tell this function to just return the API call " +
 972            "as a Dictionary (read: JSON) object."
 973        )
 974        json_data = get_cfbd_returning_production(
 975            api_key=cfbd_key,
 976            season=2020,
 977            team="LSU",
 978            return_as_dict=True
 979        )
 980        print(json_data)
 981
 982    else:
 983        # Alternatively, if the CFBD API key exists in this python environment,
 984        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 985        # you could just call these functions directly,
 986        # without setting the API key in the script.
 987        print(
 988            "Using the user's API key supposedly loaded " +
 989            "into this python environment for this example."
 990        )
 991
 992        # Get returning production
 993        # for teams who competed in the 2020 CFB season.
 994        print(
 995            "Get returning production for teams " +
 996            "who competed in the 2020 CFB season."
 997        )
 998        json_data = get_cfbd_returning_production(
 999            season=2020
1000        )
1001        print(json_data)
1002        time.sleep(5)
1003
1004        # Get historical returning production
1005        # for the Ohio Bobcats Football Team.
1006        print(
1007            "Get historical returning production " +
1008            "for the Ohio Bobcats Football Team."
1009        )
1010        json_data = get_cfbd_returning_production(
1011            team="Ohio"
1012        )
1013        print(json_data)
1014        time.sleep(5)
1015
1016        # Get returning production for the 2019 LSU Tigers.
1017        print("Get returning production for the 2019 LSU Tigers.")
1018        json_data = get_cfbd_returning_production(
1019            season=2019,
1020            team="LSU"
1021        )
1022        print(json_data)
1023        time.sleep(5)
1024
1025        # Get returning production for Maryland,
1026        # for seasons where Maryland is a member
1027        # of the Big 10 (B1G) Conference.
1028        print(
1029            "Get returning production for Maryland, " +
1030            "for seasons where Maryland is a member " +
1031            "of the Big 10 (B1G) Conference."
1032        )
1033        json_data = get_cfbd_returning_production(
1034            team="Maryland",
1035            conference="B1G"
1036        )
1037        print(json_data)
1038        time.sleep(5)
1039
1040        # You can also tell this function to just return the API call as
1041        # a Dictionary (read: JSON) object.
1042        print(
1043            "You can also tell this function to just return the API call " +
1044            "as a Dictionary (read: JSON) object."
1045        )
1046        json_data = get_cfbd_returning_production(
1047            season=2020,
1048            team="LSU",
1049            return_as_dict=True
1050        )
1051        print(json_data)
1052
1053
1054    ```
1055    Returns
1056    ----------
1057    A pandas `DataFrame` object with returning production data,
1058    or (if `return_as_dict` is set to `True`)
1059    a dictionary object with returning production data.
1060
1061    """
1062    now = datetime.now()
1063    team_df = pd.DataFrame()
1064    # row_df = pd.DataFrame()
1065    url = "https://api.collegefootballdata.com/player/returning"
1066
1067    ##########################################################################
1068
1069    if api_key is not None:
1070        real_api_key = api_key
1071        del api_key
1072    else:
1073        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1074
1075    if real_api_key == "tigersAreAwesome":
1076        raise ValueError(
1077            "You actually need to change `cfbd_key` to your CFBD API key."
1078        )
1079    elif "Bearer " in real_api_key:
1080        pass
1081    elif "Bearer" in real_api_key:
1082        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1083    else:
1084        real_api_key = "Bearer " + real_api_key
1085
1086    if season is None and team is None:
1087        raise ValueError(
1088            "To use this function, `season` and/or `team` must be set to a "
1089            + "non-null variable."
1090        )
1091
1092    if season is None:
1093        # Rare, but in this endpoint,
1094        # you don't need to input the season.
1095        pass
1096    elif season > (now.year + 1):
1097        raise ValueError(f"`season` cannot be greater than {season}.")
1098    elif season < 1869:
1099        raise ValueError("`season` cannot be less than 1869.")
1100
1101    # URL Builder
1102    ##########################################################################
1103
1104    url_elements = 0
1105
1106    if season is not None and url_elements == 0:
1107        url += f"?year={season}"
1108        url_elements += 1
1109    elif season is not None:
1110        url += f"&year={season}"
1111        url_elements += 1
1112
1113    if team is not None and url_elements == 0:
1114        url += f"?team={team}"
1115        url_elements += 1
1116    elif team is not None:
1117        url += f"&team={team}"
1118        url_elements += 1
1119
1120    if conference is not None and url_elements == 0:
1121        url += f"?conference={conference}"
1122        url_elements += 1
1123    elif conference is not None:
1124        url += f"&conference={conference}"
1125        url_elements += 1
1126
1127    headers = {
1128        "Authorization": f"{real_api_key}",
1129        "accept": "application/json"
1130    }
1131
1132    response = requests.get(url, headers=headers)
1133
1134    if response.status_code == 200:
1135        pass
1136    elif response.status_code == 401:
1137        raise ConnectionRefusedError(
1138            "Could not connect. The connection was refused." +
1139            "\nHTTP Status Code 401."
1140        )
1141    else:
1142        raise ConnectionError(
1143            f"Could not connect.\nHTTP Status code {response.status_code}"
1144        )
1145
1146    json_data = response.json()
1147
1148    if return_as_dict is True:
1149        return json_data
1150
1151    team_df = pd.json_normalize(json_data)
1152    team_df.rename(
1153        columns={
1154            "team": "team_name",
1155            "conference": "conference_name",
1156            "totalPPA": "returning_total_ppa",
1157            "totalPassingPPA": "returning_total_passing_ppa",
1158            "totalReceivingPPA": "returning_total_receiving_ppa",
1159            "totalRushingPPA": "returning_total_rush_ppa",
1160            "percentPPA": "returning_ppa_percent",
1161            "percentPassingPPA": "returning_percent_passing_ppa",
1162            "percentReceivingPPA": "returning_percent_receiving_ppa",
1163            "percentRushingPPA": "returning_percent_rushing_ppa",
1164            "usage": "returning_usage",
1165            "passingUsage": "returning_passing_usage",
1166            "receivingUsage": "returning_receiving_usage",
1167            "rushingUsage": "returning_rushing_usage",
1168        },
1169        inplace=True,
1170    )
1171    return team_df
1172
1173
1174def get_cfbd_player_season_stats(
1175    season: int,
1176    api_key: str = None,
1177    api_key_dir: str = None,
1178    team: str = None,
1179    conference: str = None,
1180    start_week: int = None,
1181    end_week: int = None,
1182    season_type: str = "both",  # "regular", "postseason", or "both"
1183    stat_category: str = None,
1184    return_as_dict: bool = False,
1185):
1186    """
1187    Get player season stats,
1188    or the stats of players in a specific time frame, from the CFBD API.
1189
1190    Parameters
1191    ----------
1192    `season` (int, mandatory):
1193        Required argument.
1194        Specifies the season you want CFB player season stats from.
1195        This must be specified, otherwise this package, and by extension
1196        the CFBD API, will not accept
1197        the request to get CFB player season stats.
1198
1199    `api_key` (str, optional):
1200        Semi-optional argument.
1201        If `api_key` is null, this function will attempt to load a CFBD API key
1202        from the python environment, or from a file on this computer.
1203        If `api_key` is not null,
1204        this function will automatically assume that the
1205        inputted `api_key` is a valid CFBD API key.
1206
1207    `api_key_dir` (str, optional):
1208        Optional argument.
1209        If `api_key` is set to am empty string, this variable is ignored.
1210        If `api_key_dir` is null, and `api_key` is null,
1211        this function will try to find
1212        a CFBD API key file in this user's home directory.
1213        If `api_key_dir` is set to a string, and `api_key` is null,
1214        this function will assume that `api_key_dir` is a directory,
1215        and will try to find a CFBD API key file in that directory.
1216
1217    `team` (str, optional):
1218        Optional argument.
1219        If you only want CFB player season stats for a team,
1220        regardless if they are the home/away team,
1221        set `team` to the name of the team
1222        you want CFB player season stats from.
1223
1224    `conference` (str, optional):
1225        Optional argument.
1226        If you only want player season stats from games
1227        involving teams a specific conference,
1228        set `conference` to the abbreviation
1229        of the conference you want stats from.
1230
1231    `start_week` (int, semi-optional):
1232        Optional argument.
1233        If you only want player stats for a range of weeks,
1234        set `start_week` and `end_week` to
1235        the range of weeks you want season-level data for.
1236
1237    `end_week` (int, semi-optional):
1238        Optional argument.
1239        If you only want player stats for a range of weeks,
1240        set `start_week` and `end_week` to
1241        the range of weeks you want season-level data for.
1242
1243    **NOTE**: If the following conditions are `True`, a `ValueError()`
1244    will be raised when calling this function:
1245    - `start_week < 0`
1246    - `end_week < 0`
1247    - `start_week is not None and end_week is None`
1248        (will be changed in a future version)
1249    - `start_week is None and end_week is not None`
1250        (will be changed in a future version)
1251    - `end_week < start_week`
1252    - `end_week = start_week`
1253
1254    `season_type` (str, semi-optional):
1255        Semi-optional argument.
1256        By default, this will be set to "regular", for the CFB regular season.
1257        If you want CFB media information for non-regular season games,
1258        set `season_type` to "postseason".
1259        If you want ***both*** regular
1260        and postseason stats, set `season_type = "both"`.
1261        If `season_type` is set to anything but "regular",
1262        "postseason",  or "both", a `ValueError()` will be raised.
1263
1264    `stat_category` (str, optional):
1265        Optional argument.
1266        If only want stats for a specific stat category,
1267        set this variable to that category.
1268
1269        Valid inputs are:
1270        - `passing`
1271        - `rushing`
1272        - `receiving`
1273        - `fumbles`
1274        - `defensive`
1275        - `interceptions`
1276        - `punting`
1277        - `kicking`
1278        - `kickReturns`
1279        - `puntReturns`
1280
1281    `return_as_dict` (bool, semi-optional):
1282        Semi-optional argument.
1283        If you want this function to return
1284        the data as a dictionary (read: JSON object),
1285        instead of a pandas `DataFrame` object,
1286        set `return_as_dict` to `True`.
1287
1288    Usage
1289    ----------
1290    ```
1291    import time
1292
1293    from cfbd_json_py.players import get_cfbd_player_season_stats
1294
1295
1296    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
1297
1298    if cfbd_key != "tigersAreAwesome":
1299        print(
1300            "Using the user's API key declared in this script " +
1301            "for this example."
1302        )
1303
1304        # Get player season stats for
1305        # the Ohio Bobcats Football team in the 2020 CFB season.
1306        print(
1307            "Get player season stats for " +
1308            "the Ohio Bobcats Football team in the 2020 CFB season."
1309        )
1310        json_data = get_cfbd_player_season_stats(
1311            api_key=cfbd_key,
1312            season=2020,
1313            team="Ohio"
1314        )
1315        print(json_data)
1316        time.sleep(5)
1317
1318        # Get player season stats for teams who competed in
1319        # the Southeastern conference (SEC) in the 2023 CFB season.
1320        print(
1321            "Get player season stats for teams who competed " +
1322            "in the Southeastern conference (SEC) in the 2023 CFB season."
1323        )
1324        json_data = get_cfbd_player_season_stats(
1325            api_key=cfbd_key,
1326            season=2020,
1327            conference="SEC"
1328        )
1329        print(json_data)
1330        time.sleep(5)
1331
1332        # Get player season stats for teams who competed in
1333        # the Southeastern conference (SEC) in the 2023 CFB season,
1334        # but only between weeks 1 and 5.
1335        print(
1336            "Get player season stats for teams who competed " +
1337            "in the Southeastern conference (SEC) in the 2023 CFB season."
1338        )
1339        json_data = get_cfbd_player_season_stats(
1340            api_key=cfbd_key,
1341            season=2020,
1342            conference="SEC",
1343            start_week=1,
1344            end_week=5
1345        )
1346        print(json_data)
1347        time.sleep(5)
1348
1349        # Get player season stats for the 2020 CFB season.
1350        print("Get player season stats for the 2020 CFB season.")
1351        json_data = get_cfbd_player_season_stats(
1352            api_key=cfbd_key,
1353            season=2020
1354        )
1355        print(json_data)
1356        time.sleep(5)
1357
1358        # Get player season stats for
1359        # the Ohio Bobcats Football team in the 2022 CFB season,
1360        # but only use regular season games when calculating season stats.
1361        print(
1362            "Get player season stats for the Ohio Bobcats Football team " +
1363            "in the 2020 CFB season, but only use regular season games " +
1364            "when calculating season stats."
1365        )
1366        json_data = get_cfbd_player_season_stats(
1367            api_key=cfbd_key,
1368            season=2022,
1369            team="Ohio",
1370            season_type="regular"
1371        )
1372        print(json_data)
1373        time.sleep(5)
1374
1375        # Get passing stats for teams who competed in
1376        # the Southeastern conference (SEC) in the 2023 CFB season.
1377        print(
1378            "Get passing stats for teams who competed " +
1379            "in the Southeastern conference (SEC) in the 2023 CFB season."
1380        )
1381        json_data = get_cfbd_player_season_stats(
1382            api_key=cfbd_key,
1383            season=2020,
1384            conference="SEC",
1385            stat_category="passing"
1386        )
1387        print(json_data)
1388        time.sleep(5)
1389
1390        # You can also tell this function to just return the API call as
1391        # a Dictionary (read: JSON) object.
1392        print(
1393            "You can also tell this function to just return the API call " +
1394            "as a Dictionary (read: JSON) object."
1395        )
1396        json_data = get_cfbd_player_season_stats(
1397            api_key=cfbd_key,
1398            season=2020,
1399            team="LSU",
1400            stat_category="kicking",
1401            return_as_dict=True
1402        )
1403        print(json_data)
1404
1405    else:
1406        # Alternatively, if the CFBD API key exists in this python environment,
1407        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
1408        # you could just call these functions directly,
1409        # without setting the API key in the script.
1410        print(
1411            "Using the user's API key supposedly loaded " +
1412            "into this python environment for this example."
1413        )
1414
1415        # Get player season stats for
1416        # the Ohio Bobcats Football team in the 2020 CFB season.
1417        print(
1418            "Get player season stats for " +
1419            "the Ohio Bobcats Football team in the 2020 CFB season."
1420        )
1421        json_data = get_cfbd_player_season_stats(
1422            season=2020,
1423            team="Ohio"
1424        )
1425        print(json_data)
1426        time.sleep(5)
1427
1428        # Get player season stats for teams who competed in
1429        # the Southeastern conference (SEC) in the 2023 CFB season.
1430        print(
1431            "Get player season stats for teams who competed " +
1432            "in the Southeastern conference (SEC) in the 2023 CFB season."
1433        )
1434        json_data = get_cfbd_player_season_stats(
1435            season=2020,
1436            conference="SEC"
1437        )
1438        print(json_data)
1439        time.sleep(5)
1440
1441        # Get player season stats for teams who competed in
1442        # the Southeastern conference (SEC) in the 2023 CFB season,
1443        # but only between weeks 1 and 5.
1444        print(
1445            "Get player season stats for teams who competed " +
1446            "in the Southeastern conference (SEC) in the 2023 CFB season."
1447        )
1448        json_data = get_cfbd_player_season_stats(
1449            season=2020,
1450            conference="SEC",
1451            start_week=1,
1452            end_week=5
1453        )
1454        print(json_data)
1455        time.sleep(5)
1456
1457        # Get player season stats for the 2020 CFB season.
1458        print("Get player season stats for the 2020 CFB season.")
1459        json_data = get_cfbd_player_season_stats(
1460            season=2020
1461        )
1462        print(json_data)
1463        time.sleep(5)
1464
1465        # Get player season stats for
1466        # the Ohio Bobcats Football team in the 2022 CFB season,
1467        # but only use regular season games when calculating season stats.
1468        print(
1469            "Get player season stats for the Ohio Bobcats Football team " +
1470            "in the 2020 CFB season, but only use regular season games " +
1471            "when calculating season stats."
1472        )
1473        json_data = get_cfbd_player_season_stats(
1474            season=2022,
1475            team="Ohio",
1476            season_type="regular"
1477        )
1478        print(json_data)
1479        time.sleep(5)
1480
1481        # Get passing stats for teams who competed in
1482        # the Southeastern conference (SEC) in the 2023 CFB season.
1483        print(
1484            "Get passing stats for teams who competed " +
1485            "in the Southeastern conference (SEC) in the 2023 CFB season."
1486        )
1487        json_data = get_cfbd_player_season_stats(
1488            season=2020,
1489            conference="SEC",
1490            stat_category="passing"
1491        )
1492        print(json_data)
1493        time.sleep(5)
1494
1495        # You can also tell this function to just return the API call as
1496        # a Dictionary (read: JSON) object.
1497        print(
1498            "You can also tell this function to just return the API call " +
1499            "as a Dictionary (read: JSON) object."
1500        )
1501        json_data = get_cfbd_player_season_stats(
1502            season=2020,
1503            team="LSU",
1504            stat_category="kicking",
1505            return_as_dict=True
1506        )
1507        print(json_data)
1508
1509    ```
1510    Returns
1511    ----------
1512    A pandas `DataFrame` object with
1513    a list of players who matched the search string,
1514    or (if `return_as_dict` is set to `True`)
1515    a dictionary object with a list of players who matched the search string.
1516
1517    """
1518
1519    rebuilt_json = {}
1520    rebuilt_json_list = []
1521
1522    stat_columns = [
1523        "season",
1524        "team_name",
1525        "team_conference",
1526        "player_id",
1527        "player_name",
1528        # PASS
1529        "passing_COMP",
1530        "passing_ATT",
1531        "passing_COMP%",
1532        "passing_YDS",
1533        "passing_AVG",
1534        "passing_TD",
1535        "passing_INT",
1536        # RUSH
1537        "rushing_CAR",
1538        "rushing_YDS",
1539        "rushing_AVG",
1540        "rushing_TD",
1541        "rushing_LONG",
1542        # REC
1543        "receiving_REC",
1544        "receiving_YDS",
1545        "receiving_AVG",
1546        "receiving_TD",
1547        "receiving_LONG",
1548        # FUM
1549        "fumbles_FUM",
1550        "fumbles_LOST",
1551        "fumbles_REC",
1552        # DEFENSE
1553        "defensive_TOT",
1554        "defensive_SOLO",
1555        "defensive_TFL",
1556        "defensive_QB HUR",
1557        "defensive_SACKS",
1558        "defensive_PD",
1559        "defensive_TD",
1560        # INT
1561        "interceptions_INT",
1562        "interceptions_YDS",
1563        "interceptions_TD",
1564        # PUNT
1565        "punting_NO",
1566        "punting_YDS",
1567        "punting_AVG",
1568        "punting_TB",
1569        "punting_In 20",
1570        "punting_LONG",
1571        # KICK
1572        "kicking_FGM",
1573        "kicking_FGA",
1574        "kicking_FG%",
1575        "kicking_LONG",
1576        "kicking_XPM",
1577        "kicking_XPA",
1578        "kicking_XP%",
1579        # KR
1580        "kickReturns_NO",
1581        "kickReturns_YDS",
1582        "kickReturns_AVG",
1583        "kickReturns_TD",
1584        "kickReturns_LONG",
1585        # PR
1586        "puntReturns_NO",
1587        "puntReturns_YDS",
1588        "puntReturns_AVG",
1589        "puntReturns_TD",
1590        "puntReturns_LONG",
1591    ]
1592
1593    now = datetime.now()
1594    url = "https://api.collegefootballdata.com/stats/player/season"
1595
1596    final_df = pd.DataFrame()
1597
1598    if api_key is not None:
1599        real_api_key = api_key
1600        del api_key
1601    else:
1602        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1603
1604    if real_api_key == "tigersAreAwesome":
1605        raise ValueError(
1606            "You actually need to change `cfbd_key` to your CFBD API key."
1607        )
1608    elif "Bearer " in real_api_key:
1609        pass
1610    elif "Bearer" in real_api_key:
1611        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1612    else:
1613        real_api_key = "Bearer " + real_api_key
1614
1615    if season is None:
1616        # This should never happen without user tampering, but if it does,
1617        # we need to raise an error,
1618        # because the CFBD API will refuse this call without a valid season.
1619        raise SystemError(
1620            "I don't know how, I don't know why, "
1621            + "but you managed to call this function "
1622            + "while `season` was `None` (NULL),"
1623            + " and the function got to this point in the code."
1624            + "\nIf you have a GitHub account, "
1625            + "please raise an issue on this python package's GitHub page:\n"
1626            + "https://github.com/armstjc/cfbd-json-py/issues"
1627        )
1628    elif season > (now.year + 1):
1629        raise ValueError(f"`season` cannot be greater than {season}.")
1630    elif season < 1869:
1631        raise ValueError("`season` cannot be less than 1869.")
1632
1633    if (
1634        season_type != "regular"
1635        and season_type != "postseason"
1636        and season_type != "both"
1637    ):
1638        raise ValueError(
1639            '`season_type` must be set to either "regular" or '
1640            + '"postseason" for this function to work.'
1641        )
1642
1643    filter_by_stat_category = False
1644
1645    if stat_category is None:
1646        pass
1647    elif stat_category == "passing":
1648        filter_by_stat_category = True
1649    elif stat_category == "rushing":
1650        filter_by_stat_category = True
1651    elif stat_category == "receiving":
1652        filter_by_stat_category = True
1653    elif stat_category == "fumbles":
1654        filter_by_stat_category = True
1655    elif stat_category == "passing":
1656        filter_by_stat_category = True
1657    elif stat_category == "defensive":
1658        filter_by_stat_category = True
1659    elif stat_category == "interceptions":
1660        filter_by_stat_category = True
1661    elif stat_category == "punting":
1662        filter_by_stat_category = True
1663    elif stat_category == "kicking":
1664        filter_by_stat_category = True
1665    elif stat_category == "kickReturns":
1666        filter_by_stat_category = True
1667    elif stat_category == "puntReturns":
1668        filter_by_stat_category = True
1669    else:
1670        raise ValueError(
1671            "Invalid input for `stat_category`."
1672            + "\nValid inputs are:"
1673            + """
1674            - `passing`
1675            - `rushing`
1676            - `receiving`
1677            - `fumbles`
1678            - `defensive`
1679            - `interceptions`
1680            - `punting`
1681            - `kicking`
1682            - `kickReturns`
1683            - `puntReturns`
1684            """
1685        )
1686
1687    if start_week is not None and end_week is not None:
1688        if start_week > end_week:
1689            raise ValueError("`start_week` cannot be greater than `end_week`.")
1690        elif start_week == end_week:
1691            raise ValueError(
1692                "`start_week` cannot be equal to `end_week`."
1693                + "\n Use "
1694                + "`cfbd_json_py.games.get_cfbd_player_game_stats()` instead "
1695                + "if you want player stats for a specific week in ."
1696            )
1697        elif start_week < 0:
1698            raise ValueError("`start_week` cannot be less than 0.")
1699        elif end_week < 0:
1700            raise ValueError("`end_week` cannot be less than 0.")
1701
1702    if filter_by_stat_category is True:
1703        pass
1704
1705    # URL builder
1706    ##########################################################################
1707
1708    # Required by the API
1709    url += f"?year={season}"
1710
1711    if team is not None:
1712        url += f"&team={team}"
1713
1714    if conference is not None:
1715        url += f"&conference={conference}"
1716
1717    if season_type is not None:
1718        url += f"&seasonType={season_type}"
1719
1720    if stat_category is not None:
1721        url += f"&category={stat_category}"
1722
1723    if start_week is not None:
1724        url += f"&startWeek={start_week}"
1725
1726    if end_week is not None:
1727        url += f"&endWeek={end_week}"
1728
1729    headers = {
1730        "Authorization": f"{real_api_key}",
1731        "accept": "application/json"
1732    }
1733
1734    response = requests.get(url, headers=headers)
1735
1736    if response.status_code == 200:
1737        pass
1738    elif response.status_code == 401:
1739        raise ConnectionRefusedError(
1740            "Could not connect. The connection was refused." +
1741            "\nHTTP Status Code 401."
1742        )
1743    else:
1744        raise ConnectionError(
1745            f"Could not connect.\nHTTP Status code {response.status_code}"
1746        )
1747
1748    json_data = response.json()
1749
1750    if return_as_dict is True:
1751        return json_data
1752
1753    for player in json_data:
1754        player_id = player["playerId"]
1755        player_name = player["player"]
1756        team_name = player["team"]
1757        team_conference = player["conference"]
1758
1759        if rebuilt_json.get(player_id) is None:
1760            rebuilt_json[player_id] = {}
1761
1762        stat_category = player["category"]
1763        stat_type = player["statType"]
1764        stat_name = f"{stat_category}_{stat_type}"
1765
1766        stat_value = player["stat"]
1767
1768        rebuilt_json[player_id]["player_id"] = player_id
1769        rebuilt_json[player_id]["player_name"] = player_name
1770        rebuilt_json[player_id]["team_name"] = team_name
1771        rebuilt_json[player_id]["team_conference"] = team_conference
1772        rebuilt_json[player_id][stat_name] = stat_value
1773
1774    for _, value in rebuilt_json.items():
1775        rebuilt_json_list.append(value)
1776
1777    final_df = pd.DataFrame(rebuilt_json_list)
1778    final_df["season"] = season
1779    # print(final_df.columns)
1780
1781    final_df = final_df.rename(
1782        columns={
1783            "passing_COMPLETIONS": "passing_COMP",
1784            "passing_YPA": "passing_AVG",
1785            "passing_PCT": "passing_COMP%",
1786            "rushing_YPC": "rushing_AVG",
1787            "punting_YPP": "punting_AVG",
1788            "kicking_PCT": "kicking_FG%",
1789            "receiving_YPR": "receiving_AVG",
1790        }
1791    )
1792    final_df = final_df.reindex(columns=stat_columns)
1793    final_df = final_df.fillna(0)
1794    final_df = final_df.astype(
1795        {
1796            "passing_COMP": "int",
1797            "passing_ATT": "int",
1798            "rushing_CAR": "int",
1799            "rushing_YDS": "int",
1800            "receiving_REC": "int",
1801            "receiving_YDS": "int",
1802            "punting_NO": "int",
1803            "punting_YDS": "int",
1804            "kicking_FGM": "int",
1805            "kicking_FGA": "int",
1806            "kicking_XPM": "int",
1807            "kicking_XPA": "int",
1808            "kickReturns_NO": "int",
1809            "kickReturns_YDS": "int",
1810            "puntReturns_NO": "int",
1811            "puntReturns_YDS": "int",
1812        },
1813        # errors="ignore"
1814    )
1815
1816    final_df.loc[final_df["passing_ATT"] > 0, "passing_COMP%"] = (
1817        final_df["passing_COMP"] / final_df["passing_ATT"]
1818    )
1819    final_df["passing_COMP%"] = final_df["passing_COMP%"].round(3)
1820
1821    final_df.loc[final_df["rushing_CAR"] > 0, "rushing_AVG"] = (
1822        final_df["rushing_YDS"] / final_df["rushing_CAR"]
1823    )
1824    final_df["rushing_AVG"] = final_df["rushing_AVG"].round(3)
1825
1826    final_df.loc[final_df["receiving_REC"] > 0, "receiving_AVG"] = (
1827        final_df["receiving_YDS"] / final_df["receiving_REC"]
1828    )
1829    final_df["receiving_AVG"] = final_df["receiving_AVG"].round(3)
1830
1831    final_df.loc[final_df["punting_NO"] > 0, "punting_AVG"] = (
1832        final_df["punting_YDS"] / final_df["punting_NO"]
1833    )
1834    final_df["punting_AVG"] = final_df["punting_AVG"].round(3)
1835
1836    final_df.loc[final_df["kicking_FGA"] > 0, "kicking_FG%"] = (
1837        final_df["kicking_FGM"] / final_df["kicking_FGA"]
1838    )
1839    final_df["kicking_FG%"] = final_df["kicking_FG%"].round(5)
1840
1841    final_df.loc[final_df["kicking_XPA"] > 0, "kicking_XP%"] = (
1842        final_df["kicking_XPM"] / final_df["kicking_XPA"]
1843    )
1844    final_df["kicking_XP%"] = final_df["kicking_XP%"].round(5)
1845
1846    final_df.loc[final_df["kickReturns_NO"] > 0, "kickReturns_AVG"] = (
1847        final_df["kickReturns_YDS"] / final_df["kickReturns_NO"]
1848    )
1849    final_df["kickReturns_AVG"] = final_df["kickReturns_AVG"].round(3)
1850
1851    final_df.loc[final_df["puntReturns_NO"] > 0, "puntReturns_AVG"] = (
1852        final_df["puntReturns_YDS"] / final_df["puntReturns_NO"]
1853    )
1854    final_df["puntReturns_AVG"] = final_df["puntReturns_AVG"].round(3)
1855    if filter_by_stat_category is True and stat_category == "passing":
1856
1857        final_df = final_df[
1858            [
1859                "season",
1860                "team_name",
1861                "team_conference",
1862                "player_id",
1863                "player_name",
1864                # PASS
1865                "passing_COMP",
1866                "passing_ATT",
1867                "passing_YDS",
1868                "passing_TD",
1869                "passing_INT",
1870            ]
1871        ]
1872    elif filter_by_stat_category is True and stat_category == "rushing":
1873
1874        final_df = final_df[
1875            [
1876                "season",
1877                "team_name",
1878                "team_conference",
1879                "player_id",
1880                "player_name",
1881                # RUSH
1882                "rushing_CAR",
1883                "rushing_YDS",
1884                "rushing_AVG",
1885                "rushing_TD",
1886                "rushing_LONG",
1887            ]
1888        ]
1889    elif filter_by_stat_category is True and stat_category == "receiving":
1890
1891        final_df = final_df[
1892            [
1893                "season",
1894                "team_name",
1895                "team_conference",
1896                "player_id",
1897                "player_name",
1898                # REC
1899                "receiving_REC",
1900                "receiving_YDS",
1901                "receiving_AVG",
1902                "receiving_TD",
1903                "receiving_LONG",
1904            ]
1905        ]
1906    elif filter_by_stat_category is True and stat_category == "fumbles":
1907        final_df = final_df[
1908            [
1909                "season",
1910                "team_name",
1911                "team_conference",
1912                "player_id",
1913                "player_name",
1914                # FUM
1915                "fumbles_FUM",
1916                "fumbles_LOST",
1917                "fumbles_REC",
1918            ]
1919        ]
1920    elif filter_by_stat_category is True and stat_category == "defensive":
1921        final_df = final_df[
1922            [
1923                "season",
1924                "team_name",
1925                "team_conference",
1926                "player_id",
1927                "player_name",
1928                # DEFENSE
1929                "defensive_TOT",
1930                "defensive_SOLO",
1931                "defensive_TFL",
1932                "defensive_QB HUR",
1933                "defensive_SACKS",
1934                "defensive_PD",
1935                "defensive_TD",
1936            ]
1937        ]
1938    elif filter_by_stat_category is True and stat_category == "interceptions":
1939        final_df = final_df[
1940            [
1941                "season",
1942                "team_name",
1943                "team_conference",
1944                "player_id",
1945                "player_name",
1946                # INT
1947                "interceptions_INT",
1948                "interceptions_YDS",
1949                "interceptions_TD",
1950            ]
1951        ]
1952    elif filter_by_stat_category is True and stat_category == "punting":
1953
1954        final_df = final_df[
1955            [
1956                "season",
1957                "team_name",
1958                "team_conference",
1959                "player_id",
1960                "player_name",
1961                # PUNT
1962                "punting_NO",
1963                "punting_YDS",
1964                "punting_AVG",
1965                "punting_TB",
1966                "punting_In 20",
1967                "punting_LONG",
1968            ]
1969        ]
1970    elif filter_by_stat_category is True and stat_category == "kicking":
1971
1972        final_df = final_df[
1973            [
1974                "season",
1975                "team_name",
1976                "team_conference",
1977                "player_id",
1978                "player_name",
1979                # KICK
1980                "kicking_FGM",
1981                "kicking_FGA",
1982                "kicking_FG%",
1983                "kicking_LONG",
1984                "kicking_XPM",
1985                "kicking_XPA" "kicking_XP%",
1986            ]
1987        ]
1988    elif filter_by_stat_category is True and stat_category == "kickReturns":
1989
1990        final_df = final_df[
1991            [
1992                "season",
1993                "team_name",
1994                "team_conference",
1995                "player_id",
1996                "player_name",
1997                # KR
1998                "kickReturns_NO",
1999                "kickReturns_YDS",
2000                "kickReturns_AVG",
2001                "kickReturns_TD",
2002                "kickReturns_LONG",
2003            ]
2004        ]
2005    elif filter_by_stat_category is True and stat_category == "puntReturns":
2006
2007        final_df = final_df[
2008            [
2009                "season",
2010                "team_name",
2011                "team_conference",
2012                "player_id",
2013                "player_name",
2014                # KR
2015                "puntReturns_NO",
2016                "puntReturns_YDS",
2017                "puntReturns_AVG",
2018                "puntReturns_TD",
2019                "puntReturns_LONG",
2020            ]
2021        ]
2022
2023    return final_df
2024
2025
2026def get_cfbd_transfer_portal_data(
2027    season: int,
2028    api_key: str = None,
2029    api_key_dir: str = None,
2030    return_as_dict: bool = False,
2031):
2032    """
2033    Get player usage data
2034    (A.K.A., the percentages for how often a player touched the ball),
2035    for a given season, from the CFBD API.
2036
2037    Parameters
2038    ----------
2039    `season` (int, mandatory):
2040        Required argument.
2041        Specifies the season you want CFB transfer portal data from.
2042        This must be specified, otherwise this package, and by extension
2043        the CFBD API, will not accept
2044        the request to get CFB transfer portal data stats.
2045
2046    `api_key` (str, optional):
2047        Semi-optional argument.
2048        If `api_key` is null, this function will attempt to load a CFBD API key
2049        from the python environment, or from a file on this computer.
2050        If `api_key` is not null,
2051        this function will automatically assume that the
2052        inputted `api_key` is a valid CFBD API key.
2053
2054    `api_key_dir` (str, optional):
2055        Optional argument.
2056        If `api_key` is set to am empty string, this variable is ignored.
2057        If `api_key_dir` is null, and `api_key` is null,
2058        this function will try to find
2059        a CFBD API key file in this user's home directory.
2060        If `api_key_dir` is set to a string, and `api_key` is null,
2061        this function will assume that `api_key_dir` is a directory,
2062        and will try to find a CFBD API key file in that directory.
2063
2064    `return_as_dict` (bool, semi-optional):
2065        Semi-optional argument.
2066        If you want this function to return
2067        the data as a dictionary (read: JSON object),
2068        instead of a pandas `DataFrame` object,
2069        set `return_as_dict` to `True`.
2070
2071    Usage
2072    ----------
2073    ```
2074    import time
2075
2076    from cfbd_json_py.players import get_cfbd_transfer_portal_data
2077
2078
2079    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
2080
2081    if cfbd_key != "tigersAreAwesome":
2082        print(
2083            "Using the user's API key declared in this script " +
2084            "for this example."
2085        )
2086
2087        # Get Transfer Portal data for the 2021 CFB season.
2088        print("Get Transfer Portal data for the 2021 CFB season.")
2089        json_data = get_cfbd_transfer_portal_data(
2090            api_key=cfbd_key,
2091            season=2021
2092        )
2093        print(json_data)
2094        time.sleep(5)
2095
2096        # You can also tell this function to just return the API call as
2097        # a Dictionary (read: JSON) object.
2098        print(
2099            "You can also tell this function to just return the API call " +
2100            "as a Dictionary (read: JSON) object."
2101        )
2102        json_data = get_cfbd_transfer_portal_data(
2103            api_key=cfbd_key,
2104            season=2021,
2105            return_as_dict=True
2106        )
2107        print(json_data)
2108
2109    else:
2110        # Alternatively, if the CFBD API key exists in this python environment,
2111        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
2112        # you could just call these functions directly,
2113        # without setting the API key in the script.
2114        print(
2115            "Using the user's API key supposedly loaded " +
2116            "into this python environment for this example."
2117        )
2118
2119        # Get Transfer Portal data for the 2021 CFB season.
2120        print("Get Transfer Portal data for the 2021 CFB season.")
2121        json_data = get_cfbd_transfer_portal_data(
2122            season=2021
2123        )
2124        print(json_data)
2125        time.sleep(5)
2126
2127        # You can also tell this function to just return the API call as
2128        # a Dictionary (read: JSON) object.
2129        print(
2130            "You can also tell this function to just return the API call " +
2131            "as a Dictionary (read: JSON) object."
2132        )
2133        json_data = get_cfbd_transfer_portal_data(
2134            season=2021,
2135            return_as_dict=True
2136        )
2137        print(json_data)
2138
2139    ```
2140    Returns
2141    ----------
2142    A pandas `DataFrame` object with transfer portal data,
2143    or (if `return_as_dict` is set to `True`)
2144    a dictionary object with transfer portal data.
2145
2146    """
2147    now = datetime.now()
2148    url = "https://api.collegefootballdata.com/player/portal"
2149
2150    portal_df = pd.DataFrame()
2151    # row_df = pd.DataFrame()
2152
2153    if api_key is not None:
2154        real_api_key = api_key
2155        del api_key
2156    else:
2157        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
2158
2159    if real_api_key == "tigersAreAwesome":
2160        raise ValueError(
2161            "You actually need to change `cfbd_key` to your CFBD API key."
2162        )
2163    elif "Bearer " in real_api_key:
2164        pass
2165    elif "Bearer" in real_api_key:
2166        real_api_key = real_api_key.replace("Bearer", "Bearer ")
2167    else:
2168        real_api_key = "Bearer " + real_api_key
2169
2170    if season is None:
2171        # This should never happen without user tampering, but if it does,
2172        # we need to raise an error,
2173        # because the CFBD API will refuse this call without a valid season.
2174        raise SystemError(
2175            "I don't know how, I don't know why, "
2176            + "but you managed to call this function "
2177            + "while `season` was `None` (NULL),"
2178            + " and the function got to this point in the code."
2179            + "\nIf you have a GitHub account, "
2180            + "please raise an issue on this python package's GitHub page:\n"
2181            + "https://github.com/armstjc/cfbd-json-py/issues"
2182        )
2183    elif season > (now.year + 1):
2184        raise ValueError(f"`season` cannot be greater than {season}.")
2185    elif season < 2017:
2186        raise ValueError(f"Transfer portal wasn't really a thing in {season}.")
2187
2188    # URL builder
2189    ##########################################################################
2190
2191    # required by API
2192    url += f"?year={season}"
2193
2194    headers = {
2195        "Authorization": f"{real_api_key}",
2196        "accept": "application/json"
2197    }
2198
2199    response = requests.get(url, headers=headers)
2200
2201    if response.status_code == 200:
2202        pass
2203    elif response.status_code == 401:
2204        raise ConnectionRefusedError(
2205            "Could not connect. The connection was refused." +
2206            "\nHTTP Status Code 401."
2207        )
2208    else:
2209        raise ConnectionError(
2210            f"Could not connect.\nHTTP Status code {response.status_code}"
2211        )
2212
2213    json_data = response.json()
2214
2215    if return_as_dict is True:
2216        return json_data
2217
2218    portal_df = pd.json_normalize(json_data)
2219    portal_df.rename(
2220        columns={
2221            "firstName": "first_name",
2222            "lastName": "last_name",
2223            "position": "position_abv",
2224            "origin": "origin_team",
2225            "destination": "destination_team",
2226            "transferDate": "transfer_date",
2227            "rating": "rating",
2228            "stars": "stars",
2229            "eligibility": "eligibility",
2230        },
2231        inplace=True,
2232    )
2233    return portal_df
def get_cfbd_player_usage( season: int, api_key: str = None, api_key_dir: str = None, team: str = None, conference: str = None, position: str = None, player_id: int = None, exclude_garbage_time: bool = False, return_as_dict: bool = False):
399def get_cfbd_player_usage(
400    season: int,
401    api_key: str = None,
402    api_key_dir: str = None,
403    team: str = None,
404    conference: str = None,
405    position: str = None,
406    player_id: int = None,
407    exclude_garbage_time: bool = False,
408    return_as_dict: bool = False,
409):
410    """
411    Get player usage data
412    (A.K.A., the percentages for how often a player touched the ball),
413    for a given season, at the season level, from the CFBD API.
414
415    Parameters
416    ----------
417    `season` (int, optional):
418        Mandatory argument.
419        Specifies the season you want player usage data from.
420        You MUST set `season` or `team` to a non-null value for
421        this function to work. If you don't, a `ValueError()`
422        will be raised.
423
424    `api_key` (str, optional):
425        Semi-optional argument.
426        If `api_key` is null, this function will attempt to load a CFBD API key
427        from the python environment, or from a file on this computer.
428        If `api_key` is not null,
429        this function will automatically assume that the
430        inputted `api_key` is a valid CFBD API key.
431
432    `api_key_dir` (str, optional):
433        Optional argument.
434        If `api_key` is set to am empty string, this variable is ignored.
435        If `api_key_dir` is null, and `api_key` is null,
436        this function will try to find
437        a CFBD API key file in this user's home directory.
438        If `api_key_dir` is set to a string, and `api_key` is null,
439        this function will assume that `api_key_dir` is a directory,
440        and will try to find a CFBD API key file in that directory.
441
442    `team` (str, optional):
443        Semi-optional argument.
444        If you only want player usage data for a specific team,
445        set `team` to the name of the team you want player usage data from.
446        You MUST set `season` or `team` to a non-null value for
447        this function to work. If you don't, a `ValueError()`
448        will be raised.
449
450    `position` (str, optional):
451        Semi-Optional argument.
452        If you only want player usage data
453        for players who played a specific position,
454        set `position` to that position's abbreviation.
455        A list of CFBD API positions can be found
456        in the `position_abbreviation` column from
457        the pandas DataFrame that is returned
458        by calling `cfbd_json_py.draft.get_cfbd_nfl_positions()`.
459
460    `conference` (str, optional):
461        Optional argument.
462        If you only want player usage data from games
463        involving teams from a specific conference,
464        set `conference` to the abbreviation
465        of the conference you want player usage data from.
466        For a list of conferences,
467        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
468        function.
469
470    `player_id` (int, optional):
471        Optional argument.
472        If you only want player usage data for a specific player ID,
473        set this variable to the player ID
474        of the player you want player usage data from.
475
476    `exclude_garbage_time` (bool, optional):
477        Optional argument.
478        If you want to filter out plays
479        where the result of the game is largely decided,
480        set `exclude_garbage_time = True`.
481        Default behavior is that this variable is set to
482        `False` when this function is called.
483
484    `return_as_dict` (bool, semi-optional):
485        Semi-optional argument.
486        If you want this function to return
487        the data as a dictionary (read: JSON object),
488        instead of a pandas `DataFrame` object,
489        set `return_as_dict` to `True`.
490
491    Usage
492    ----------
493    ```
494    import time
495
496    from cfbd_json_py.players import get_cfbd_player_usage
497
498
499    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
500
501    if cfbd_key != "tigersAreAwesome":
502        print(
503            "Using the user's API key declared in this script " +
504            "for this example."
505        )
506
507        # Get player usage data from the 2020 CFB season.
508        print("Get player usage data from the 2020 CFB season.")
509        json_data = get_cfbd_player_usage(
510            api_key=cfbd_key,
511            season=2020
512        )
513        print(json_data)
514        time.sleep(5)
515
516        # Get player usage data for the
517        # University of Cincinnati Bearcats Football Team,
518        # during the 2020 CFB season.
519        print(
520            "Get player usage data for " +
521            "the University of Cincinnati Bearcats Football Team, " +
522            "during the 2020 CFB season."
523        )
524        json_data = get_cfbd_player_usage(
525            api_key=cfbd_key,
526            season=2020,
527            team="Cincinnati"
528        )
529        print(json_data)
530        time.sleep(5)
531
532        # Get player usage data from players who
533        # primarily played running back (RB) in the 2020 CFB season.
534        print(
535            "Get player usage data from players " +
536            "who primarily played running back (RB) in the 2020 CFB season."
537        )
538        json_data = get_cfbd_player_usage(
539            api_key=cfbd_key,
540            season=2020,
541            position="RB"
542        )
543        print(json_data)
544        time.sleep(5)
545
546        # Get player usage data from players who played on
547        # Big 10 conference (B1G) teams during the 2020 CFB Season.
548        print(
549            "Get player usage data from players who played " +
550            "on Big 10 conference (B1G) teams during the 2020 CFB Season."
551        )
552        json_data = get_cfbd_player_usage(
553            api_key=cfbd_key,
554            season=2020,
555            conference="B1G"
556        )
557        print(json_data)
558        time.sleep(5)
559
560        # Get player usage data from
561        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
562        # during the 2019 CFB season.
563        print(
564            "Get player usage data " +
565            "from former LSU Tigers quarterback Joe Burrow " +
566            "(player ID #3915511), during the 2019 CFB season."
567        )
568        json_data = get_cfbd_player_usage(
569            api_key=cfbd_key,
570            season=2019,
571            player_id=3915511
572        )
573        print(json_data)
574        time.sleep(5)
575
576        # Get player usage data from
577        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
578        # during the 2019 CFB season,
579        # but filter out plays that occurred in garbage time.
580        print(
581            "Get player usage data from " +
582            "former LSU Tigers quarterback Joe Burrow " +
583            "(player ID #3915511), during the 2019 CFB season."
584        )
585        json_data = get_cfbd_player_usage(
586            api_key=cfbd_key,
587            season=2019,
588            player_id=3915511,
589            exclude_garbage_time=True
590        )
591        print(json_data)
592        time.sleep(5)
593
594        # You can also tell this function to just return the API call as
595        # a Dictionary (read: JSON) object.
596        print(
597            "You can also tell this function to just return the API call " +
598            "as a Dictionary (read: JSON) object."
599        )
600        json_data = get_cfbd_player_usage(
601            api_key=cfbd_key,
602            season=2020,
603            team="LSU",
604            return_as_dict=True
605        )
606        print(json_data)
607
608    else:
609        # Alternatively, if the CFBD API key exists in this python environment,
610        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
611        # you could just call these functions directly,
612        # without setting the API key in the script.
613        print(
614            "Using the user's API key supposedly loaded " +
615            "into this python environment for this example."
616        )
617
618        # Get player usage data from the 2020 CFB season.
619        print("Get player usage data from the 2020 CFB season.")
620        json_data = get_cfbd_player_usage(
621            season=2020
622        )
623        print(json_data)
624        time.sleep(5)
625
626        # Get player usage data for the
627        # University of Cincinnati Bearcats Football Team,
628        # during the 2020 CFB season.
629        print(
630            "Get player usage data for " +
631            "the University of Cincinnati Bearcats Football Team, " +
632            "during the 2020 CFB season."
633        )
634        json_data = get_cfbd_player_usage(
635            season=2020,
636            team="Cincinnati"
637        )
638        print(json_data)
639        time.sleep(5)
640
641        # Get player usage data from players who
642        # primarily played running back (RB) in the 2020 CFB season.
643        print(
644            "Get player usage data from players " +
645            "who primarily played running back (RB) in the 2020 CFB season."
646        )
647        json_data = get_cfbd_player_usage(
648            season=2020,
649            position="RB"
650        )
651        print(json_data)
652        time.sleep(5)
653
654        # Get player usage data from players who played on
655        # Big 10 conference (B1G) teams during the 2020 CFB Season.
656        print(
657            "Get player usage data from players " +
658            "who played on Big 10 conference (B1G) teams " +
659            "during the 2020 CFB Season."
660        )
661        json_data = get_cfbd_player_usage(
662            season=2020,
663            conference="B1G"
664        )
665        print(json_data)
666        time.sleep(5)
667
668        # Get player usage data from
669        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
670        # during the 2019 CFB season.
671        print(
672            "Get player usage data from " +
673            "former LSU Tigers quarterback Joe Burrow " +
674            "(player ID #3915511), during the 2019 CFB season."
675        )
676        json_data = get_cfbd_player_usage(
677            season=2019,
678            player_id=3915511
679        )
680        print(json_data)
681        time.sleep(5)
682
683        # Get player usage data from
684        # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
685        # during the 2019 CFB season,
686        # but filter out plays that occurred in garbage time.
687        print(
688            "Get player usage data from " +
689            "former LSU Tigers quarterback Joe Burrow " +
690            "(player ID #3915511), during the 2019 CFB season."
691        )
692        json_data = get_cfbd_player_usage(
693            season=2019,
694            player_id=3915511,
695            exclude_garbage_time=True
696        )
697        print(json_data)
698        time.sleep(5)
699
700        # You can also tell this function to just return the API call as
701        # a Dictionary (read: JSON) object.
702        print(
703            "You can also tell this function to just return the API call " +
704            "as a Dictionary (read: JSON) object."
705        )
706        json_data = get_cfbd_player_usage(
707            season=2020,
708            team="LSU",
709            return_as_dict=True
710        )
711        print(json_data)
712
713    ```
714    Returns
715    ----------
716    A pandas `DataFrame` object with player usage data,
717    or (if `return_as_dict` is set to `True`)
718    a dictionary object with player usage data.
719
720    """
721
722    now = datetime.now()
723    players_df = pd.DataFrame()
724    # row_df = pd.DataFrame()
725    url = "https://api.collegefootballdata.com/player/usage"
726
727    ##########################################################################
728
729    if api_key is not None:
730        real_api_key = api_key
731        del api_key
732    else:
733        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
734
735    if real_api_key == "tigersAreAwesome":
736        raise ValueError(
737            "You actually need to change `cfbd_key` to your CFBD API key."
738        )
739    elif "Bearer " in real_api_key:
740        pass
741    elif "Bearer" in real_api_key:
742        real_api_key = real_api_key.replace("Bearer", "Bearer ")
743    else:
744        real_api_key = "Bearer " + real_api_key
745
746    if season is None:
747        # This should never happen without user tampering, but if it does,
748        # we need to raise an error,
749        # because the CFBD API will refuse this call without a valid season.
750        raise SystemError(
751            "I don't know how, I don't know why, "
752            + "but you managed to call this function "
753            + "while `season` was `None` (NULL),"
754            + " and the function got to this point in the code."
755            + "\nIf you have a GitHub account, "
756            + "please raise an issue on this python package's GitHub page:\n"
757            + "https://github.com/armstjc/cfbd-json-py/issues"
758        )
759    elif season > (now.year + 1):
760        raise ValueError(f"`season` cannot be greater than {season}.")
761    elif season < 1869:
762        raise ValueError("`season` cannot be less than 1869.")
763
764    gt_str = ""
765    if exclude_garbage_time is True:
766        gt_str = "true"
767    elif exclude_garbage_time is False:
768        gt_str = "false"
769
770    # URL builder
771    ##########################################################################
772
773    url += f"?year={season}"
774
775    if team is not None:
776        url += f"&team={team}"
777
778    if conference is not None:
779        url += f"&conference={conference}"
780
781    if position is not None:
782        url += f"&position={position}"
783
784    if player_id is not None:
785        url += f"&playerId={player_id}"
786    if exclude_garbage_time is not None:
787        url += f"&excludeGarbageTime={gt_str}"
788
789    headers = {
790        "Authorization": f"{real_api_key}",
791        "accept": "application/json"
792    }
793
794    response = requests.get(url, headers=headers)
795
796    if response.status_code == 200:
797        pass
798    elif response.status_code == 401:
799        raise ConnectionRefusedError(
800            "Could not connect. The connection was refused." +
801            "\nHTTP Status Code 401."
802        )
803    else:
804        raise ConnectionError(
805            f"Could not connect.\nHTTP Status code {response.status_code}"
806        )
807
808    json_data = response.json()
809
810    if return_as_dict is True:
811        return json_data
812
813    players_df = pd.json_normalize(json_data)
814    players_df.rename(
815        columns={
816            "id": "player_id",
817            "name": "player_name",
818            "position": "position_abv",
819            "team": "team_name",
820            "conference": "conference_name",
821            "usage.overall": "usage_overall",
822            "usage.pass": "usage_pass",
823            "usage.rush": "usage_rush",
824            "usage.firstDown": "usage_first_down",
825            "usage.secondDown": "usage_second_down",
826            "usage.thirdDown": "usage_third_down",
827            "usage.standardDowns": "usage_standard_downs",
828            "usage.passingDowns": "usage_passing_downs",
829        },
830        inplace=True,
831    )
832    return players_df

Get player usage data (A.K.A., the percentages for how often a player touched the ball), for a given season, at the season level, from the CFBD API.

Parameters

season (int, optional): Mandatory argument. Specifies the season you want player usage data from. You MUST set season or team to a non-null value for this function to work. If you don't, a ValueError() will be raised.

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.

team (str, optional): Semi-optional argument. If you only want player usage data for a specific team, set team to the name of the team you want player usage data from. You MUST set season or team to a non-null value for this function to work. If you don't, a ValueError() will be raised.

position (str, optional): Semi-Optional argument. If you only want player usage data for players who played a specific position, set position to that position's abbreviation. A list of CFBD API positions can be found in the position_abbreviation column from the pandas DataFrame that is returned by calling cfbd_json_py.draft.get_cfbd_nfl_positions().

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

player_id (int, optional): Optional argument. If you only want player usage data for a specific player ID, set this variable to the player ID of the player you want player usage data from.

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.

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.players import get_cfbd_player_usage


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 player usage data from the 2020 CFB season.
    print("Get player usage data from the 2020 CFB season.")
    json_data = get_cfbd_player_usage(
        api_key=cfbd_key,
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data for the
    # University of Cincinnati Bearcats Football Team,
    # during the 2020 CFB season.
    print(
        "Get player usage data for " +
        "the University of Cincinnati Bearcats Football Team, " +
        "during the 2020 CFB season."
    )
    json_data = get_cfbd_player_usage(
        api_key=cfbd_key,
        season=2020,
        team="Cincinnati"
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from players who
    # primarily played running back (RB) in the 2020 CFB season.
    print(
        "Get player usage data from players " +
        "who primarily played running back (RB) in the 2020 CFB season."
    )
    json_data = get_cfbd_player_usage(
        api_key=cfbd_key,
        season=2020,
        position="RB"
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from players who played on
    # Big 10 conference (B1G) teams during the 2020 CFB Season.
    print(
        "Get player usage data from players who played " +
        "on Big 10 conference (B1G) teams during the 2020 CFB Season."
    )
    json_data = get_cfbd_player_usage(
        api_key=cfbd_key,
        season=2020,
        conference="B1G"
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from
    # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
    # during the 2019 CFB season.
    print(
        "Get player usage data " +
        "from former LSU Tigers quarterback Joe Burrow " +
        "(player ID #3915511), during the 2019 CFB season."
    )
    json_data = get_cfbd_player_usage(
        api_key=cfbd_key,
        season=2019,
        player_id=3915511
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from
    # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
    # during the 2019 CFB season,
    # but filter out plays that occurred in garbage time.
    print(
        "Get player usage data from " +
        "former LSU Tigers quarterback Joe Burrow " +
        "(player ID #3915511), during the 2019 CFB season."
    )
    json_data = get_cfbd_player_usage(
        api_key=cfbd_key,
        season=2019,
        player_id=3915511,
        exclude_garbage_time=True
    )
    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_player_usage(
        api_key=cfbd_key,
        season=2020,
        team="LSU",
        return_as_dict=True
    )
    print(json_data)

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

    # Get player usage data from the 2020 CFB season.
    print("Get player usage data from the 2020 CFB season.")
    json_data = get_cfbd_player_usage(
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data for the
    # University of Cincinnati Bearcats Football Team,
    # during the 2020 CFB season.
    print(
        "Get player usage data for " +
        "the University of Cincinnati Bearcats Football Team, " +
        "during the 2020 CFB season."
    )
    json_data = get_cfbd_player_usage(
        season=2020,
        team="Cincinnati"
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from players who
    # primarily played running back (RB) in the 2020 CFB season.
    print(
        "Get player usage data from players " +
        "who primarily played running back (RB) in the 2020 CFB season."
    )
    json_data = get_cfbd_player_usage(
        season=2020,
        position="RB"
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from players who played on
    # Big 10 conference (B1G) teams during the 2020 CFB Season.
    print(
        "Get player usage data from players " +
        "who played on Big 10 conference (B1G) teams " +
        "during the 2020 CFB Season."
    )
    json_data = get_cfbd_player_usage(
        season=2020,
        conference="B1G"
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from
    # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
    # during the 2019 CFB season.
    print(
        "Get player usage data from " +
        "former LSU Tigers quarterback Joe Burrow " +
        "(player ID #3915511), during the 2019 CFB season."
    )
    json_data = get_cfbd_player_usage(
        season=2019,
        player_id=3915511
    )
    print(json_data)
    time.sleep(5)

    # Get player usage data from
    # former LSU Tigers quarterback Joe Burrow (player ID #3915511),
    # during the 2019 CFB season,
    # but filter out plays that occurred in garbage time.
    print(
        "Get player usage data from " +
        "former LSU Tigers quarterback Joe Burrow " +
        "(player ID #3915511), during the 2019 CFB season."
    )
    json_data = get_cfbd_player_usage(
        season=2019,
        player_id=3915511,
        exclude_garbage_time=True
    )
    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_player_usage(
        season=2020,
        team="LSU",
        return_as_dict=True
    )
    print(json_data)

Returns

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

def get_cfbd_returning_production( api_key: str = None, api_key_dir: str = None, season: int = None, team: str = None, conference: str = None, return_as_dict: bool = False):
 835def get_cfbd_returning_production(
 836    api_key: str = None,
 837    api_key_dir: str = None,
 838    season: int = None,
 839    team: str = None,
 840    # `season` or `team` must be specified.
 841    conference: str = None,
 842    return_as_dict: bool = False,
 843):
 844    """
 845    Get data from the CFBD API
 846    on how much returning production a team has going into a CFB season.
 847
 848    Parameters
 849    ----------
 850
 851    `api_key` (str, optional):
 852        Semi-optional argument.
 853        If `api_key` is null, this function will attempt to load a CFBD API key
 854        from the python environment, or from a file on this computer.
 855        If `api_key` is not null,
 856        this function will automatically assume that the
 857        inputted `api_key` is a valid CFBD API key.
 858
 859    `api_key_dir` (str, optional):
 860        Optional argument.
 861        If `api_key` is set to am empty string, this variable is ignored.
 862        If `api_key_dir` is null, and `api_key` is null,
 863        this function will try to find
 864        a CFBD API key file in this user's home directory.
 865        If `api_key_dir` is set to a string, and `api_key` is null,
 866        this function will assume that `api_key_dir` is a directory,
 867        and will try to find a CFBD API key file in that directory.
 868
 869    `season` (int, optional):
 870        Semi-optional argument.
 871        Specifies the season you want team PPA data from.
 872        You MUST set `season` or `team` to a non-null value for
 873        this function to work. If you don't, a `ValueError()`
 874        will be raised.
 875
 876    `team` (str, optional):
 877        Semi-optional argument.
 878        If you only want team PPA data for a specific team,
 879        set `team` to the name of the team you want team PPA data from.
 880        You MUST set `season` or `team` to a non-null value for
 881        this function to work. If you don't, a `ValueError()`
 882        will be raised.
 883
 884    `conference` (str, optional):
 885        Optional argument.
 886        If you only want team PPA data from games
 887        involving teams from a specific conference,
 888        set `conference` to the abbreviation
 889        of the conference you want team PPA data from.
 890        For a list of conferences,
 891        use the `cfbd_json_py.conferences.get_cfbd_conference_info()`
 892        function.
 893
 894    `return_as_dict` (bool, semi-optional):
 895        Semi-optional argument.
 896        If you want this function to return
 897        the data as a dictionary (read: JSON object),
 898        instead of a pandas `DataFrame` object,
 899        set `return_as_dict` to `True`.
 900
 901    Usage
 902    ----------
 903    ```
 904    import time
 905
 906    from cfbd_json_py.players import get_cfbd_returning_production
 907
 908
 909    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
 910
 911    if cfbd_key != "tigersAreAwesome":
 912        print(
 913            "Using the user's API key declared in this script " +
 914            "for this example."
 915        )
 916
 917        # Get returning production
 918        # for teams who competed in the 2020 CFB season.
 919        print(
 920            "Get returning production for teams " +
 921            "who competed in the 2020 CFB season."
 922        )
 923        json_data = get_cfbd_returning_production(
 924            api_key=cfbd_key,
 925            season=2020
 926        )
 927        print(json_data)
 928        time.sleep(5)
 929
 930        # Get historical returning production
 931        # for the Ohio Bobcats Football Team.
 932        print(
 933            "Get historical returning production " +
 934            "for the Ohio Bobcats Football Team."
 935        )
 936        json_data = get_cfbd_returning_production(
 937            api_key=cfbd_key,
 938            team="Ohio"
 939        )
 940        print(json_data)
 941        time.sleep(5)
 942
 943        # Get returning production for the 2019 LSU Tigers.
 944        print("Get returning production for the 2019 LSU Tigers.")
 945        json_data = get_cfbd_returning_production(
 946            api_key=cfbd_key,
 947            season=2019,
 948            team="LSU"
 949        )
 950        print(json_data)
 951        time.sleep(5)
 952
 953        # Get returning production for Maryland,
 954        # for seasons where Maryland is a member
 955        # of the Big 10 (B1G) Conference.
 956        print(
 957            "Get returning production for Maryland, " +
 958            "for seasons where Maryland is a member " +
 959            "of the Big 10 (B1G) Conference."
 960        )
 961        json_data = get_cfbd_returning_production(
 962            api_key=cfbd_key,
 963            team="Maryland",
 964            conference="B1G"
 965        )
 966        print(json_data)
 967        time.sleep(5)
 968
 969        # You can also tell this function to just return the API call as
 970        # a Dictionary (read: JSON) object.
 971        print(
 972            "You can also tell this function to just return the API call " +
 973            "as a Dictionary (read: JSON) object."
 974        )
 975        json_data = get_cfbd_returning_production(
 976            api_key=cfbd_key,
 977            season=2020,
 978            team="LSU",
 979            return_as_dict=True
 980        )
 981        print(json_data)
 982
 983    else:
 984        # Alternatively, if the CFBD API key exists in this python environment,
 985        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
 986        # you could just call these functions directly,
 987        # without setting the API key in the script.
 988        print(
 989            "Using the user's API key supposedly loaded " +
 990            "into this python environment for this example."
 991        )
 992
 993        # Get returning production
 994        # for teams who competed in the 2020 CFB season.
 995        print(
 996            "Get returning production for teams " +
 997            "who competed in the 2020 CFB season."
 998        )
 999        json_data = get_cfbd_returning_production(
1000            season=2020
1001        )
1002        print(json_data)
1003        time.sleep(5)
1004
1005        # Get historical returning production
1006        # for the Ohio Bobcats Football Team.
1007        print(
1008            "Get historical returning production " +
1009            "for the Ohio Bobcats Football Team."
1010        )
1011        json_data = get_cfbd_returning_production(
1012            team="Ohio"
1013        )
1014        print(json_data)
1015        time.sleep(5)
1016
1017        # Get returning production for the 2019 LSU Tigers.
1018        print("Get returning production for the 2019 LSU Tigers.")
1019        json_data = get_cfbd_returning_production(
1020            season=2019,
1021            team="LSU"
1022        )
1023        print(json_data)
1024        time.sleep(5)
1025
1026        # Get returning production for Maryland,
1027        # for seasons where Maryland is a member
1028        # of the Big 10 (B1G) Conference.
1029        print(
1030            "Get returning production for Maryland, " +
1031            "for seasons where Maryland is a member " +
1032            "of the Big 10 (B1G) Conference."
1033        )
1034        json_data = get_cfbd_returning_production(
1035            team="Maryland",
1036            conference="B1G"
1037        )
1038        print(json_data)
1039        time.sleep(5)
1040
1041        # You can also tell this function to just return the API call as
1042        # a Dictionary (read: JSON) object.
1043        print(
1044            "You can also tell this function to just return the API call " +
1045            "as a Dictionary (read: JSON) object."
1046        )
1047        json_data = get_cfbd_returning_production(
1048            season=2020,
1049            team="LSU",
1050            return_as_dict=True
1051        )
1052        print(json_data)
1053
1054
1055    ```
1056    Returns
1057    ----------
1058    A pandas `DataFrame` object with returning production data,
1059    or (if `return_as_dict` is set to `True`)
1060    a dictionary object with returning production data.
1061
1062    """
1063    now = datetime.now()
1064    team_df = pd.DataFrame()
1065    # row_df = pd.DataFrame()
1066    url = "https://api.collegefootballdata.com/player/returning"
1067
1068    ##########################################################################
1069
1070    if api_key is not None:
1071        real_api_key = api_key
1072        del api_key
1073    else:
1074        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1075
1076    if real_api_key == "tigersAreAwesome":
1077        raise ValueError(
1078            "You actually need to change `cfbd_key` to your CFBD API key."
1079        )
1080    elif "Bearer " in real_api_key:
1081        pass
1082    elif "Bearer" in real_api_key:
1083        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1084    else:
1085        real_api_key = "Bearer " + real_api_key
1086
1087    if season is None and team is None:
1088        raise ValueError(
1089            "To use this function, `season` and/or `team` must be set to a "
1090            + "non-null variable."
1091        )
1092
1093    if season is None:
1094        # Rare, but in this endpoint,
1095        # you don't need to input the season.
1096        pass
1097    elif season > (now.year + 1):
1098        raise ValueError(f"`season` cannot be greater than {season}.")
1099    elif season < 1869:
1100        raise ValueError("`season` cannot be less than 1869.")
1101
1102    # URL Builder
1103    ##########################################################################
1104
1105    url_elements = 0
1106
1107    if season is not None and url_elements == 0:
1108        url += f"?year={season}"
1109        url_elements += 1
1110    elif season is not None:
1111        url += f"&year={season}"
1112        url_elements += 1
1113
1114    if team is not None and url_elements == 0:
1115        url += f"?team={team}"
1116        url_elements += 1
1117    elif team is not None:
1118        url += f"&team={team}"
1119        url_elements += 1
1120
1121    if conference is not None and url_elements == 0:
1122        url += f"?conference={conference}"
1123        url_elements += 1
1124    elif conference is not None:
1125        url += f"&conference={conference}"
1126        url_elements += 1
1127
1128    headers = {
1129        "Authorization": f"{real_api_key}",
1130        "accept": "application/json"
1131    }
1132
1133    response = requests.get(url, headers=headers)
1134
1135    if response.status_code == 200:
1136        pass
1137    elif response.status_code == 401:
1138        raise ConnectionRefusedError(
1139            "Could not connect. The connection was refused." +
1140            "\nHTTP Status Code 401."
1141        )
1142    else:
1143        raise ConnectionError(
1144            f"Could not connect.\nHTTP Status code {response.status_code}"
1145        )
1146
1147    json_data = response.json()
1148
1149    if return_as_dict is True:
1150        return json_data
1151
1152    team_df = pd.json_normalize(json_data)
1153    team_df.rename(
1154        columns={
1155            "team": "team_name",
1156            "conference": "conference_name",
1157            "totalPPA": "returning_total_ppa",
1158            "totalPassingPPA": "returning_total_passing_ppa",
1159            "totalReceivingPPA": "returning_total_receiving_ppa",
1160            "totalRushingPPA": "returning_total_rush_ppa",
1161            "percentPPA": "returning_ppa_percent",
1162            "percentPassingPPA": "returning_percent_passing_ppa",
1163            "percentReceivingPPA": "returning_percent_receiving_ppa",
1164            "percentRushingPPA": "returning_percent_rushing_ppa",
1165            "usage": "returning_usage",
1166            "passingUsage": "returning_passing_usage",
1167            "receivingUsage": "returning_receiving_usage",
1168            "rushingUsage": "returning_rushing_usage",
1169        },
1170        inplace=True,
1171    )
1172    return team_df

Get data from the CFBD API on how much returning production a team has going into a CFB season.

Parameters

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

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

season (int, optional): Semi-optional argument. Specifies the season you want team PPA data from. You MUST set season or team to a non-null value for this function to work. If you don't, a ValueError() will be raised.

team (str, optional): Semi-optional argument. If you only want team PPA data for a specific team, set team to the name of the team you want team PPA data from. You MUST set season or team to a non-null value for this function to work. If you don't, a ValueError() will be raised.

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

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

Usage

import time

from cfbd_json_py.players import get_cfbd_returning_production


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 returning production
    # for teams who competed in the 2020 CFB season.
    print(
        "Get returning production for teams " +
        "who competed in the 2020 CFB season."
    )
    json_data = get_cfbd_returning_production(
        api_key=cfbd_key,
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get historical returning production
    # for the Ohio Bobcats Football Team.
    print(
        "Get historical returning production " +
        "for the Ohio Bobcats Football Team."
    )
    json_data = get_cfbd_returning_production(
        api_key=cfbd_key,
        team="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get returning production for the 2019 LSU Tigers.
    print("Get returning production for the 2019 LSU Tigers.")
    json_data = get_cfbd_returning_production(
        api_key=cfbd_key,
        season=2019,
        team="LSU"
    )
    print(json_data)
    time.sleep(5)

    # Get returning production for Maryland,
    # for seasons where Maryland is a member
    # of the Big 10 (B1G) Conference.
    print(
        "Get returning production for Maryland, " +
        "for seasons where Maryland is a member " +
        "of the Big 10 (B1G) Conference."
    )
    json_data = get_cfbd_returning_production(
        api_key=cfbd_key,
        team="Maryland",
        conference="B1G"
    )
    print(json_data)
    time.sleep(5)

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

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

    # Get returning production
    # for teams who competed in the 2020 CFB season.
    print(
        "Get returning production for teams " +
        "who competed in the 2020 CFB season."
    )
    json_data = get_cfbd_returning_production(
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get historical returning production
    # for the Ohio Bobcats Football Team.
    print(
        "Get historical returning production " +
        "for the Ohio Bobcats Football Team."
    )
    json_data = get_cfbd_returning_production(
        team="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get returning production for the 2019 LSU Tigers.
    print("Get returning production for the 2019 LSU Tigers.")
    json_data = get_cfbd_returning_production(
        season=2019,
        team="LSU"
    )
    print(json_data)
    time.sleep(5)

    # Get returning production for Maryland,
    # for seasons where Maryland is a member
    # of the Big 10 (B1G) Conference.
    print(
        "Get returning production for Maryland, " +
        "for seasons where Maryland is a member " +
        "of the Big 10 (B1G) Conference."
    )
    json_data = get_cfbd_returning_production(
        team="Maryland",
        conference="B1G"
    )
    print(json_data)
    time.sleep(5)

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


Returns

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

def get_cfbd_player_season_stats( season: int, api_key: str = None, api_key_dir: str = None, team: str = None, conference: str = None, start_week: int = None, end_week: int = None, season_type: str = 'both', stat_category: str = None, return_as_dict: bool = False):
1175def get_cfbd_player_season_stats(
1176    season: int,
1177    api_key: str = None,
1178    api_key_dir: str = None,
1179    team: str = None,
1180    conference: str = None,
1181    start_week: int = None,
1182    end_week: int = None,
1183    season_type: str = "both",  # "regular", "postseason", or "both"
1184    stat_category: str = None,
1185    return_as_dict: bool = False,
1186):
1187    """
1188    Get player season stats,
1189    or the stats of players in a specific time frame, from the CFBD API.
1190
1191    Parameters
1192    ----------
1193    `season` (int, mandatory):
1194        Required argument.
1195        Specifies the season you want CFB player season stats from.
1196        This must be specified, otherwise this package, and by extension
1197        the CFBD API, will not accept
1198        the request to get CFB player season stats.
1199
1200    `api_key` (str, optional):
1201        Semi-optional argument.
1202        If `api_key` is null, this function will attempt to load a CFBD API key
1203        from the python environment, or from a file on this computer.
1204        If `api_key` is not null,
1205        this function will automatically assume that the
1206        inputted `api_key` is a valid CFBD API key.
1207
1208    `api_key_dir` (str, optional):
1209        Optional argument.
1210        If `api_key` is set to am empty string, this variable is ignored.
1211        If `api_key_dir` is null, and `api_key` is null,
1212        this function will try to find
1213        a CFBD API key file in this user's home directory.
1214        If `api_key_dir` is set to a string, and `api_key` is null,
1215        this function will assume that `api_key_dir` is a directory,
1216        and will try to find a CFBD API key file in that directory.
1217
1218    `team` (str, optional):
1219        Optional argument.
1220        If you only want CFB player season stats for a team,
1221        regardless if they are the home/away team,
1222        set `team` to the name of the team
1223        you want CFB player season stats from.
1224
1225    `conference` (str, optional):
1226        Optional argument.
1227        If you only want player season stats from games
1228        involving teams a specific conference,
1229        set `conference` to the abbreviation
1230        of the conference you want stats from.
1231
1232    `start_week` (int, semi-optional):
1233        Optional argument.
1234        If you only want player stats for a range of weeks,
1235        set `start_week` and `end_week` to
1236        the range of weeks you want season-level data for.
1237
1238    `end_week` (int, semi-optional):
1239        Optional argument.
1240        If you only want player stats for a range of weeks,
1241        set `start_week` and `end_week` to
1242        the range of weeks you want season-level data for.
1243
1244    **NOTE**: If the following conditions are `True`, a `ValueError()`
1245    will be raised when calling this function:
1246    - `start_week < 0`
1247    - `end_week < 0`
1248    - `start_week is not None and end_week is None`
1249        (will be changed in a future version)
1250    - `start_week is None and end_week is not None`
1251        (will be changed in a future version)
1252    - `end_week < start_week`
1253    - `end_week = start_week`
1254
1255    `season_type` (str, semi-optional):
1256        Semi-optional argument.
1257        By default, this will be set to "regular", for the CFB regular season.
1258        If you want CFB media information for non-regular season games,
1259        set `season_type` to "postseason".
1260        If you want ***both*** regular
1261        and postseason stats, set `season_type = "both"`.
1262        If `season_type` is set to anything but "regular",
1263        "postseason",  or "both", a `ValueError()` will be raised.
1264
1265    `stat_category` (str, optional):
1266        Optional argument.
1267        If only want stats for a specific stat category,
1268        set this variable to that category.
1269
1270        Valid inputs are:
1271        - `passing`
1272        - `rushing`
1273        - `receiving`
1274        - `fumbles`
1275        - `defensive`
1276        - `interceptions`
1277        - `punting`
1278        - `kicking`
1279        - `kickReturns`
1280        - `puntReturns`
1281
1282    `return_as_dict` (bool, semi-optional):
1283        Semi-optional argument.
1284        If you want this function to return
1285        the data as a dictionary (read: JSON object),
1286        instead of a pandas `DataFrame` object,
1287        set `return_as_dict` to `True`.
1288
1289    Usage
1290    ----------
1291    ```
1292    import time
1293
1294    from cfbd_json_py.players import get_cfbd_player_season_stats
1295
1296
1297    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
1298
1299    if cfbd_key != "tigersAreAwesome":
1300        print(
1301            "Using the user's API key declared in this script " +
1302            "for this example."
1303        )
1304
1305        # Get player season stats for
1306        # the Ohio Bobcats Football team in the 2020 CFB season.
1307        print(
1308            "Get player season stats for " +
1309            "the Ohio Bobcats Football team in the 2020 CFB season."
1310        )
1311        json_data = get_cfbd_player_season_stats(
1312            api_key=cfbd_key,
1313            season=2020,
1314            team="Ohio"
1315        )
1316        print(json_data)
1317        time.sleep(5)
1318
1319        # Get player season stats for teams who competed in
1320        # the Southeastern conference (SEC) in the 2023 CFB season.
1321        print(
1322            "Get player season stats for teams who competed " +
1323            "in the Southeastern conference (SEC) in the 2023 CFB season."
1324        )
1325        json_data = get_cfbd_player_season_stats(
1326            api_key=cfbd_key,
1327            season=2020,
1328            conference="SEC"
1329        )
1330        print(json_data)
1331        time.sleep(5)
1332
1333        # Get player season stats for teams who competed in
1334        # the Southeastern conference (SEC) in the 2023 CFB season,
1335        # but only between weeks 1 and 5.
1336        print(
1337            "Get player season stats for teams who competed " +
1338            "in the Southeastern conference (SEC) in the 2023 CFB season."
1339        )
1340        json_data = get_cfbd_player_season_stats(
1341            api_key=cfbd_key,
1342            season=2020,
1343            conference="SEC",
1344            start_week=1,
1345            end_week=5
1346        )
1347        print(json_data)
1348        time.sleep(5)
1349
1350        # Get player season stats for the 2020 CFB season.
1351        print("Get player season stats for the 2020 CFB season.")
1352        json_data = get_cfbd_player_season_stats(
1353            api_key=cfbd_key,
1354            season=2020
1355        )
1356        print(json_data)
1357        time.sleep(5)
1358
1359        # Get player season stats for
1360        # the Ohio Bobcats Football team in the 2022 CFB season,
1361        # but only use regular season games when calculating season stats.
1362        print(
1363            "Get player season stats for the Ohio Bobcats Football team " +
1364            "in the 2020 CFB season, but only use regular season games " +
1365            "when calculating season stats."
1366        )
1367        json_data = get_cfbd_player_season_stats(
1368            api_key=cfbd_key,
1369            season=2022,
1370            team="Ohio",
1371            season_type="regular"
1372        )
1373        print(json_data)
1374        time.sleep(5)
1375
1376        # Get passing stats for teams who competed in
1377        # the Southeastern conference (SEC) in the 2023 CFB season.
1378        print(
1379            "Get passing stats for teams who competed " +
1380            "in the Southeastern conference (SEC) in the 2023 CFB season."
1381        )
1382        json_data = get_cfbd_player_season_stats(
1383            api_key=cfbd_key,
1384            season=2020,
1385            conference="SEC",
1386            stat_category="passing"
1387        )
1388        print(json_data)
1389        time.sleep(5)
1390
1391        # You can also tell this function to just return the API call as
1392        # a Dictionary (read: JSON) object.
1393        print(
1394            "You can also tell this function to just return the API call " +
1395            "as a Dictionary (read: JSON) object."
1396        )
1397        json_data = get_cfbd_player_season_stats(
1398            api_key=cfbd_key,
1399            season=2020,
1400            team="LSU",
1401            stat_category="kicking",
1402            return_as_dict=True
1403        )
1404        print(json_data)
1405
1406    else:
1407        # Alternatively, if the CFBD API key exists in this python environment,
1408        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
1409        # you could just call these functions directly,
1410        # without setting the API key in the script.
1411        print(
1412            "Using the user's API key supposedly loaded " +
1413            "into this python environment for this example."
1414        )
1415
1416        # Get player season stats for
1417        # the Ohio Bobcats Football team in the 2020 CFB season.
1418        print(
1419            "Get player season stats for " +
1420            "the Ohio Bobcats Football team in the 2020 CFB season."
1421        )
1422        json_data = get_cfbd_player_season_stats(
1423            season=2020,
1424            team="Ohio"
1425        )
1426        print(json_data)
1427        time.sleep(5)
1428
1429        # Get player season stats for teams who competed in
1430        # the Southeastern conference (SEC) in the 2023 CFB season.
1431        print(
1432            "Get player season stats for teams who competed " +
1433            "in the Southeastern conference (SEC) in the 2023 CFB season."
1434        )
1435        json_data = get_cfbd_player_season_stats(
1436            season=2020,
1437            conference="SEC"
1438        )
1439        print(json_data)
1440        time.sleep(5)
1441
1442        # Get player season stats for teams who competed in
1443        # the Southeastern conference (SEC) in the 2023 CFB season,
1444        # but only between weeks 1 and 5.
1445        print(
1446            "Get player season stats for teams who competed " +
1447            "in the Southeastern conference (SEC) in the 2023 CFB season."
1448        )
1449        json_data = get_cfbd_player_season_stats(
1450            season=2020,
1451            conference="SEC",
1452            start_week=1,
1453            end_week=5
1454        )
1455        print(json_data)
1456        time.sleep(5)
1457
1458        # Get player season stats for the 2020 CFB season.
1459        print("Get player season stats for the 2020 CFB season.")
1460        json_data = get_cfbd_player_season_stats(
1461            season=2020
1462        )
1463        print(json_data)
1464        time.sleep(5)
1465
1466        # Get player season stats for
1467        # the Ohio Bobcats Football team in the 2022 CFB season,
1468        # but only use regular season games when calculating season stats.
1469        print(
1470            "Get player season stats for the Ohio Bobcats Football team " +
1471            "in the 2020 CFB season, but only use regular season games " +
1472            "when calculating season stats."
1473        )
1474        json_data = get_cfbd_player_season_stats(
1475            season=2022,
1476            team="Ohio",
1477            season_type="regular"
1478        )
1479        print(json_data)
1480        time.sleep(5)
1481
1482        # Get passing stats for teams who competed in
1483        # the Southeastern conference (SEC) in the 2023 CFB season.
1484        print(
1485            "Get passing stats for teams who competed " +
1486            "in the Southeastern conference (SEC) in the 2023 CFB season."
1487        )
1488        json_data = get_cfbd_player_season_stats(
1489            season=2020,
1490            conference="SEC",
1491            stat_category="passing"
1492        )
1493        print(json_data)
1494        time.sleep(5)
1495
1496        # You can also tell this function to just return the API call as
1497        # a Dictionary (read: JSON) object.
1498        print(
1499            "You can also tell this function to just return the API call " +
1500            "as a Dictionary (read: JSON) object."
1501        )
1502        json_data = get_cfbd_player_season_stats(
1503            season=2020,
1504            team="LSU",
1505            stat_category="kicking",
1506            return_as_dict=True
1507        )
1508        print(json_data)
1509
1510    ```
1511    Returns
1512    ----------
1513    A pandas `DataFrame` object with
1514    a list of players who matched the search string,
1515    or (if `return_as_dict` is set to `True`)
1516    a dictionary object with a list of players who matched the search string.
1517
1518    """
1519
1520    rebuilt_json = {}
1521    rebuilt_json_list = []
1522
1523    stat_columns = [
1524        "season",
1525        "team_name",
1526        "team_conference",
1527        "player_id",
1528        "player_name",
1529        # PASS
1530        "passing_COMP",
1531        "passing_ATT",
1532        "passing_COMP%",
1533        "passing_YDS",
1534        "passing_AVG",
1535        "passing_TD",
1536        "passing_INT",
1537        # RUSH
1538        "rushing_CAR",
1539        "rushing_YDS",
1540        "rushing_AVG",
1541        "rushing_TD",
1542        "rushing_LONG",
1543        # REC
1544        "receiving_REC",
1545        "receiving_YDS",
1546        "receiving_AVG",
1547        "receiving_TD",
1548        "receiving_LONG",
1549        # FUM
1550        "fumbles_FUM",
1551        "fumbles_LOST",
1552        "fumbles_REC",
1553        # DEFENSE
1554        "defensive_TOT",
1555        "defensive_SOLO",
1556        "defensive_TFL",
1557        "defensive_QB HUR",
1558        "defensive_SACKS",
1559        "defensive_PD",
1560        "defensive_TD",
1561        # INT
1562        "interceptions_INT",
1563        "interceptions_YDS",
1564        "interceptions_TD",
1565        # PUNT
1566        "punting_NO",
1567        "punting_YDS",
1568        "punting_AVG",
1569        "punting_TB",
1570        "punting_In 20",
1571        "punting_LONG",
1572        # KICK
1573        "kicking_FGM",
1574        "kicking_FGA",
1575        "kicking_FG%",
1576        "kicking_LONG",
1577        "kicking_XPM",
1578        "kicking_XPA",
1579        "kicking_XP%",
1580        # KR
1581        "kickReturns_NO",
1582        "kickReturns_YDS",
1583        "kickReturns_AVG",
1584        "kickReturns_TD",
1585        "kickReturns_LONG",
1586        # PR
1587        "puntReturns_NO",
1588        "puntReturns_YDS",
1589        "puntReturns_AVG",
1590        "puntReturns_TD",
1591        "puntReturns_LONG",
1592    ]
1593
1594    now = datetime.now()
1595    url = "https://api.collegefootballdata.com/stats/player/season"
1596
1597    final_df = pd.DataFrame()
1598
1599    if api_key is not None:
1600        real_api_key = api_key
1601        del api_key
1602    else:
1603        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
1604
1605    if real_api_key == "tigersAreAwesome":
1606        raise ValueError(
1607            "You actually need to change `cfbd_key` to your CFBD API key."
1608        )
1609    elif "Bearer " in real_api_key:
1610        pass
1611    elif "Bearer" in real_api_key:
1612        real_api_key = real_api_key.replace("Bearer", "Bearer ")
1613    else:
1614        real_api_key = "Bearer " + real_api_key
1615
1616    if season is None:
1617        # This should never happen without user tampering, but if it does,
1618        # we need to raise an error,
1619        # because the CFBD API will refuse this call without a valid season.
1620        raise SystemError(
1621            "I don't know how, I don't know why, "
1622            + "but you managed to call this function "
1623            + "while `season` was `None` (NULL),"
1624            + " and the function got to this point in the code."
1625            + "\nIf you have a GitHub account, "
1626            + "please raise an issue on this python package's GitHub page:\n"
1627            + "https://github.com/armstjc/cfbd-json-py/issues"
1628        )
1629    elif season > (now.year + 1):
1630        raise ValueError(f"`season` cannot be greater than {season}.")
1631    elif season < 1869:
1632        raise ValueError("`season` cannot be less than 1869.")
1633
1634    if (
1635        season_type != "regular"
1636        and season_type != "postseason"
1637        and season_type != "both"
1638    ):
1639        raise ValueError(
1640            '`season_type` must be set to either "regular" or '
1641            + '"postseason" for this function to work.'
1642        )
1643
1644    filter_by_stat_category = False
1645
1646    if stat_category is None:
1647        pass
1648    elif stat_category == "passing":
1649        filter_by_stat_category = True
1650    elif stat_category == "rushing":
1651        filter_by_stat_category = True
1652    elif stat_category == "receiving":
1653        filter_by_stat_category = True
1654    elif stat_category == "fumbles":
1655        filter_by_stat_category = True
1656    elif stat_category == "passing":
1657        filter_by_stat_category = True
1658    elif stat_category == "defensive":
1659        filter_by_stat_category = True
1660    elif stat_category == "interceptions":
1661        filter_by_stat_category = True
1662    elif stat_category == "punting":
1663        filter_by_stat_category = True
1664    elif stat_category == "kicking":
1665        filter_by_stat_category = True
1666    elif stat_category == "kickReturns":
1667        filter_by_stat_category = True
1668    elif stat_category == "puntReturns":
1669        filter_by_stat_category = True
1670    else:
1671        raise ValueError(
1672            "Invalid input for `stat_category`."
1673            + "\nValid inputs are:"
1674            + """
1675            - `passing`
1676            - `rushing`
1677            - `receiving`
1678            - `fumbles`
1679            - `defensive`
1680            - `interceptions`
1681            - `punting`
1682            - `kicking`
1683            - `kickReturns`
1684            - `puntReturns`
1685            """
1686        )
1687
1688    if start_week is not None and end_week is not None:
1689        if start_week > end_week:
1690            raise ValueError("`start_week` cannot be greater than `end_week`.")
1691        elif start_week == end_week:
1692            raise ValueError(
1693                "`start_week` cannot be equal to `end_week`."
1694                + "\n Use "
1695                + "`cfbd_json_py.games.get_cfbd_player_game_stats()` instead "
1696                + "if you want player stats for a specific week in ."
1697            )
1698        elif start_week < 0:
1699            raise ValueError("`start_week` cannot be less than 0.")
1700        elif end_week < 0:
1701            raise ValueError("`end_week` cannot be less than 0.")
1702
1703    if filter_by_stat_category is True:
1704        pass
1705
1706    # URL builder
1707    ##########################################################################
1708
1709    # Required by the API
1710    url += f"?year={season}"
1711
1712    if team is not None:
1713        url += f"&team={team}"
1714
1715    if conference is not None:
1716        url += f"&conference={conference}"
1717
1718    if season_type is not None:
1719        url += f"&seasonType={season_type}"
1720
1721    if stat_category is not None:
1722        url += f"&category={stat_category}"
1723
1724    if start_week is not None:
1725        url += f"&startWeek={start_week}"
1726
1727    if end_week is not None:
1728        url += f"&endWeek={end_week}"
1729
1730    headers = {
1731        "Authorization": f"{real_api_key}",
1732        "accept": "application/json"
1733    }
1734
1735    response = requests.get(url, headers=headers)
1736
1737    if response.status_code == 200:
1738        pass
1739    elif response.status_code == 401:
1740        raise ConnectionRefusedError(
1741            "Could not connect. The connection was refused." +
1742            "\nHTTP Status Code 401."
1743        )
1744    else:
1745        raise ConnectionError(
1746            f"Could not connect.\nHTTP Status code {response.status_code}"
1747        )
1748
1749    json_data = response.json()
1750
1751    if return_as_dict is True:
1752        return json_data
1753
1754    for player in json_data:
1755        player_id = player["playerId"]
1756        player_name = player["player"]
1757        team_name = player["team"]
1758        team_conference = player["conference"]
1759
1760        if rebuilt_json.get(player_id) is None:
1761            rebuilt_json[player_id] = {}
1762
1763        stat_category = player["category"]
1764        stat_type = player["statType"]
1765        stat_name = f"{stat_category}_{stat_type}"
1766
1767        stat_value = player["stat"]
1768
1769        rebuilt_json[player_id]["player_id"] = player_id
1770        rebuilt_json[player_id]["player_name"] = player_name
1771        rebuilt_json[player_id]["team_name"] = team_name
1772        rebuilt_json[player_id]["team_conference"] = team_conference
1773        rebuilt_json[player_id][stat_name] = stat_value
1774
1775    for _, value in rebuilt_json.items():
1776        rebuilt_json_list.append(value)
1777
1778    final_df = pd.DataFrame(rebuilt_json_list)
1779    final_df["season"] = season
1780    # print(final_df.columns)
1781
1782    final_df = final_df.rename(
1783        columns={
1784            "passing_COMPLETIONS": "passing_COMP",
1785            "passing_YPA": "passing_AVG",
1786            "passing_PCT": "passing_COMP%",
1787            "rushing_YPC": "rushing_AVG",
1788            "punting_YPP": "punting_AVG",
1789            "kicking_PCT": "kicking_FG%",
1790            "receiving_YPR": "receiving_AVG",
1791        }
1792    )
1793    final_df = final_df.reindex(columns=stat_columns)
1794    final_df = final_df.fillna(0)
1795    final_df = final_df.astype(
1796        {
1797            "passing_COMP": "int",
1798            "passing_ATT": "int",
1799            "rushing_CAR": "int",
1800            "rushing_YDS": "int",
1801            "receiving_REC": "int",
1802            "receiving_YDS": "int",
1803            "punting_NO": "int",
1804            "punting_YDS": "int",
1805            "kicking_FGM": "int",
1806            "kicking_FGA": "int",
1807            "kicking_XPM": "int",
1808            "kicking_XPA": "int",
1809            "kickReturns_NO": "int",
1810            "kickReturns_YDS": "int",
1811            "puntReturns_NO": "int",
1812            "puntReturns_YDS": "int",
1813        },
1814        # errors="ignore"
1815    )
1816
1817    final_df.loc[final_df["passing_ATT"] > 0, "passing_COMP%"] = (
1818        final_df["passing_COMP"] / final_df["passing_ATT"]
1819    )
1820    final_df["passing_COMP%"] = final_df["passing_COMP%"].round(3)
1821
1822    final_df.loc[final_df["rushing_CAR"] > 0, "rushing_AVG"] = (
1823        final_df["rushing_YDS"] / final_df["rushing_CAR"]
1824    )
1825    final_df["rushing_AVG"] = final_df["rushing_AVG"].round(3)
1826
1827    final_df.loc[final_df["receiving_REC"] > 0, "receiving_AVG"] = (
1828        final_df["receiving_YDS"] / final_df["receiving_REC"]
1829    )
1830    final_df["receiving_AVG"] = final_df["receiving_AVG"].round(3)
1831
1832    final_df.loc[final_df["punting_NO"] > 0, "punting_AVG"] = (
1833        final_df["punting_YDS"] / final_df["punting_NO"]
1834    )
1835    final_df["punting_AVG"] = final_df["punting_AVG"].round(3)
1836
1837    final_df.loc[final_df["kicking_FGA"] > 0, "kicking_FG%"] = (
1838        final_df["kicking_FGM"] / final_df["kicking_FGA"]
1839    )
1840    final_df["kicking_FG%"] = final_df["kicking_FG%"].round(5)
1841
1842    final_df.loc[final_df["kicking_XPA"] > 0, "kicking_XP%"] = (
1843        final_df["kicking_XPM"] / final_df["kicking_XPA"]
1844    )
1845    final_df["kicking_XP%"] = final_df["kicking_XP%"].round(5)
1846
1847    final_df.loc[final_df["kickReturns_NO"] > 0, "kickReturns_AVG"] = (
1848        final_df["kickReturns_YDS"] / final_df["kickReturns_NO"]
1849    )
1850    final_df["kickReturns_AVG"] = final_df["kickReturns_AVG"].round(3)
1851
1852    final_df.loc[final_df["puntReturns_NO"] > 0, "puntReturns_AVG"] = (
1853        final_df["puntReturns_YDS"] / final_df["puntReturns_NO"]
1854    )
1855    final_df["puntReturns_AVG"] = final_df["puntReturns_AVG"].round(3)
1856    if filter_by_stat_category is True and stat_category == "passing":
1857
1858        final_df = final_df[
1859            [
1860                "season",
1861                "team_name",
1862                "team_conference",
1863                "player_id",
1864                "player_name",
1865                # PASS
1866                "passing_COMP",
1867                "passing_ATT",
1868                "passing_YDS",
1869                "passing_TD",
1870                "passing_INT",
1871            ]
1872        ]
1873    elif filter_by_stat_category is True and stat_category == "rushing":
1874
1875        final_df = final_df[
1876            [
1877                "season",
1878                "team_name",
1879                "team_conference",
1880                "player_id",
1881                "player_name",
1882                # RUSH
1883                "rushing_CAR",
1884                "rushing_YDS",
1885                "rushing_AVG",
1886                "rushing_TD",
1887                "rushing_LONG",
1888            ]
1889        ]
1890    elif filter_by_stat_category is True and stat_category == "receiving":
1891
1892        final_df = final_df[
1893            [
1894                "season",
1895                "team_name",
1896                "team_conference",
1897                "player_id",
1898                "player_name",
1899                # REC
1900                "receiving_REC",
1901                "receiving_YDS",
1902                "receiving_AVG",
1903                "receiving_TD",
1904                "receiving_LONG",
1905            ]
1906        ]
1907    elif filter_by_stat_category is True and stat_category == "fumbles":
1908        final_df = final_df[
1909            [
1910                "season",
1911                "team_name",
1912                "team_conference",
1913                "player_id",
1914                "player_name",
1915                # FUM
1916                "fumbles_FUM",
1917                "fumbles_LOST",
1918                "fumbles_REC",
1919            ]
1920        ]
1921    elif filter_by_stat_category is True and stat_category == "defensive":
1922        final_df = final_df[
1923            [
1924                "season",
1925                "team_name",
1926                "team_conference",
1927                "player_id",
1928                "player_name",
1929                # DEFENSE
1930                "defensive_TOT",
1931                "defensive_SOLO",
1932                "defensive_TFL",
1933                "defensive_QB HUR",
1934                "defensive_SACKS",
1935                "defensive_PD",
1936                "defensive_TD",
1937            ]
1938        ]
1939    elif filter_by_stat_category is True and stat_category == "interceptions":
1940        final_df = final_df[
1941            [
1942                "season",
1943                "team_name",
1944                "team_conference",
1945                "player_id",
1946                "player_name",
1947                # INT
1948                "interceptions_INT",
1949                "interceptions_YDS",
1950                "interceptions_TD",
1951            ]
1952        ]
1953    elif filter_by_stat_category is True and stat_category == "punting":
1954
1955        final_df = final_df[
1956            [
1957                "season",
1958                "team_name",
1959                "team_conference",
1960                "player_id",
1961                "player_name",
1962                # PUNT
1963                "punting_NO",
1964                "punting_YDS",
1965                "punting_AVG",
1966                "punting_TB",
1967                "punting_In 20",
1968                "punting_LONG",
1969            ]
1970        ]
1971    elif filter_by_stat_category is True and stat_category == "kicking":
1972
1973        final_df = final_df[
1974            [
1975                "season",
1976                "team_name",
1977                "team_conference",
1978                "player_id",
1979                "player_name",
1980                # KICK
1981                "kicking_FGM",
1982                "kicking_FGA",
1983                "kicking_FG%",
1984                "kicking_LONG",
1985                "kicking_XPM",
1986                "kicking_XPA" "kicking_XP%",
1987            ]
1988        ]
1989    elif filter_by_stat_category is True and stat_category == "kickReturns":
1990
1991        final_df = final_df[
1992            [
1993                "season",
1994                "team_name",
1995                "team_conference",
1996                "player_id",
1997                "player_name",
1998                # KR
1999                "kickReturns_NO",
2000                "kickReturns_YDS",
2001                "kickReturns_AVG",
2002                "kickReturns_TD",
2003                "kickReturns_LONG",
2004            ]
2005        ]
2006    elif filter_by_stat_category is True and stat_category == "puntReturns":
2007
2008        final_df = final_df[
2009            [
2010                "season",
2011                "team_name",
2012                "team_conference",
2013                "player_id",
2014                "player_name",
2015                # KR
2016                "puntReturns_NO",
2017                "puntReturns_YDS",
2018                "puntReturns_AVG",
2019                "puntReturns_TD",
2020                "puntReturns_LONG",
2021            ]
2022        ]
2023
2024    return final_df

Get player season stats, or the stats of players in a specific time frame, from the CFBD API.

Parameters

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

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.

team (str, optional): Optional argument. If you only want CFB player season stats for a team, regardless if they are the home/away team, set team to the name of the team you want CFB player season stats from.

conference (str, optional): Optional argument. If you only want player 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 player 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 player 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

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 media information for non-regular season games, set season_type to "postseason". If you want both regular and postseason stats, set season_type = "both". If season_type is set to anything but "regular", "postseason", or "both", a ValueError() will be raised.

stat_category (str, optional): Optional argument. If only want stats for a specific stat category, set this variable to that category.

Valid inputs are:
- `passing`
- `rushing`
- `receiving`
- `fumbles`
- `defensive`
- `interceptions`
- `punting`
- `kicking`
- `kickReturns`
- `puntReturns`

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.players import get_cfbd_player_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 player season stats for
    # the Ohio Bobcats Football team in the 2020 CFB season.
    print(
        "Get player season stats for " +
        "the Ohio Bobcats Football team in the 2020 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        api_key=cfbd_key,
        season=2020,
        team="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for teams who competed in
    # the Southeastern conference (SEC) in the 2023 CFB season.
    print(
        "Get player season stats for teams who competed " +
        "in the Southeastern conference (SEC) in the 2023 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        api_key=cfbd_key,
        season=2020,
        conference="SEC"
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for teams who competed in
    # the Southeastern conference (SEC) in the 2023 CFB season,
    # but only between weeks 1 and 5.
    print(
        "Get player season stats for teams who competed " +
        "in the Southeastern conference (SEC) in the 2023 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        api_key=cfbd_key,
        season=2020,
        conference="SEC",
        start_week=1,
        end_week=5
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for the 2020 CFB season.
    print("Get player season stats for the 2020 CFB season.")
    json_data = get_cfbd_player_season_stats(
        api_key=cfbd_key,
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for
    # the Ohio Bobcats Football team in the 2022 CFB season,
    # but only use regular season games when calculating season stats.
    print(
        "Get player season stats for the Ohio Bobcats Football team " +
        "in the 2020 CFB season, but only use regular season games " +
        "when calculating season stats."
    )
    json_data = get_cfbd_player_season_stats(
        api_key=cfbd_key,
        season=2022,
        team="Ohio",
        season_type="regular"
    )
    print(json_data)
    time.sleep(5)

    # Get passing stats for teams who competed in
    # the Southeastern conference (SEC) in the 2023 CFB season.
    print(
        "Get passing stats for teams who competed " +
        "in the Southeastern conference (SEC) in the 2023 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        api_key=cfbd_key,
        season=2020,
        conference="SEC",
        stat_category="passing"
    )
    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_player_season_stats(
        api_key=cfbd_key,
        season=2020,
        team="LSU",
        stat_category="kicking",
        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 player season stats for
    # the Ohio Bobcats Football team in the 2020 CFB season.
    print(
        "Get player season stats for " +
        "the Ohio Bobcats Football team in the 2020 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        season=2020,
        team="Ohio"
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for teams who competed in
    # the Southeastern conference (SEC) in the 2023 CFB season.
    print(
        "Get player season stats for teams who competed " +
        "in the Southeastern conference (SEC) in the 2023 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        season=2020,
        conference="SEC"
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for teams who competed in
    # the Southeastern conference (SEC) in the 2023 CFB season,
    # but only between weeks 1 and 5.
    print(
        "Get player season stats for teams who competed " +
        "in the Southeastern conference (SEC) in the 2023 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        season=2020,
        conference="SEC",
        start_week=1,
        end_week=5
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for the 2020 CFB season.
    print("Get player season stats for the 2020 CFB season.")
    json_data = get_cfbd_player_season_stats(
        season=2020
    )
    print(json_data)
    time.sleep(5)

    # Get player season stats for
    # the Ohio Bobcats Football team in the 2022 CFB season,
    # but only use regular season games when calculating season stats.
    print(
        "Get player season stats for the Ohio Bobcats Football team " +
        "in the 2020 CFB season, but only use regular season games " +
        "when calculating season stats."
    )
    json_data = get_cfbd_player_season_stats(
        season=2022,
        team="Ohio",
        season_type="regular"
    )
    print(json_data)
    time.sleep(5)

    # Get passing stats for teams who competed in
    # the Southeastern conference (SEC) in the 2023 CFB season.
    print(
        "Get passing stats for teams who competed " +
        "in the Southeastern conference (SEC) in the 2023 CFB season."
    )
    json_data = get_cfbd_player_season_stats(
        season=2020,
        conference="SEC",
        stat_category="passing"
    )
    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_player_season_stats(
        season=2020,
        team="LSU",
        stat_category="kicking",
        return_as_dict=True
    )
    print(json_data)

Returns

A pandas DataFrame object with a list of players who matched the search string, or (if return_as_dict is set to True) a dictionary object with a list of players who matched the search string.

def get_cfbd_transfer_portal_data( season: int, api_key: str = None, api_key_dir: str = None, return_as_dict: bool = False):
2027def get_cfbd_transfer_portal_data(
2028    season: int,
2029    api_key: str = None,
2030    api_key_dir: str = None,
2031    return_as_dict: bool = False,
2032):
2033    """
2034    Get player usage data
2035    (A.K.A., the percentages for how often a player touched the ball),
2036    for a given season, from the CFBD API.
2037
2038    Parameters
2039    ----------
2040    `season` (int, mandatory):
2041        Required argument.
2042        Specifies the season you want CFB transfer portal data from.
2043        This must be specified, otherwise this package, and by extension
2044        the CFBD API, will not accept
2045        the request to get CFB transfer portal data stats.
2046
2047    `api_key` (str, optional):
2048        Semi-optional argument.
2049        If `api_key` is null, this function will attempt to load a CFBD API key
2050        from the python environment, or from a file on this computer.
2051        If `api_key` is not null,
2052        this function will automatically assume that the
2053        inputted `api_key` is a valid CFBD API key.
2054
2055    `api_key_dir` (str, optional):
2056        Optional argument.
2057        If `api_key` is set to am empty string, this variable is ignored.
2058        If `api_key_dir` is null, and `api_key` is null,
2059        this function will try to find
2060        a CFBD API key file in this user's home directory.
2061        If `api_key_dir` is set to a string, and `api_key` is null,
2062        this function will assume that `api_key_dir` is a directory,
2063        and will try to find a CFBD API key file in that directory.
2064
2065    `return_as_dict` (bool, semi-optional):
2066        Semi-optional argument.
2067        If you want this function to return
2068        the data as a dictionary (read: JSON object),
2069        instead of a pandas `DataFrame` object,
2070        set `return_as_dict` to `True`.
2071
2072    Usage
2073    ----------
2074    ```
2075    import time
2076
2077    from cfbd_json_py.players import get_cfbd_transfer_portal_data
2078
2079
2080    cfbd_key = "tigersAreAwesome"  # placeholder for your CFBD API Key.
2081
2082    if cfbd_key != "tigersAreAwesome":
2083        print(
2084            "Using the user's API key declared in this script " +
2085            "for this example."
2086        )
2087
2088        # Get Transfer Portal data for the 2021 CFB season.
2089        print("Get Transfer Portal data for the 2021 CFB season.")
2090        json_data = get_cfbd_transfer_portal_data(
2091            api_key=cfbd_key,
2092            season=2021
2093        )
2094        print(json_data)
2095        time.sleep(5)
2096
2097        # You can also tell this function to just return the API call as
2098        # a Dictionary (read: JSON) object.
2099        print(
2100            "You can also tell this function to just return the API call " +
2101            "as a Dictionary (read: JSON) object."
2102        )
2103        json_data = get_cfbd_transfer_portal_data(
2104            api_key=cfbd_key,
2105            season=2021,
2106            return_as_dict=True
2107        )
2108        print(json_data)
2109
2110    else:
2111        # Alternatively, if the CFBD API key exists in this python environment,
2112        # or it's been set by cfbd_json_py.utls.set_cfbd_api_token(),
2113        # you could just call these functions directly,
2114        # without setting the API key in the script.
2115        print(
2116            "Using the user's API key supposedly loaded " +
2117            "into this python environment for this example."
2118        )
2119
2120        # Get Transfer Portal data for the 2021 CFB season.
2121        print("Get Transfer Portal data for the 2021 CFB season.")
2122        json_data = get_cfbd_transfer_portal_data(
2123            season=2021
2124        )
2125        print(json_data)
2126        time.sleep(5)
2127
2128        # You can also tell this function to just return the API call as
2129        # a Dictionary (read: JSON) object.
2130        print(
2131            "You can also tell this function to just return the API call " +
2132            "as a Dictionary (read: JSON) object."
2133        )
2134        json_data = get_cfbd_transfer_portal_data(
2135            season=2021,
2136            return_as_dict=True
2137        )
2138        print(json_data)
2139
2140    ```
2141    Returns
2142    ----------
2143    A pandas `DataFrame` object with transfer portal data,
2144    or (if `return_as_dict` is set to `True`)
2145    a dictionary object with transfer portal data.
2146
2147    """
2148    now = datetime.now()
2149    url = "https://api.collegefootballdata.com/player/portal"
2150
2151    portal_df = pd.DataFrame()
2152    # row_df = pd.DataFrame()
2153
2154    if api_key is not None:
2155        real_api_key = api_key
2156        del api_key
2157    else:
2158        real_api_key = get_cfbd_api_token(api_key_dir=api_key_dir)
2159
2160    if real_api_key == "tigersAreAwesome":
2161        raise ValueError(
2162            "You actually need to change `cfbd_key` to your CFBD API key."
2163        )
2164    elif "Bearer " in real_api_key:
2165        pass
2166    elif "Bearer" in real_api_key:
2167        real_api_key = real_api_key.replace("Bearer", "Bearer ")
2168    else:
2169        real_api_key = "Bearer " + real_api_key
2170
2171    if season is None:
2172        # This should never happen without user tampering, but if it does,
2173        # we need to raise an error,
2174        # because the CFBD API will refuse this call without a valid season.
2175        raise SystemError(
2176            "I don't know how, I don't know why, "
2177            + "but you managed to call this function "
2178            + "while `season` was `None` (NULL),"
2179            + " and the function got to this point in the code."
2180            + "\nIf you have a GitHub account, "
2181            + "please raise an issue on this python package's GitHub page:\n"
2182            + "https://github.com/armstjc/cfbd-json-py/issues"
2183        )
2184    elif season > (now.year + 1):
2185        raise ValueError(f"`season` cannot be greater than {season}.")
2186    elif season < 2017:
2187        raise ValueError(f"Transfer portal wasn't really a thing in {season}.")
2188
2189    # URL builder
2190    ##########################################################################
2191
2192    # required by API
2193    url += f"?year={season}"
2194
2195    headers = {
2196        "Authorization": f"{real_api_key}",
2197        "accept": "application/json"
2198    }
2199
2200    response = requests.get(url, headers=headers)
2201
2202    if response.status_code == 200:
2203        pass
2204    elif response.status_code == 401:
2205        raise ConnectionRefusedError(
2206            "Could not connect. The connection was refused." +
2207            "\nHTTP Status Code 401."
2208        )
2209    else:
2210        raise ConnectionError(
2211            f"Could not connect.\nHTTP Status code {response.status_code}"
2212        )
2213
2214    json_data = response.json()
2215
2216    if return_as_dict is True:
2217        return json_data
2218
2219    portal_df = pd.json_normalize(json_data)
2220    portal_df.rename(
2221        columns={
2222            "firstName": "first_name",
2223            "lastName": "last_name",
2224            "position": "position_abv",
2225            "origin": "origin_team",
2226            "destination": "destination_team",
2227            "transferDate": "transfer_date",
2228            "rating": "rating",
2229            "stars": "stars",
2230            "eligibility": "eligibility",
2231        },
2232        inplace=True,
2233    )
2234    return portal_df

Get player usage data (A.K.A., the percentages for how often a player touched the ball), for a given season, from the CFBD API.

Parameters

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

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.players import get_cfbd_transfer_portal_data


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

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

    # Get Transfer Portal data for the 2021 CFB season.
    print("Get Transfer Portal data for the 2021 CFB season.")
    json_data = get_cfbd_transfer_portal_data(
        api_key=cfbd_key,
        season=2021
    )
    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_transfer_portal_data(
        api_key=cfbd_key,
        season=2021,
        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 Transfer Portal data for the 2021 CFB season.
    print("Get Transfer Portal data for the 2021 CFB season.")
    json_data = get_cfbd_transfer_portal_data(
        season=2021
    )
    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_transfer_portal_data(
        season=2021,
        return_as_dict=True
    )
    print(json_data)

Returns

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