Do you use Splitwise? Monitor Expenses & Unlock Free Premium with Splitwise APIs!
18 / 7 / 2023
- api
- finance
- python
- splitwise
About a year ago, I started following some blogs that talk about personal finance. I immediately became interested in the topic and, after reading a lot of stuff, I felt the need to start putting into practice what I had learned from all those articles. The first obstacle was that I didn't have any data on my expenses, no Excel sheet, no database... or maybe I did. Actually, yes, because practically my wife and I have been using this fantastic application called Splitwise on a daily basis. It simplifies our lives a lot.
Okay, I have the data, but (second obstacle) I can't read it dynamically. The only thing Splitwise offers me with a free account is the ability to download a CSV file containing all the expenses of a single group. It's not enough for me to create graphs, apply formulas, and so on.
I immediately thought of using the Splitwise APIs, which are available for free: https://dev.splitwise.com/ ❤️ ... and so the Splitwired project began.
Backend
On the official Splitwise API page, there is a list of SDKs created by the community. While using these kits is not mandatory since Splitwise provides everything necessary, I chose to use the library by @namaggarwa. The SDK is written in Python, has good documentation, is continuously updated, and therefore, I consider it the best in the list.
The project was built with Flask and served with Gunicorn on Render. The backend part is entirely located within the /app
folder.
The auth.py
file is used to create the user authentication system in Flask using Flask-Login. An instance of LoginManager
is initialized and added to the Flask application. The Authentication
class is defined, which contains a dictionary of authenticated users and two class methods to verify the presence of the user and match the username and password. The user_loader function loads the data of the authenticated user, while the unauthorized function handles unauthorized
users by redirecting them to the login page.
The config.py
file contains the Config
class used to initialize four attributes: api_key
, environment
, consumer_key
, and consumer_secret
. These attributes are required to authenticate the Splitwise instance.
The data.py
file provides basic methods to access shared expense data using the splitwise
library. After creating an instance of Splitwise
using the values of the aforementioned config
attributes, there are two functions for retrieving data: the data_groups
function to get the data of the groups the user belongs to, and the data_expenses
function to return the shared expense data.
The utils.py
file contains functions related to data manipulation and the final creation of the expense list. The generate_expense
method serves this purpose. Based on a series of parameters, it generates an expense table, graphs, and a CSV file with the expense data.
The parameters of the function are:
csv
: a boolean value indicating whether to generate the CSV file or not.expenses
: the list of "expense" objects obtained from thegetExpenses
function of Splitwise.filename
: a string indicating the name of the CSV file to generate ifcsv
is True.category
: an integer value indicating the ID of the category to filter expenses to include in the table (only applies to the CSV file table since, in the application, I prefer to do the category filtering on the client side).personal
: a boolean value indicating whether to generate the table and chart only for personal expenses (i.e., all expenses from all groups the selected user is involved in).chart
: a string or a list indicating the types of charts to generate.
It's important to note that the computational cost for executing the function with the personal
parameter activated will be quite high. This is because this parameter triggers the process of creating the expense table by checking all the groups where the specified user ID is present, thus obtaining all the expenses in which that user has participated.
A recently added feature is the currency converter. I often go to the United States, and when I'm there, I prefer to pay in dollars rather than euros to avoid paying currency exchange fees. Therefore, I added the costs_conversions
function that allows me to convert and record my expenses in euros that I made and added to Splitwise in dollars. The conversion is done by scraping the Yahoo Finance portal using the yfinance library, which provides currency values at a specific historical moment. By providing the expense date, I can obtain the desired result. It is possible to convert any currency to euros. If you want to convert an expense to a currency other than euros, you just need to modify the ticker
variable in the set_currency_conversion
function.
import yfinance as yf
def set_currency_conversion(
amount: float,
curr_from: str,
conv_date: date,
):
ticker = f"{curr_from}EUR=X"
currency_data = yf.Ticker(ticker).history(
period="1d", start=conv_date, end=conv_date + timedelta(days=1)
)
if currency_data.empty or currency_data["Close"].size == 0:
return set_currency_conversion(
amount, curr_from, conv_date=conv_date - timedelta(days=1)
)
exchange_rate = currency_data["Close"][-1]
return str(exchange_rate * amount)
Well, in the end, the generate_expense
function returns a dictionary with three keys: table for the table, data for the data, and chart for the chart (if chart
is specified). If csv
is set to True, the generate_csv
function will be executed, generating a CSV file containing the expense data. The file can be downloaded from the download area at the top of the page.
Frontend
From the frontend perspective, there isn't much to say, just a few notes.
I started by configuring Webpack and setting up React. Then, I installed TanStack Table for table management and Plotly for creating graphs.
Finally, I added a service worker and a manifest.json file to enable installing the Progressive Web App (PWA) on a smartphone.
Conclusion
Splitwise is truly a valuable application. Over the past few years, it has made my life easier by handling all the calculations of debts and credits for me. Now, with this new little "extension" I created, I have achieved much more comprehensive control over my finances.
If you appreciated the article, give it a like on dev.to.