示例#1
0
def fill_results_from_api(gw_start, gw_end, season, dbsession):
    fetcher = FPLDataFetcher()
    matches = fetcher.get_fixture_data()
    for m in matches:
        if not m["finished"]:
            continue
        gameweek = m["event"]
        if gameweek < gw_start or gameweek > gw_end:
            continue
        home_id = m["team_h"]
        away_id = m["team_a"]
        home_team = None
        away_team = None
        for k, v in alternative_team_names.items():
            if str(home_id) in v:
                home_team = k
            elif str(away_id) in v:
                away_team = k
        if not home_team:
            raise ValueError("Unable to find team with id {}".format(home_id))
        if not away_team:
            raise ValueError("Unable to find team with id {}".format(away_id))
        home_score = m["team_h_score"]
        away_score = m["team_a_score"]
        f = _find_fixture(season, home_team, away_team, dbsession)
        res = Result()
        res.fixture = f
        res.home_score = int(home_score)
        res.away_score = int(away_score)
        dbsession.add(res)
    dbsession.commit()
def main():
    parser = argparse.ArgumentParser(description="plot mini-league")
    parser.add_argument(
        "--thing_to_plot",
        help="points,total_points,ranking,overall_ranking",
        default="total_points",
    )
    args = parser.parse_args()
    thing_to_plot = args.thing_to_plot

    fetcher = FPLDataFetcher()
    league_data = fetcher.get_fpl_league_data()
    team_ids = get_team_ids(league_data)
    team_names = get_team_names(league_data)
    team_histories = []
    for i, team_id in enumerate(team_ids):
        team_data = fetcher.get_fpl_team_history_data(team_id)
        history_dict = get_team_history(team_data)
        history_dict["name"] = team_names[i]
        team_histories.append(history_dict)

    xvals = sorted(team_histories[0]["history"].keys())
    points = []
    for th in team_histories:
        points.append([
            th["history"][gw][thing_to_plot]
            for gw in sorted(th["history"].keys())
        ])
        plt.plot(xvals, points[-1], label=th["name"])
    plt.legend(loc="best")
    plt.xlabel("gameweek")
    plt.ylabel(thing_to_plot)
    plt.show()
示例#3
0
def test_get_summary_data():
    """
    get summary of all players' data for this season.
    """
    fetcher = FPLDataFetcher()
    data = fetcher.get_current_summary_data()
    assert isinstance(data, dict)
    assert len(data) > 0
示例#4
0
def test_get_event_data():
    """
    gameweek list with deadlines and status
    """
    fetcher = FPLDataFetcher()
    data = fetcher.get_event_data()
    assert isinstance(data, dict)
    assert len(data) > 0
示例#5
0
def test_get_team_history_data():
    """
    gameweek history for our team id
    """
    fetcher = FPLDataFetcher()
    data = fetcher.get_fpl_team_history_data()
    assert isinstance(data, dict)
    assert len(data) > 0
示例#6
0
def test_get_player_summary_data():
    """
    summary for individual players
    """
    fetcher = FPLDataFetcher()
    data = fetcher.get_player_summary_data()
    assert isinstance(data, dict)
    assert len(data) > 0
示例#7
0
def test_get_current_team_data():
    """
    summary for current teams
    """
    fetcher = FPLDataFetcher()
    data = fetcher.get_current_team_data()
    assert isinstance(data, dict)
    assert len(data) > 0
示例#8
0
def test_get_team_data():
    """
    should give current list of players in our team
    """
    fetcher = FPLDataFetcher()
    data = fetcher.get_fpl_team_data(1)["picks"]
    assert isinstance(data, list)
    assert len(data) == 15
示例#9
0
def test_get_detailed_player_data():
    """
    for player_id=1, list of gameweek data
    """
    fetcher = FPLDataFetcher()

    data = fetcher.get_gameweek_data_for_player(1)
    assert isinstance(data, dict)
    assert len(data) > 0
示例#10
0
def test_get_fpl_team_data_gw1():
    """
    which players are in our squad for gw1
    """
    fetcher = FPLDataFetcher()
    data = fetcher.get_fpl_team_data(1)
    assert isinstance(data, dict)
    assert "picks" in data.keys()
    players = [p["element"] for p in data["picks"]]
    assert len(players) == 15
示例#11
0
def fill_fixtures_from_api(season, dbsession=session):
    """
    Use the FPL API to get a list of fixures.
    """
    tag = str(uuid.uuid4())
    fetcher = FPLDataFetcher()
    fixtures = fetcher.get_fixture_data()
    for fixture in fixtures:
        try:
            f = find_fixture(
                fixture["team_h"],
                was_home=True,
                other_team=fixture["team_a"],
                season=season,
                dbsession=dbsession,
            )
            update = True
        except ValueError:
            f = Fixture()
            update = False

        f.date = fixture["kickoff_time"]
        f.gameweek = fixture["event"]
        f.season = season
        f.tag = tag

        home_id = fixture["team_h"]
        away_id = fixture["team_a"]
        found_home = False
        found_away = False
        for k, v in alternative_team_names.items():
            if str(home_id) in v:
                f.home_team = k
                found_home = True
            elif str(away_id) in v:
                f.away_team = k
                found_away = True
            if found_home and found_away:
                break

        error_str = "Can't find team(s) with id(s): {}."
        if not found_home and found_away:
            raise ValueError(error_str.format(home_id + ", " + away_id))
        elif not found_home:
            raise ValueError(error_str.format(home_id))
        elif not found_away:
            raise ValueError(error_str.format(away_id))
        else:
            pass

        if not update:
            dbsession.add(f)

    dbsession.commit()
    return True
示例#12
0
def make_transfers(fpl_team_id=None, skip_check=False):

    transfer_player_ids, team_id, current_gw, chip_played = get_gw_transfer_suggestions(
        fpl_team_id
    )
    fetcher = FPLDataFetcher(team_id)
    if len(transfer_player_ids[0]) == 0:
        # no players to remove in DB - initial team?
        print("Making transfer list for starting team")
        priced_transfers = build_init_priced_transfers(fetcher, team_id)
    else:

        pre_transfer_bank = get_bank(fpl_team_id=team_id)
        priced_transfers = price_transfers(transfer_player_ids, fetcher, current_gw)
        post_transfer_bank = deduct_transfer_price(pre_transfer_bank, priced_transfers)
        print_output(
            team_id, current_gw, priced_transfers, pre_transfer_bank, post_transfer_bank
        )

    if skip_check or check_proceed():
        transfer_req = build_transfer_payload(
            priced_transfers, current_gw, fetcher, chip_played
        )
        post_transfers(transfer_req, fetcher)
    return True
示例#13
0
def test_get_fpl_team_data_gw1_different_fpl_team_ids():
    """
    which players are in a couple of different squads for gw 1
    """
    fetcher = FPLDataFetcher()
    # assume that fpl_team_ids < 100 will all have squads for
    # gameweek 1, and that they will be different..
    team_id_1 = random.randint(1, 50)
    team_id_2 = random.randint(51, 100)
    data_1 = fetcher.get_fpl_team_data(1, fpl_team_id=team_id_1)
    players_1 = [p["element"] for p in data_1["picks"]]
    assert len(players_1) == 15
    data_2 = fetcher.get_fpl_team_data(1, fpl_team_id=team_id_2)
    players_2 = [p["element"] for p in data_2["picks"]]
    assert len(players_2) == 15
    # check they are different
    assert sorted(players_1) != sorted(players_2)
示例#14
0
def fill_player_table_from_api(season, session):
    """
    use the FPL API
    """
    df = FPLDataFetcher()
    pd = df.get_player_summary_data()

    for k, v in pd.items():
        p = Player()
        p.fpl_api_id = k
        first_name = v["first_name"]  # .encode("utf-8")
        second_name = v["second_name"]  # .encode("utf-8")
        name = "{} {}".format(first_name, second_name)

        print("PLAYER {} {}".format(season, name))
        p.name = name
        session.add(p)
    session.commit()
def set_lineup(fpl_team_id=None):
    """
    Retrieve the latest lineup and apply the latest prediction to it.

    Note that this assumes that the prediction has been ran recently.
    """

    print("fpl_team_id is {}".format(fpl_team_id))
    fetcher = FPLDataFetcher(fpl_team_id)
    print("Got fetcher {}".format(fetcher.FPL_TEAM_ID))
    picks = fetcher.get_lineup()
    print("Got picks {}".format(picks))
    squad = get_lineup_from_payload(picks)
    print("got squad: {}".format(squad))

    squad.optimize_lineup(NEXT_GAMEWEEK, get_latest_prediction_tag())

    if check_proceed(squad):
        payload = build_lineup_payload(squad)
        fetcher.post_lineup(payload)
示例#16
0
def main(fpl_team_id=None):

    transfer_player_ids, team_id, current_gw, chip_played = get_gw_transfer_suggestions(
        fpl_team_id
    )

    fetcher = FPLDataFetcher(team_id)

    pre_transfer_bank = get_bank(fpl_team_id=team_id)
    priced_transfers = price_transfers(transfer_player_ids, fetcher, current_gw)
    post_transfer_bank = deduct_transfer_price(pre_transfer_bank, priced_transfers)

    print_output(
        team_id, current_gw, priced_transfers, pre_transfer_bank, post_transfer_bank
    )

    if check_proceed():
        transfer_req = build_transfer_payload(
            priced_transfers, current_gw, fetcher, chip_played
        )
        post_transfers(transfer_req, fetcher)
def fill_playerscores_from_api(season,
                               gw_start=1,
                               gw_end=NEXT_GAMEWEEK,
                               dbsession=session):

    fetcher = FPLDataFetcher()
    input_data = fetcher.get_player_summary_data()
    for player_api_id in input_data.keys():
        # find the player in the player table.  If they're not
        # there, then we don't care (probably not a current player).
        player = get_player_from_api_id(player_api_id, dbsession=dbsession)
        if not player:
            print("No player with API id {}".format(player_api_id))
        player_id = player.player_id
        print("SCORES {} {}".format(season, player.name))
        player_data = fetcher.get_gameweek_data_for_player(player_api_id)
        # now loop through all the matches that player played in
        for gameweek, results in player_data.items():
            if gameweek not in range(gw_start, gw_end):
                continue
            for result in results:
                # try to find the match in the match table
                opponent = get_team_name(result["opponent_team"])

                played_for, fixture = get_player_team_from_fixture(
                    gameweek,
                    opponent,
                    player_at_home=result["was_home"],
                    kickoff_time=result["kickoff_time"],
                    season=season,
                    dbsession=dbsession,
                    return_fixture=True,
                )

                if not fixture or not played_for:
                    print("  Couldn't find match for {} in gw {}".format(
                        player.name, gameweek))
                    continue

                ps = PlayerScore()
                ps.player_team = played_for
                ps.opponent = opponent
                ps.goals = result["goals_scored"]
                ps.assists = result["assists"]
                ps.bonus = result["bonus"]
                ps.points = result["total_points"]
                ps.conceded = result["goals_conceded"]
                ps.minutes = result["minutes"]
                ps.player = player
                ps.fixture = fixture
                ps.result = fixture.result

                # extended features
                # get features excluding the core ones already populated above
                extended_feats = [
                    col for col in ps.__table__.columns.keys() if col not in [
                        "id",
                        "player_team",
                        "opponent",
                        "goals",
                        "assists",
                        "bonus",
                        "points",
                        "conceded",
                        "minutes",
                        "player_id",
                        "result_id",
                        "fixture_id",
                    ]
                ]
                for feat in extended_feats:
                    try:
                        ps.__setattr__(feat, result[feat])
                    except KeyError:
                        pass

                dbsession.add(ps)
                print("  got {} points vs {} in gameweek {}".format(
                    result["total_points"], opponent, gameweek))
示例#18
0
def fill_attributes_table_from_api(season, gw_start=1, dbsession=session):
    """
    use the FPL API to get player attributes info for the current season
    """
    fetcher = FPLDataFetcher()
    next_gw = get_next_gameweek(season=season, dbsession=dbsession)

    # needed for selected by calculation from percentage below
    n_players = fetcher.get_current_summary_data()["total_players"]

    input_data = fetcher.get_player_summary_data()

    for player_api_id in input_data.keys():
        # find the player in the player table
        player = get_player_from_api_id(player_api_id, dbsession=dbsession)
        if not player:
            print("ATTRIBUTES {} No player found with id {}".format(
                season, player_api_id))
            continue

        print("ATTRIBUTES {} {}".format(season, player.name))

        # First update the current gameweek using the summary data
        p_summary = input_data[player_api_id]
        position = positions[p_summary["element_type"]]

        pa = get_player_attributes(player.player_id,
                                   season=season,
                                   gameweek=next_gw,
                                   dbsession=dbsession)
        if pa:
            # found pre-existing attributes for this gameweek
            update = True
        else:
            # no attributes for this gameweek for this player yet
            pa = PlayerAttributes()
            update = False

        pa.player = player
        pa.player_id = player.player_id
        pa.season = season
        pa.gameweek = next_gw
        pa.price = int(p_summary["now_cost"])
        pa.team = get_team_name(p_summary["team"],
                                season=season,
                                dbsession=dbsession)
        pa.position = positions[p_summary["element_type"]]
        pa.selected = int(
            float(p_summary["selected_by_percent"]) * n_players / 100)
        pa.transfers_in = int(p_summary["transfers_in_event"])
        pa.transfers_out = int(p_summary["transfers_out_event"])
        pa.transfers_balance = pa.transfers_in - pa.transfers_out
        pa.chance_of_playing_next_round = p_summary[
            "chance_of_playing_next_round"]
        pa.news = p_summary["news"]
        if (pa.chance_of_playing_next_round is not None
                and pa.chance_of_playing_next_round <= 50):
            pa.return_gameweek = get_return_gameweek_from_news(
                p_summary["news"],
                season=season,
                dbsession=dbsession,
            )

        if not update:
            # only need to add to the dbsession for new entries, if we're doing
            #  an update the final dbsession.commit() is enough
            dbsession.add(pa)

        # now get data for previous gameweeks
        if next_gw > 1:
            player_data = fetcher.get_gameweek_data_for_player(player_api_id)
            if not player_data:
                print("Failed to get data for", player.name)
                continue
            for gameweek, data in player_data.items():
                if gameweek < gw_start:
                    continue

                for result in data:
                    # check whether there are pre-existing attributes to update
                    pa = get_player_attributes(
                        player.player_id,
                        season=season,
                        gameweek=gameweek,
                        dbsession=dbsession,
                    )
                    if pa:
                        update = True
                    else:
                        pa = PlayerAttributes()
                        update = False

                    # determine the team the player played for in this fixture
                    opponent_id = result["opponent_team"]
                    was_home = result["was_home"]
                    kickoff_time = result["kickoff_time"]
                    team = get_player_team_from_fixture(
                        gameweek,
                        opponent_id,
                        was_home,
                        kickoff_time,
                        season=season,
                        dbsession=dbsession,
                    )

                    pa.player = player
                    pa.player_id = player.player_id
                    pa.season = season
                    pa.gameweek = gameweek
                    pa.price = int(result["value"])
                    pa.team = team
                    pa.position = position  # does not change during season
                    pa.transfers_balance = int(result["transfers_balance"])
                    pa.selected = int(result["selected"])
                    pa.transfers_in = int(result["transfers_in"])
                    pa.transfers_out = int(result["transfers_out"])

                    if not update:
                        # don't need to add to dbsession if updating pre-existing row
                        dbsession.add(pa)

                    break  # done this gameweek now
示例#19
0
    names
    """
    best_ratio = 0.0
    best_match = None
    for t in fpl_teams:
        if fuzz.partial_ratio(t, team) > best_ratio:
            best_ratio = fuzz.partial_ratio(t, team)
            best_match = t
    print("Best match {}/{}, score {}".format(best_match, team, best_ratio))
    return best_match, best_ratio


if __name__ == "__main__":

    # get the team names as used in FPL
    df = FPLDataFetcher()
    teamdata = df.get_current_team_data()
    teamdict = {
        teamdata[k]["name"]: [teamdata[k]["short_name"]]
        for k in teamdata.keys()
    }

    #    teamdicts = [{teamdata[k]['name']:[teamdata[k]['short_name']]} \
    #                for k in teamdata.keys()]
    fpl_teams = list(teamdict.keys())
    # get the team names from the results csv
    missing = set()
    matched = set()
    history_teams = set()
    for season in ["1415", "1516", "1617", "1718"]:
        filename = "../data/results_{}.csv".format(season)
示例#20
0
"""

Season details

"""
from datetime import datetime
from airsenal.framework.data_fetcher import FPLDataFetcher


def get_current_season():
    """
    use the current time to find what season we're in.
    """
    current_time = datetime.now()
    if current_time.month > 7:
        start_year = current_time.year
    else:
        start_year = current_time.year - 1
    end_year = start_year + 1
    return "{}{}".format(str(start_year)[2:], str(end_year)[2:])


# make this a global variable in this module, import into other modules
CURRENT_SEASON = get_current_season()

fetcher = FPLDataFetcher()
# TODO make this a database table so we can look at past seasons
CURRENT_TEAMS = [
    t["short_name"] for t in fetcher.get_current_team_data().values()
]
def fill_playerscores_from_api(season,
                               gw_start=1,
                               gw_end=NEXT_GAMEWEEK,
                               dbsession=session):
    fetcher = FPLDataFetcher()
    input_data = fetcher.get_player_summary_data()
    for player_api_id in input_data.keys():
        player = get_player_from_api_id(player_api_id, dbsession=dbsession)
        if not player:
            # If no player found with this API ID something has gone wrong with the
            # Player table, e.g. clashes between players with the same name
            print(f"ERROR! No player with API id {player_api_id}. Skipped.")
            continue

        print("SCORES {} {}".format(season, player))
        player_data = fetcher.get_gameweek_data_for_player(player_api_id)
        # now loop through all the matches that player played in
        for gameweek, results in player_data.items():
            if gameweek not in range(gw_start, gw_end):
                continue
            for result in results:
                # try to find the match in the match table
                opponent = get_team_name(result["opponent_team"])

                played_for, fixture = get_player_team_from_fixture(
                    gameweek,
                    opponent,
                    player_at_home=result["was_home"],
                    kickoff_time=result["kickoff_time"],
                    season=season,
                    dbsession=dbsession,
                    return_fixture=True,
                )

                if not fixture or not played_for or not fixture.result:
                    print(
                        "  Couldn't find match result for {} in gw {}".format(
                            player, gameweek))
                    continue

                ps = get_player_scores(fixture=fixture,
                                       player=player,
                                       dbsession=dbsession)
                if ps is None:
                    ps = PlayerScore()
                    add = True
                else:
                    add = False
                ps.player_team = played_for
                ps.opponent = opponent
                ps.goals = result["goals_scored"]
                ps.assists = result["assists"]
                ps.bonus = result["bonus"]
                ps.points = result["total_points"]
                ps.conceded = result["goals_conceded"]
                ps.minutes = result["minutes"]
                ps.player = player
                ps.fixture = fixture
                ps.result = fixture.result

                # extended features
                # get features excluding the core ones already populated above
                extended_feats = [
                    col for col in ps.__table__.columns.keys() if col not in [
                        "id",
                        "player_team",
                        "opponent",
                        "goals",
                        "assists",
                        "bonus",
                        "points",
                        "conceded",
                        "minutes",
                        "player_id",
                        "result_id",
                        "fixture_id",
                    ]
                ]
                for feat in extended_feats:
                    try:
                        ps.__setattr__(feat, result[feat])
                    except KeyError:
                        pass

                if add:
                    dbsession.add(ps)
                print("  got {} points vs {} in gameweek {}".format(
                    result["total_points"], opponent, gameweek))
    dbsession.commit()
示例#22
0
    best_ratio = 0.0
    best_match = None
    for p in fpl_players:
        if fuzz.partial_ratio(p, player) > best_ratio:
            best_ratio = fuzz.partial_ratio(p, player)
            best_match = p
    #   print("Best match {}/{}, score {}".format(best_match,
    #                                             player,
    #                                             best_ratio))
    return best_match, best_ratio


if __name__ == "__main__":

    # get the team names as used in FPL
    df = FPLDataFetcher()
    playerdict = {}
    playerdata = df.get_player_summary_data()
    for k in playerdata.keys():
        player_name = "{} {}".format(playerdata[k]["first_name"],
                                     playerdata[k]["second_name"])
        playerdict[player_name] = [playerdata[k]["web_name"]]

    fpl_players_to_match = list(playerdict.keys())
    # get the player names from the fpl archives json
    missing = set()
    matched = set()
    history_players = set()
    for season in ["1516", "1617"]:
        filename = "../data/player_summary_{}.json".format(season)
        player_data = json.load(open(filename))
示例#23
0
from airsenal.framework.mappings import alternative_player_names
from airsenal.framework.data_fetcher import FPLDataFetcher
from airsenal.framework.schema import (
    Player,
    PlayerAttributes,
    Fixture,
    PlayerScore,
    PlayerPrediction,
    Transaction,
    Team,
    session,
)
from airsenal.framework.season import CURRENT_SEASON

fetcher = FPLDataFetcher()  # in global scope so it can keep cached data


def get_max_gameweek(season=CURRENT_SEASON, dbsession=session):
    """
    Return the maximum gameweek number across all scheduled fixtures. This shuold
    generally be 38, but may be different in the case of major disruptino (e.g.
    Covid-19)
    """
    max_gw_fixture = (dbsession.query(Fixture).filter_by(
        season=season).order_by(Fixture.gameweek.desc()).first())

    if max_gw_fixture is None:
        # TODO Tests fail without this as tests don't populate fixture table in db
        max_gw = 100
    else:
示例#24
0
def test_instantiate_fetchers():
    """
    check we can instantiate the classes
    """
    fpl = FPLDataFetcher()
    assert fpl