cwendt94 / espn-api

ESPN Fantasy API! (Football, Basketball)
MIT License
544 stars 183 forks source link

adding owners to Team #487

Closed bnm91 closed 8 months ago

bnm91 commented 8 months ago

Problem

Currently there's no way to get info on the "owner" (aka "manager") of a Team. While the team's name is available, those are subject to change making tracking over longer periods difficult

Solution

ESPN has a concept of Members on a League and Owners on a Team. These are tied together by an Id and the Member entity has much more stable information about the actual humans behind the team. Storing this Member info with the Team will make that info more accessible

Code Changes

bnm91 commented 8 months ago

I’ll take a look at these failures soon

cwendt94 commented 8 months ago

Don't worry about the hockey team names one those just popped up, but it does look like two new ones are failing for owner logic.

cwendt94 commented 8 months ago

FYI I did have owners but them removed because they no longer had the actual name, but I can see why we would want at least the unique id. Here was the PR removing it. There is a chance a team might not have a owner see this comment

samthom1 commented 8 months ago

For what it's worth, there may have been further changes to the ESPN API this morning. I was making my own attempt at fixing this issue when the API call started returning additional fields under data['members']. Restoring the members/owner references from before commit cc82818 allows owner names to flow through again.

bnm91 commented 8 months ago

@cwendt94 I rewrote this to only include the "unique id" as you mentioned above. I also fixed a couple tests broken by these changes. I still think it would be nice to have the "member" (and therefore the user's actual name) associated with the Team but currently this leaves that exercise to the user. Perhaps I'll open a separate discussion for that improvement

I'm struggling to run the entire test suite in my environment but addressed a few test issues I was aware of.

The following tests will probably still fail but due to separate issue: test_league_draft (basketball.integration.test_league.LeagueTest) separate issue -- test uses 2019 data which requires 'location' but none exists

test_box_scores (football.integration.test_league.LeagueTest) separate issue -- test uses 2019 data which requires 'location' but none exists

test_league_int (hockey.integration.test_league.LeagueTest) separate issue -- test uses 2021 data which requires 'location' but none exists

codecov-commenter commented 8 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (f268c46) 80.42% compared to head (ed238bc) 80.53%. Report is 7 commits behind head on master.

:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #487 +/- ## ========================================== + Coverage 80.42% 80.53% +0.11% ========================================== Files 59 59 Lines 2094 2106 +12 ========================================== + Hits 1684 1696 +12 Misses 410 410 ``` | [Files](https://app.codecov.io/gh/cwendt94/espn-api/pull/487?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt) | Coverage Δ | | |---|---|---| | [espn\_api/base\_league.py](https://app.codecov.io/gh/cwendt94/espn-api/pull/487?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt#diff-ZXNwbl9hcGkvYmFzZV9sZWFndWUucHk=) | `100.00% <100.00%> (ø)` | | | [espn\_api/baseball/team.py](https://app.codecov.io/gh/cwendt94/espn-api/pull/487?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt#diff-ZXNwbl9hcGkvYmFzZWJhbGwvdGVhbS5weQ==) | `95.45% <ø> (+0.10%)` | :arrow_up: | | [espn\_api/basketball/team.py](https://app.codecov.io/gh/cwendt94/espn-api/pull/487?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt#diff-ZXNwbl9hcGkvYmFza2V0YmFsbC90ZWFtLnB5) | `97.82% <ø> (-2.18%)` | :arrow_down: | | [espn\_api/football/team.py](https://app.codecov.io/gh/cwendt94/espn-api/pull/487?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt#diff-ZXNwbl9hcGkvZm9vdGJhbGwvdGVhbS5weQ==) | `100.00% <ø> (+1.51%)` | :arrow_up: | | [espn\_api/hockey/team.py](https://app.codecov.io/gh/cwendt94/espn-api/pull/487?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt#diff-ZXNwbl9hcGkvaG9ja2V5L3RlYW0ucHk=) | `100.00% <ø> (+2.12%)` | :arrow_up: | | [espn\_api/wbasketball/team.py](https://app.codecov.io/gh/cwendt94/espn-api/pull/487?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt#diff-ZXNwbl9hcGkvd2Jhc2tldGJhbGwvdGVhbS5weQ==) | `17.02% <ø> (-0.38%)` | :arrow_down: | ... and [2 files with indirect coverage changes](https://app.codecov.io/gh/cwendt94/espn-api/pull/487/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Christian+Wendt)

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

DesiPilla commented 8 months ago

@bnm91 Is there an endpoint / header we can use to get the actual users' names?

DesiPilla commented 8 months ago

I'm using the following workaround for now:

def set_league_endpoint(league: League) -> None:
    """Set the league's endpoint."""

    # Current season
    if league.year >= (datetime.datetime.today() - datetime.timedelta(weeks=12)).year:
        league.endpoint = (
            "https://fantasy.espn.com/apis/v3/games/ffl/seasons/"
            + str(league.year)
            + "/segments/0/leagues/"
            + str(league.league_id)
            + "?"
        )

    # Old season
    else:
        league.endpoint = (
            "https://fantasy.espn.com/apis/v3/games/ffl/leagueHistory/"
            + str(league.league_id)
            + "?seasonId="
            + str(league.year)
            + "&"
        )

def set_owner_names(league: League):
    """This function sets the owner names for each team in the league.
    The team.owners attribute only contains the SWIDs of each owner, not their real name.

    Args:
        league (League): ESPN League object
    """
    endpoint = "{}view=mTeam".format(league.endpoint)
    r = requests.get(endpoint, cookies=league.cookies).json()
    if type(r) == list:
        r = r[0]

    # For each member in the data, create a map from SWID to their full name
    swid_to_name = {}
    for member in r["members"]:
        swid_to_name[member["id"]] = re.sub(
            " +", " ", member["firstName"] + " " + member["lastName"]
        ).title()

    # Set the owner name for each team
    for team in league.teams:
        team.owner = swid_to_name[team.owners[0]]

set_league_endpoint(league)
set_owner_names(league)