How I built a live-updating Jeff Bezos wealth tracker web app (incl. code)

Lockdown fun — Building a web app compare Bezos’ growing fortune with the society’s (not quite) fortunes. (Also, help me donate more to food banks.)

Photo by Bryan Angelo on Unsplash

In this article, I will show you how to use an API to get up-to-date information, generate figures, and build a simple web app which will automatically update the displayed data live — like this!

Here’s one I made earlier

Background

I’ve written a bit more than usual about my motivation for writing this piece — if you’re just interested in the web app and the code, feel free to skip this section, and go to “Before we get started”.

It’s mid-April 2020 as I write this. Like many of you, I have been in lockdown for the past four weeks or so. At least according to the calendar, that is — because let’s be honest; if I didn’t have the Internet, I couldn’t tell you if it’s been two weeks or eight years. It certainly feels a lifetime ago that I was able to go out to be around strangers, touch random stuff in stores, or sit down on a park bench and eat a kebab without being hit with a fine.

But, all things considered, I’ve been pretty lucky to have a safe space to be isolated to and have some steady income. Many have not been as lucky.

COVID-19’s impact is likely to be more significant among the less affluent. In the United States alone, twenty million people have filed jobless claims in the last month with unemployment estimated to already have hit 15%, which is of course going to impact the less affluent more significantly. Even for children, it is said to exacerbate existing inequalities through mechanisms such as food insecurity and widening learning gaps.

It’s not all bad news for everyone, of course. Someone is always making money off something. In this case, the lockdown has proved a boon for Amazon, which translated to quite a run of fortune for the currently richest person in the world, Jeff Bezos.

According to Forbes, Mr. Bezos owns about 11.2% of Amazon, whose stock price has ballooned from US$1,875 to US$2,375 just in 2020. Given that there are 498 million Amazon shares outstanding (i.e. circulating), Amazon is now worth well over a trillion dollars, and Mr. Bezos’ Amazon stock value has increased by a tidy US$26.6 billion in 2020 to over US$130 billion dollars.

That averages out to about US$250 million dollars a day that Jeff Bezos has made in 2020 — while tens of millions of people across the world have lost their jobs, or worse. Sure, he has pledged to donate US$100 million to feed the hungry during this time. It is a nice gesture and certainly will have an impact. But, that figure is not even half of what he has made in a single day just from his Amazon ownership.

So, I thought it would be interesting to put Jeff Bezos’ obscene earnings during this global health and economic crisis to other indicators such as unemployment, the number of COVID-19 patients, or the typical U.S. individual income. That’s exactly what we are going to do in this article.

Twenty million people in the U.S. have filed jobless claims in the last month with unemployment estimated to already have hit 15% … while Bezos’ Amazon stock value has increased by US$27.9 billion in early 2020.

I learned a lot (and not just about coding) putting this together, and I hope you get something useful out of it, or at least find it interesting.

Before we get started

I assume you’re familiar with python. Even if you’re relatively new, this tutorial shouldn’t be too tricky.

Code

As usual, I include the code and any data that I’ve used here. You can find it on my GitHub repo here.

Packages

To follow along, you’ll need pandas , requests , plotly and dash . Install each (in your virtual environment) with a simple pip install [PACKAGE_NAME] .

If you would like to reproduce the full app, you’d probably also like to use fredapi and dash_bootstrap_components .

Tracking Amazon

Gather data

Here, our calculation of Jeff Bezos’ net worth is going to be simply based on his Amazon ownership. So, we’re going to need some way of following Amazon’s stock price.

We’ll use the free tier API from a financial data service called Tiingo, which I have had good experiences with. (If you haven’t got an account with them, you can sign up or read their documentation here.)

Once you have a login, it’s very simple to get the stock price data:

import requests

headers = {'Content-Type': 'application/json'}

amzn_resp = requests.get("https://api.tiingo.com/tiingo/daily/amzn/prices?startDate=2020-01-01&token=" + tkn, headers=headers)

This will return all end-of-day prices from January 1, 2020, and if the request was successful, amzn_resp.json() will show you the resulting list of dictionaries.

I also converted the resulting data to a DataFrame, and built in some messages. All in all, my code is:

The resulting DataFrame should look like this:

Process data

We can quickly plot this data to inspect it:

fig = px.scatter(amzn_df, x='date', y='close', template='ggplot2')

fig.update_traces(mode='lines+markers')

fig.update_xaxes(rangebreaks=[dict(bounds=["sat", "mon"])]) # hide weekends

fig.show()

And just as a sanity test — let’s check it against Yahoo! Fiance data.

Comparing our charts vs Yahoo! Finance

Great! So we’ve verified that we’ve got the right data source. Let’s convert this Amazon stock price data to data indicating Jeff Bezos’ wealth. It’s pretty simple arithmatic — we know that there are 498 million Amazon shares out there, and Mr. Bezos owns 11.2% of them. So:

amzn_df = amzn_df.assign(bezos_bucks=amzn_df.close * 498 * 10**6 * 0.112)

That does it. The latest figure — as of April 17, 2020 — Mr. Bezos’s Amazon shares are worth a lazy 132 billion U.S. dollars.

Let’s calculate two more columns to plot — one is Mr. Bezos’ increase in net worth for the last week, and the second is his increase in net worth for the year to date.

We can also plot this data, very similarly to what we did above.

Changes to Jeff Bezos’ Amazon fortune — year to date in 2020

Perfect. So we have a data source which can be updated periodically to get the latest data.

Now, let’s use Plotly Dash to turn that to a live web application. Importantly, here, you will also see how to use Dash to update the data without any other intervention — manually refreshing, programming a cron job, or whatever.

Putting it online

As I’ve written in another article, I am a fan of Plotly Dash which simplifies many aspects of constructing a web dashboard app.

For example, Dash uses “callback applications” to automatically update its outputs based on user interaction (e.g. change to a pulldown menu selection). Another useful aspect of Dash is its ability to automatically update its data.

So, for this tutorial let’s focus on that aspect of Dash which allows us to automatically update the displayed data.

(If you are not familiar with Dash at all, I recommend reading my previous article.)

The mechanics of automatically updating data in Dash is quite simple, actually. Its dcc.Interval component does most of the hard work for us (documentation). It is essentially a timer that can be used to trigger a callback function.

I’ve put together a rough code outline to use this module below, where the parameter n_intervals is the value that triggers the callback.

For a concrete example, take a look below, where I use it to update the stock price every hour:

Update Bezos’ year-to-date profit

The above layout has been updated here to download the latest Amazon stock price, generate a DataFrame, and to plot the estimated year-to-date increase in Mr. Bezos’ net worth:

That’s quite a chunk of code, but the logic is as follows. The callback function @app.callback is monitoring the dcc.Interval module as one of its inputs ( Input(‘bezos-graph-interval’, ‘n_intervals’ )).

Because the dcc.Interval module is defined with the parameter interval=60 * 60 * 1000 , it is triggered once every hour (the unit being milliseconds). When it is activated, it triggers the associated callback function, which in turn calls the update_graph function that it wraps around.

This way, the chart will update automatically with the latest data.

Second by second updates

Updating stick charts is fine, but it’s not very dynamic-looking. The stock price and associated stats don’t change all that quickly over time, especially relative to the overall value.

For this demonstration, let’s build something a bit more visually impactful. How about we update our app to show some statistics based on time spent on our web app, starting with the amount of time the user has spent on the site.

We are going to create a new div where the updated content will go, and a new interval module with a one second interval parameter.

html.Div([

html.Div(id='bezos_text', children=[]),

dcc.Interval(

id='bezos_text-interval',

interval=1000, # in milliseconds

n_intervals=0

)

]),

And the callback / update function will look like this:

@app.callback(Output('bezos_text', 'children'),

[Input('bezos_text-interval', 'n_intervals')])

def update_bezos_text(n):

return [f'Hi, you have been on this page for {n} seconds. In that time:']

I have updated the formatting a bit also. The resulting output is this simple animation!

Live-updating output

This will simply display the value n as a variable as it increments. Adding a counter adds a dynamic element to the web app!

We can expand on the idea, to introduce more dynamic components.

I have also obtained the unemployment filings in the U.S., the typical annual per-capita income in the U.S., and contrast this with the average amount of money that Bezos has made over the course of 2020 to date.

For brevity, I won’t show the full code here. Much of it is formatting, using dash-bootstrap-components anyway. The principle is really absolutely the same as what I showed above for the simple, single number update. It’s just that here I have done some simple arithmetic and formatted the outputs.

For example, the per-second numbers are calculated with:

bezos_secondly = round(amzn_df.iloc[-1].bezos_year / ytd_seconds)

bezos_tot = bezos_secondly * n

unemp_secondly = round(sum(unemp_df.unemployment[-3:]) / (3 * 7 * 24 * 60 * 60), 1)

And each card is produced with code such as this:

After adding some words and additional Bootstrap CSS formatting, our web app looks like this:

We’ve got a live dashboard!

(To see the entire code, check out my GitHub repository for the full code.)

I’ve added a few graphs also: one of Bezos’ net worth as we discussed above, and another showing the weekly unemployment figures. The app downloads the latest unemployment figure from the FRED API , using the fredapi package.

I will leave that to you as an exercise — as always, feel free to look at my code for my implementation.

So, the finished site looks like this:

Finished site layout

That was probably enough for today. I’d like to wrap it up there!