As mentioned in my task request I have been getting a lot of emails about fpl from users and developers, so I have started working on it again. The Premier League season has also started again, so some of my gained motivation stems from that as well. Since it has been a while since I last worked on this package I have updated and refactored quite a lot, as I like to think that I have improved my programming during that time. I have also added some new functions, classes and more!
What is fpl?
It's a Python wrapper for the Fantasy Premier League API. For those who don't know what the Fantasy Premier League is, it's basically a game where you score points depending on the performance of your players in real life in the Premier League. It's quite popular on here and overall there are about 5 million players worldwide and I personally love it!
The big refactor
I think fpl was the first Python package I had ever uploaded to PyPi, so its structure wasn't very optimal. It actually did contain unit tests, but only for the FPL class and they weren't up to date, which is far from ideal. Furthermore some properties were missing from classes, there wasn't a way to retrieve your current team, you couldn't retrieve a singular player, but needed to retrieve all of them (takes a long time) and more... so this needed to be fixed!
Properties and structure
The first thing I did was change the folder structure and add a file where I could save all the URLs (constants.py) instead of declaring them in each class separately. Going through the Fantasy Premier League website with Chrome's network console open I found some additional endpoints so they were added as well. I also realised some classes were missing properties for some reason, so these were included too.
Adding the login function
The login function actually already existed in the H2HLeague class, but only for retrieving a league's fixtures. I've now moved it to the FPL class, so users can either log in with their email and password, or set environment variables and log in automatically. This is important because you need to be logged in to retrieve your current team (otherwise others can simply copy your team). Now this can be done using the my_team() function in the User class after logging in!
It returns what?!
As I was checking the unit tests I had written months ago I realised that in some places where you were for example expecting a Player object to be returned, it was returning a dictionary instead. I made sure this time that where you expect an object to be returned, it actually is the case.
Updating all the classes and unit testing
Not only were some properties missing from the classes, but also some functions that make them easier to use. I went through each and every class, added functions that I thought would be useful (if applicable) and then also added unit tests. This took quite a while, but it's definitely nice knowing that changing something doesn't completely break the code.
The User class now contains the my_team() function as I already touched on earlier. It also includes new properties, one of which is the user's watchlist, which is very useful.
A Player object can also now be made by simply passing the player's ID instead of having to retrieve ALL players and then iterating over them to find the one you want. This saves a lot of time, as there are loads of requests that need to be made to retrieve all this information.
The Team class now has a function to retrieve a list of all players (objects) that are playing for the team as well. This is one of those functions that I think should've been there from the start, but at least it's there now!
Both the ClassicLeague and H2HLeague were both missing properties as well, so those were added as well, but other than that, not much changed.
I've set up Travis CI as well, because in the future I really want to look for other contributors and so this was a small, but important addition. Since I had never used it in one of my own projects before, I was actually surprised how easy and quick it was to set up.
This also means I was able to check if everything is compatible with different versions of Python. So I checked for 2.7 and 3.3+, and it seems everything should work fine on those versions.
The Fixture class
In this update I've added the Fixture class, alongside functions in the FPL class to retrieve all fixtures (of a specific gameweek) and a specific fixture. It includes functions to retrieve who scored, assisted etc. during the fixture and all the additional properties that you would expect to see in a fixture. Of course I also wrote some unit tests for this class.
I have quite a few ideas that I want to work on, and so I'll list a couple of them below:
- Currently it's very slow having to retrieve all players, since it requires quite a lot of requests to get all the required information. Locally I have set up a database that syncs itself once a day, and I am doing some research if I could somehow implement this in the package itself. If you have any idea how I could do this, please let me know!
- Add a CLI - I think it would be really cool to see your team with your player's points live in your terminal for example!
- Create a function that linearly optimises a team based on a budget and a given metric - I've done something similar before and I think it would be an amazing feature to add.
- Update its documentation as it is pretty out of date at the moment.
- Read Fluent Python and use that to improve EVERYTHING (it finally arrived)!