Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

BASE_URL = "https://api.eia.gov/v2/electricity/rto/daily-fuel-type-data/data/"


@st.cache_data(show_spinner=False)
def load_fuel_data(api_key: str, start: str, end: str) -> pd.DataFrame:
params = {
Expand All @@ -38,6 +39,7 @@ def load_fuel_data(api_key: str, start: str, end: str) -> pd.DataFrame:
rows = fetch_all_pages(BASE_URL, params)
return pd.json_normalize(rows)


with st.spinner("Loading data..."):
df = load_fuel_data(api_key, start, end)

Expand All @@ -51,9 +53,9 @@ def load_fuel_data(api_key: str, start: str, end: str) -> pd.DataFrame:
# Aggregation by date and fuel type
agg = (
df.groupby(["period", "type-name"], as_index=False)[ycol]
.sum()
.rename(columns={ycol: "Demand"})
) # type: ignore
.sum()
.rename(columns={ycol: "Demand"})
) # type: ignore

# Keep top N fuel types by total
agg = top_n_by_total(agg, "type-name", "Demand", top_n=top_n)
Expand Down
4 changes: 3 additions & 1 deletion eia_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import requests


def fetch_all_pages(base_url: str, params: dict[str, Any], timeout: int = 60) -> list[dict[str, Any]]:
def fetch_all_pages(
base_url: str, params: dict[str, Any], timeout: int = 60
) -> list[dict[str, Any]]:
all_rows: list[dict[str, Any]] = []
offset = 0
length = params.get("length", 5000)
Expand Down
2 changes: 1 addition & 1 deletion mainPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
pg = st.navigation([main_page, page_2])

# Run the selected page
pg.run()
pg.run()
97 changes: 52 additions & 45 deletions region.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,70 @@
import pandas as pd
import plotly.express as px

from data_utils import convert_units, filter_to_timezone, parse_period_and_value, top_n_by_total
from data_utils import (
convert_units,
filter_to_timezone,
parse_period_and_value,
top_n_by_total,
)
from eia_api import fetch_all_pages
st.set_page_config(page_title="EIA Demand by Region (ET)", layout="wide")
st.title("U.S. Electricity Demand by Region (Eastern Time)")
# API Key Retrieval
api_key = st.secrets.get("EIA_API_KEY", None)
# Predefine time and unit values
start = st.sidebar.text_input("Start date (YYYY-MM-DD)", value="2026-02-09")
end = st.sidebar.text_input("End date (YYYY-MM-DD)", value="2026-02-16")
units = st.sidebar.radio("Units", ["MWh", "GWh"], horizontal=True)

st.set_page_config(page_title="EIA Demand by Region (ET)", layout="wide")
st.title("U.S. Electricity Demand by Region (Eastern Time)")

# API Key Retrieval
api_key = st.secrets.get("EIA_API_KEY", None)

# Predefine time and unit values
start = st.sidebar.text_input("Start date (YYYY-MM-DD)", value="2026-02-09")
end = st.sidebar.text_input("End date (YYYY-MM-DD)", value="2026-02-16")
units = st.sidebar.radio("Units", ["MWh", "GWh"], horizontal=True)

BASE_URL = "https://api.eia.gov/v2/electricity/rto/daily-region-data/data/"

@st.cache_data(show_spinner=False)
def load_region_data(api_key: str, start: str, end: str) -> pd.DataFrame:
params = {
"api_key": api_key,
"frequency": "daily",
"data[0]": "value",
"start": start,
"end": end,
"sort[0][column]": "period",
"sort[0][direction]": "asc",
"offset": 0,
"length": 5000,
}
rows = fetch_all_pages(BASE_URL, params)
df = pd.json_normalize(rows)
return df

with st.spinner("Loading data from EIA..."):
df = load_region_data(api_key, start, end)



@st.cache_data(show_spinner=False)
def load_region_data(api_key: str, start: str, end: str) -> pd.DataFrame:
params = {
"api_key": api_key,
"frequency": "daily",
"data[0]": "value",
"start": start,
"end": end,
"sort[0][column]": "period",
"sort[0][direction]": "asc",
"offset": 0,
"length": 5000,
}
rows = fetch_all_pages(BASE_URL, params)
df = pd.json_normalize(rows)
return df


with st.spinner("Loading data from EIA..."):
df = load_region_data(api_key, start, end)

if df.empty:
st.warning("No data returned. Double-check your dates and API key.")
st.stop()

df = parse_period_and_value(df)

# Fix to Eastern Time
# Fix to Eastern Time
df = filter_to_timezone(df, "eastern")

df, ycol, ylabel = convert_units(df, units)

# Plot Graph
df = top_n_by_total(df, "respondent", "value", top_n=10)
region_col = "respondent"
fig = px.line(
df.sort_values("period"),
x="period",
y=ycol,
color=region_col,
title=f"U.S. electricity demand by region ({start} to {end}), Eastern Time",
labels={"period": "Date", ycol: ylabel, region_col: "Region"},
)
st.plotly_chart(fig, use_container_width=True)

fig = px.line(
df.sort_values("period"),
x="period",
y=ycol,
color=region_col,
title=f"U.S. electricity demand by region ({start} to {end}), Eastern Time",
labels={"period": "Date", ycol: ylabel, region_col: "Region"},
)
st.plotly_chart(fig, use_container_width=True)
11 changes: 9 additions & 2 deletions tests/test_data_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import pandas as pd

from data_utils import convert_units, filter_to_timezone, parse_period_and_value, top_n_by_total
from data_utils import (
convert_units,
filter_to_timezone,
parse_period_and_value,
top_n_by_total,
)


def test_convert_units_to_gwh_creates_scaled_column():
Expand Down Expand Up @@ -49,7 +54,9 @@ def test_top_n_by_total_keeps_only_largest_categories():


def test_parse_period_and_value_converts_types():
df = pd.DataFrame({"period": ["2026-02-01", "not-a-date"], "value": ["12.5", "oops"]})
df = pd.DataFrame(
{"period": ["2026-02-01", "not-a-date"], "value": ["12.5", "oops"]}
)
parsed = parse_period_and_value(df)
assert parsed["period"].notna().sum() == 1
assert parsed["value"].tolist()[0] == 12.5
Expand Down
Loading