๐
amosbastian / fpl Goto Github PK
View Code? Open in Web Editor NEWAn asynchronous Python wrapper for the Fantasy Premier League API.
Home Page: https://fpl.readthedocs.io
License: MIT License
An asynchronous Python wrapper for the Fantasy Premier League API.
Home Page: https://fpl.readthedocs.io
License: MIT License
๐
format url queries in GET requests, e.g. page, event, team
Running the following python script:
#!/usr/bin/python3
import asyncio
import aiohttp
from fpl import FPL
async def my_team(user_id):
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
await fpl.login("someemail.com", "somepassword")
user = await fpl.get_user(user_id)
#await user.substitute([12],[213]). # works
#await user.captain(213). # works
await user.transfer([437],[514]). # works but gives error
team = await user.get_team()
print(user)
print(team)
asyncio.run(my_team(111111))
Makes the correct transfer, but gives out the following error:
Traceback (most recent call last):
File "/Users/rmikhael/Downloads/./test.py", line 19, in
asyncio.run(my_team(836745))
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/Users/rmikhael/Downloads/./test.py", line 14, in my_team
await user.transfer([514],[437])
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/fpl/models/user.py", line 589, in transfer
post_response = await post(
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/fpl/utils.py", line 27, in post
return await response.json()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/aiohttp/client_reqrep.py", line 1097, in json
raise ContentTypeError(
aiohttp.client_exceptions.ContentTypeError: 0, message='Attempt to decode JSON with unexpected mimetype: ', url=URL('https://fantasy.premierleague.com/api/transfers/')
my python3 version is 3.9.1
my fpl version is 0.6.25
I know I can suppress the error by calling
$ python3 test.py 2> /dev/null
But I would rather have a clean response with no errors, since I want my code to verify no errors from calling the script.
fpl.player.team_converter
seems to be missing the mapping for "West Ham"
Add a substitution function that allows the user to create their starting 11 and bench without visiting https://fantasy.premierleague.com.
fpl.py
"Those checks were added in a couple of days ago and looks like it's just a typo seeing as most references to the session are without the underscore. It's the same on line 502 which was added as part of the same commit."
When running the following code to print out all the fixtures per gameweek, the promoted teams seem to be missing, and other than that, some other fixtures are also incorrect. Relegated teams from 20/21 are still in the data.
import aiohttp
from fpl import FPL
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
for gw in range(1, 39):
print(gw)
fixtures = await fpl.get_fixtures_by_gameweek(gw)
for fix in range(len(fixtures)):
print(fixtures[fix])
asyncio.get_event_loop().run_until_complete(main())
doesn't return expected values
There is a bug in function get_user_history(). Similarly to https://github.com/amosbastian/fpl/issues/34, it hangs when user joined after gw1:
Line 347 in c8620fc
where the code should be range(self.started_event, self.current_event + 1)
after calculating live bonus
It appears that one needs to be logged in to be able use fpl fully. The FPL class gets email and password values from the env vars if not provided as input params. Since there is no mention in the docs that it is required to have the env vars set, fpl.login() will fail on KeyError exception. Consequently, tests relying on fpl.login() fail.
Required env vars are FPL_EMAIL, FPL_PASSWORD
Would be great if there was a function that allows you to activate e.g. your wildcard. I'm not sure if this is possible, but someone told me transfers and substitutions are, so this should be as well.
having trouble actually running the code
keeps giving me 'from: can't read /var/mail/fpl'
and when using 'get_players()' just gives me a > and nothing else..
Hi, this script works great for FPL. I have been trying to use it on https://fantasy.allsvenskan.se/api/ by changing the constant API_BASE_URL but I getting error in fpl.py.
I would be more than thankful for some tips how I can use this package in Sweden :)
# API_BASE_URL = "https://fantasy.premierleague.com/api/"
API_BASE_URL = "https://fantasy.allsvenskan.se/api/"
static = json.loads(resp.read().decode("utf-8"))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
The following piece of code does not finish executing (been more than 10 minutes and it is still running). If I remove the user.transfer line, everything works.
async def player_swap(players_out, players_in):
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
await fpl.login(email=os.environ['email'], password=os.environ['password'])
user = await fpl.get_user(5645003)
await user.transfer([players_out], [players_in], max_hit=100)
if __name__ == "__main__":
asyncio.run(player_swap(303, 164))
Hey I keep getting Nonetype when I try to run the basic tests. I'm pretty sure I've done everything right. Could it be that the endpoints are not updated for the new season?
Thanks!
Is there a reason that the code needs to store '_session' as an attribute in the Player class?
It seems that games_played() is the only function that uses this attribute but could be changed not to use it.
This is an issue for me as:
I am trying to cache the player data using pickle, but I am unable to pickle the Players in their current form due to the '_session' attribute, as I get the error:
AttributeError: Can't pickle local object 'WeakSet.init.._remove'
Hello,
This is my code:
from fpl import FPL
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
await fpl.login()
user = await fpl.get_user(user_id = 4865323)
team = await user.get_team()
asyncio.run(main())
Error:
Exception: User ID does not match provided email address!
I can get this to work if I change the user_id
to mine but the intention of this code block is to see another player's team.
Thanks.
I see that there is already an option for that in constants.py
"user_picks": "{}entry/{{}}/event/{{}}/picks/".format(API_BASE_URL)
There should be an easy function to take my user_id and gameweek_id to return my team details of that particular gameweek.
Could not find this in the documentation. If this already exists please let me know
When you call this for a user who joined after GW1, it hangs.
If this is addressed (and no rush as far as I'm concerned) could a feature be added so that we get the gameweek of the picks returned too please?
It can be worked out as it returns in order 1-38, but would be nice to have an attribute. Especially if the user joined after GW1.
async def main():
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
user = await fpl.get_user(<A user who started after gameweek 1>)
picks = await user.get_picks()
if name == "main":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
headers = {"User-Agent": "https://github.com/amosbastian/fpl"} from util looks like the cause of this,
when changing user agent I was able to get the information
Hi - as I'm trying to get the tests to work, I was running into a lot of missing packages. I'm not familiar with a lot of the libraries used, (mock, Sanic, pytest addons) and think it would be great to add a list of these dependencies to the Contributing part of the docs. I know it would have made my life easier to pickup this project starting with a list of dependencies / recommended Python Version.
First of all, is there a standard way to find these things out after cloning the repo? If not, I can collect what I've found to be the suite of packages that you need to install before test will work and add it to the contributing page.
avoid unnecessary repeat requests
Hi!
After installing with pip install fpl I get the following error when importing fpl in Jupyter:
ModuleNotFoundError: No module named 'fpl.models'
How can I fix this?
Thanks!
First of all, thank you, @amosbastian for creating this awesome library. I have based my pandas-fpl library on it!
Currently, if a request to the API returns anything apart from status 200, the fpl will try retry indefinitely. This an occur in a number of different scenarios, e.g. an invalid ID passed as a parameter.
Here is the relevant code section from utils.py:
async def fetch(session, url):
while True:
try:
async with session.get(url) as response:
assert response.status == 200
return await response.json()
except Exception:
pass
Infinite looping is a problem because a) the client does not get the opportunity to deal with any issues and b) the FPL API gets bombarded with requests.
Would it not be better so at least have the option to set a retry limit and raise an exception if no success?
This is a feature request. I was looking for a live points notification system which would provide realtime updates about the matchday points. What do you think about the idea? If its okay I would like to work on this.
incl. live bonus, auto-subs, vice capt, and chips
I can't get the login function to work. Maybe fpl has changed something and the headers don't work?
The main league I play in is Draft and so I would love to be able to use this library for Draft.
From what I can see, some of the endpoints for draft are not just a case of replacing the fantasy.premierleague
with draft.premierleague
. I was hoping it would be as simple as adding a parameter to each class to change the endpoints to the draft version.
I can do a bit more research into which of the current classes that would support - I'm experimenting with the endpoints at the moment for a personal project so I think it would be great to extend this library as part of that project.
Currently, the get_fixtures method is not returning fixtures without game week, e.g. at the point of writing the fixture with id 379 is not returned because it is not scheduled yet and therefore has no game week. The current implementation of the function iterates over all game week and retrieves the fixtures for these game weeks.
Should the method not simply return all fixtures as per below?
async def __fpl_get_fixtures(self, return_json=False):
"""Returns a list of *all* fixtures.
Information is taken from e.g.:
https://fantasy.premierleague.com/api/fixtures/
https://fantasy.premierleague.com/api/fixtures/?event=1
:param return_json: (optional) Boolean. If ``True`` returns a list of
``dict``s, if ``False`` returns a list of :class:`Fixture`
objects. Defaults to ``False``.
:type return_json: bool
:rtype: list
"""
fixtures = await fetch(self.session, API_URLS["fixtures"])
if return_json:
return fixtures
return [Fixture(fixture) for fixture in fixtures]
Use the property decorator instead of getters where applicable
Use the async_cached_property decorator instead of getters where applicable
First of all great library and documentation to know insights of the fpl.
Issue: Seems like API endpoints change from time to time. Even though most of the endpoints are working fine, but still some of them do not work. Can you provide a generalized way to confirm the endpoint if they change in the future.
thanks
Hi,
I have been using FPL python package for last 3-4 months, since last week I'm getting this exception . I'm not sure am I the only one getting it?
for example:
Here is my simple API call:
from fpl import FPL
async def main():
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
print('getting players')
players = await fpl.get_players(return_json=True)
Traceback (most recent call last):
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\urllib\request.py", line 1346, in do_open
h.request(req.get_method(), req.selector, req.data, headers,
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\http\client.py", line 1257, in request
self._send_request(method, url, body, headers, encode_chunked)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\http\client.py", line 1303, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\http\client.py", line 1252, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\http\client.py", line 1012, in _send_output
self.send(msg)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\http\client.py", line 952, in send
self.connect()
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\http\client.py", line 1426, in connect
self.sock = self._context.wrap_socket(self.sock,
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\ssl.py", line 1040, in _create
self.do_handshake()
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1129)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\apidigger\python\fpltweet\fplbasic.py", line 23, in
asyncio.run(main())
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\asyncio\base_events.py", line 642, in run_until_complete
return future.result()
File "C:\Users\apidigger\python\fpltweet\fplbasic.py", line 10, in main
fpl = FPL(session)
File "C:\Users\apidigger\python\fpltweet\venv\lib\site-packages\fpl\fpl.py", line 50, in init
static = json.loads(urlopen(API_URLS["static"]).read().decode("utf-8"))
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\urllib\request.py", line 214, in urlopen
return opener.open(url, data, timeout)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\urllib\request.py", line 517, in open
response = self._open(req, data)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\urllib\request.py", line 534, in _open
result = self._call_chain(self.handle_open, protocol, protocol +
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\urllib\request.py", line 494, in call_chain
result = func(*args)
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\urllib\request.py", line 1389, in https_open
return self.do_open(http.client.HTTPSConnection, req,
File "c:\users\apidigger\appdata\local\programs\python\python39\lib\urllib\request.py", line 1349, in do_open
**raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (**ssl.c:1129)>
Thanks
regards
Hi! Thanks for making this wrapper!
Everything worked well for a while until I started to get 403 when calling fpl.login
:
Traceback (most recent call last):
File "./scripts/fetch_league.py", line 389, in <module>
asyncio.run(
File "/Users/owh/.pyenv/versions/3.8.1/lib/python3.8/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/Users/owh/.pyenv/versions/3.8.1/lib/python3.8/asyncio/base_events.py", line 612, in run_until_complete
return future.result()
File "./scripts/fetch_league.py", line 88, in fetch_league_data
await fpl.login(email, password)
File "/Users/owh/code/fplstats/env/lib/python3.8/site-packages/fpl/fpl.py", line 634, in login
state = response.url.query["state"]
KeyError: 'state'
As you can se there's also a minor bug when the login fails, but that's not important. I'm more interested in how to solve the 403 issue, if possible.
The printed response looks like this:
<ClientResponse(https://users.premierleague.com/accounts/login/) [403 Forbidden]>
<CIMultiDictProxy('Connection': 'keep-alive', 'Content-Length': '545', 'Server': 'nginx/1.18.0', 'Content-Type': 'text/html;charset=utf-8', 'X-DataDome': 'protected', 'Accept-CH': 'Sec-CH-UA,Sec-CH-UA-Mobile,Sec-CH-UA-Platform,Sec-CH-UA-Arch,Sec-CH-UA-Full-Version-List,Sec-CH-UA-Model,Sec-CH-Device-Memory', 'Charset': 'utf-8', 'Cache-Control': 'max-age=0, private, no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Expose-Headers': 'x-dd-b, x-set-cookie', 'Access-Control-Allow-Origin': '*', 'X-DataDome-CID': 'AHrlqAAAAAMAvbyOxC2A3d4Aw4t9vA==', 'Set-Cookie': 'datadome=V9jlyTq9myIzxBdSfq0u59~EyY0.93SxLjV7PZeSGBZZ-_1-pc3_p.KT9dnGU84mNeFTM1F2.itU8p1-zt0wurVOBSI2vGvm~4_3YOBnjnZiEnzxhCH0YOFICFeGvW9; Max-Age=31536000; Domain=.premierleague.com; Path=/; Secure; SameSite=Lax', 'Via': '1.1 google, 1.1 varnish', 'Accept-Ranges': 'bytes', 'Date': 'Sun, 15 May 2022 15:06:49 GMT', 'X-Served-By': 'cache-cph20628-CPH', 'X-Cache': 'MISS', 'X-Cache-Hits': '0')>
Any idea how I can avoid getting 403 on logins? I guess it could be a security mechanism they use to block suspicious logins.. ๐ค
Hello,
The login seems to work but can't get any details from the classic leagues, even after logged in. Thought that they changed the link but it is still the same. I was working on a fetching the data from API from scratch and then suddenly found this repository, thought it would work, but it is not unfortunately. Could you confirm, if it is working for you, if so would like to know, what am i doing wrong.
Should return the number of games where the minutes played by the relevant player is greater than 0
Returns 0 for all players
I think this happens because the fixtures attribute that games_played uses doesn't exist because the data needed has moved to a different endpoint.
Using "https://fantasy.premierleague.com/api/element-summary/player_ID/" and returning
sum([1 for match in player["history"] if match["minutes"] > 0])
gives the desired result
Hello, i just checked your lovely project and i discovered you have some sections missing out like FAQ, about us, contact us and privacy policy. If you dont mind i will like to write that for you.
My email: [email protected]
for each fixture, based on live bps
Team IDs only work for last season's teams. Either the function team_converter
should be updated to reflect current teams or the PL(Replace relegated with promoted ones) or the function should always try to fetch the name from the ID)
Add a transfer function to transfer a player for another player.
Currently the CLI is broken because the functions aren't awaited. I am guessing you need to add some kind of decorator to the functions to make this work with asyncio.
Just a heads up
On Python 3.4.8 & fpl==0.5.0
to fpl.py i had to ammend the top of the file to
import sys
sys.path.append('/usr/lib/python3.4/site-packages/fpl')
from constants import API_URLS
from classic_league import ClassicLeague
#from fixture import Fixture
from gameweek import Gameweek
from h2h_league import H2HLeague
from player import Player
from team import Team
from user import User
to get it working
great stuff though :)
Hi there! Thanks so much for this work! I'm a bit of a beginner so I'm not sure if I'm doing something very stupid. In that case, apologies for wasting your time.
My code was working a few days ago; it's just a simple download all players. Now I get the error:
File "fpl_load.py", line 13, in
asyncio.run(save_player())
File "/anaconda3/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/anaconda3/lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete
return future.result()
File "fpl_load.py", line 9, in save_player
players = await fpl.get_player(150)
File "/anaconda3/lib/python3.7/site-packages/fpl/fpl.py", line 219, in get_player
players = players["elements"]
TypeError: 'NoneType' object is not subscriptable
The code I ran was: (I imported all modules above)
async def save_player():
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
players = await fpl.get_player(150)
with open('player_data.pkl', 'wb') as output:
#pickle.dump(players, output, pickle.HIGHEST_PROTOCOL)
asyncio.run(save_player())
The code in the quickstart example uses asyncio.run()
, however the run
method was only added in Python 3.7.
The Python 3.6 equivalent might be something like:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Hey,
I was trying out the Optimal captain choice example but the enum is not working since its not picking the values from the dictionary:
Old code:
for i, elements in enumerate(picks):
gameweek = i + 1
Fix:
for i, elements in enumerate(picks.values()):
gameweek = i + 1
Seems the previous api endpoints are not working with the new season. Getting 404 error and the lib seems to be broken.
Using TAA as an example, he got 185 points over 2460 mins which should give 6.77 pp90, however the actual returned value is 0.075. Off by exactly a factor of 90
async with aiohttp.ClientSession() as session:
fpl = FPL(session)
await fpl.login(email=email, password=password)
user = await fpl.get_user(?????????)
I want to automatically set id for logged in user. Is there a way to get this ID after I call login()?
Can we get a list of scores obtained by a player in the previous FPL years ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.