Getting Started with Powerful Data Tables in Your Python Web Apps | by Tom Gotsman | Oct, 2024

0
3


Setup

First we import the necessary libraries, including yfinance for fetching the stock data.

import reflex as rx
from reflex_ag_grid import ag_grid
import yfinance as yf
from datetime import datetime, timedelta
import pandas as pd

Fetching and transforming data

Next, we define the State class, which contains the application’s state and logic. The fetch_stock_data function fetches stock data for the specified companies and transforms it into a format suitable for display in AG Grid. We call this function when clicking on a button, by linking the on_click trigger of the button to this state function.

We define state variables, any fields in your app that may change over time (A State Var is directly rendered into the frontend of the app).

The data state variable stores the raw stock data fetched from Yahoo Finance. We transform this data to round the values and store it as a list of dictionaries, which is the format that AG Grid expects. The transformed data is sorted by date and ticker in descending order and stored in the dict_data state variable.

The datetime_now state variable stores the current datetime when the data was fetched.

# The list of companies to fetch data for
companies = ["AAPL", "MSFT", "GOOGL", "AMZN", "META"]

class State(rx.State):
# The data fetched from Yahoo Finance
data: pd.DataFrame
# The data to be displayed in the AG Grid
dict_data: list[dict] = [\{}]
# The datetime of the current fetched data
datetime_now: datetime = datetime.now()

def fetch_stock_data(self):
self.datetime_now = datetime.now()
start_date = self.datetime_now - timedelta(days=180)

# Fetch data for all tickers in a single download
self.data = yf.download(companies, start=start_date, end=self.datetime_now, group_by='ticker')
rows = []
for ticker in companies:
# Check if the DataFrame has a multi-level column index (for multiple tickers)
if isinstance(self.data.columns, pd.MultiIndex):
ticker_data = self.data[ticker] # Select the data for the current ticker
else:
ticker_data = self.data # If only one ticker, no multi-level index exists

for date, row in ticker_data.iterrows():
rows.append({
"ticker": ticker,
"date": date.strftime("%Y-%m-%d"),
"open": round(row["Open"], 2),
"high": round(row["High"], 2),
"mid": round((row["High"] + row["Low"]) / 2, 2),
"low": round(row["Low"], 2),
"close": round(row["Close"], 2),
"volume": int(row["Volume"]),
})

self.dict_data = sorted(rows, key=lambda x: (x["date"], x["ticker"]), reverse=True)

rx.button(
"Fetch Latest Data",
on_click=State.fetch_stock_data,
)