Skip to content

Commit 30c2192

Browse files
committed
fix: rename columns and tz localization for empty dataframes
1 parent a3d9de9 commit 30c2192

4 files changed

Lines changed: 80 additions & 19 deletions

File tree

src/enappsys/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
to EnAppSys' API services.
44
"""
55

6-
__version__ = "0.1.7"
6+
__version__ = "0.1.8"
77

88
from enappsys.client import EnAppSys as EnAppSys
99
from enappsys.client_async import EnAppSysAsync as EnAppSysAsync

src/enappsys/services/bulk.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,34 +97,34 @@ def to_df(
9797
return pd.DataFrame()
9898

9999
df.index.name = "dateTime"
100+
step_size = 1
101+
if self.min_avg_max:
102+
step_size = 3
103+
100104
if df.empty:
101105
_warn_empty_response("csv", url=self.url, params=self.params)
102-
if remove_units_column and len(df.columns) > 0:
103-
df = df.iloc[:, 1:]
104-
return df
105-
106+
df.index = pd.DatetimeIndex([], name="dateTime")
107+
106108
if tz_localize:
107109
df.index = df.index.tz_localize(self.time_zone, ambiguous="infer")
108110

109-
step_size = 1
110-
if self.min_avg_max:
111-
step_size = 3
112-
113111
if rename_columns or data_type_in_columns or unit_in_columns:
114112
columns = list(df.columns)
115113

116114
if isinstance(rename_columns, list):
117115
# [:1] to not include Units when comparing with rename_columns
118116
validate_rename_columns_length(rename_columns, columns[1:], step_size)
119117

120-
# Units are in first column, for every row, so take first
121-
units_colon_delimited = df.iloc[0, 0]
122-
if not pd.isnull(units_colon_delimited):
123-
units = units_colon_delimited.split(":")
124-
if len(units) == 1:
125-
units = units * ((len(columns) - 1) // step_size)
126-
else:
127-
units = [""] * ((len(columns) - 1) // step_size)
118+
units = None
119+
if not df.empty:
120+
# Units are in first column, for every row, so take first
121+
units_colon_delimited = df.iloc[0, 0]
122+
if not pd.isnull(units_colon_delimited):
123+
units = units_colon_delimited.split(":")
124+
if len(units) == 1:
125+
units = units * ((len(columns) - 1) // step_size)
126+
else:
127+
units = [""] * ((len(columns) - 1) // step_size)
128128

129129
# Add datatype to "Units" column
130130
if data_type_in_columns:
@@ -140,7 +140,7 @@ def to_df(
140140
column_name = rename_columns[column_name]
141141
if data_type_in_columns:
142142
column_name = f"{self.data_type}.{column_name}"
143-
if unit_in_columns:
143+
if unit_in_columns and units is not None:
144144
column_name = f"{column_name} ({units[(idx - 1) // step_size]})"
145145

146146
if self.min_avg_max:

src/enappsys/services/chart.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ def to_df(
9090
df.index.name = "dateTime"
9191
if df.empty:
9292
_warn_empty_response("csv", url=self.url, params=self.params)
93-
elif tz_localize:
93+
df.index = pd.DatetimeIndex([], name="dateTime")
94+
if tz_localize:
9495
df.index = df.index.tz_localize(self.time_zone, ambiguous="infer")
9596

9697
step_size = 1

tests/unit/test_bulk_api.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import logging
66

7+
import pandas as pd
8+
79
from enappsys.services.bulk import BulkCSV, BulkJSON, BulkJSONMap
810
from enappsys.services.chart import ChartCSV, ChartJSON, ChartJSONMap
911

@@ -77,6 +79,8 @@ def test_empty_bulk_csv_to_df_returns_empty_dataframe(caplog):
7779
df = out.to_df()
7880

7981
assert df.empty
82+
assert isinstance(df.index, pd.DatetimeIndex)
83+
assert str(df.index.tz) == "UTC"
8084
assert list(df.columns) == ["BE.BELGIUM"]
8185
assert "returning empty DataFrame" in caplog.text
8286
assert "url=bulk" in caplog.text
@@ -87,6 +91,33 @@ def test_empty_bulk_csv_to_df_returns_empty_dataframe(caplog):
8791
assert "test-secret" not in caplog.text
8892

8993

94+
def test_empty_bulk_csv_to_df_applies_rename_columns(caplog):
95+
out = BulkCSV(
96+
"Datetime,Units,BE.BELGIUM\n",
97+
"bulk",
98+
{},
99+
"csv",
100+
"ENTSOE_DAY_AHEAD_PRICES",
101+
["BE.BELGIUM"],
102+
None,
103+
None,
104+
"hourly",
105+
"UTC",
106+
False,
107+
)
108+
109+
with caplog.at_level(logging.WARNING):
110+
df = out.to_df(
111+
data_type_in_columns=True,
112+
rename_columns=["be_dap"],
113+
)
114+
115+
assert df.empty
116+
assert isinstance(df.index, pd.DatetimeIndex)
117+
assert str(df.index.tz) == "UTC"
118+
assert list(df.columns) == ["ENTSOE_DAY_AHEAD_PRICES.be_dap"]
119+
120+
90121
def test_bulk_empty_warning_uses_full_url(client: "EnAppSys", monkeypatch, caplog):
91122
def fake_get(url, params):
92123
assert url == "csvapi"
@@ -135,13 +166,42 @@ def test_empty_chart_csv_to_df_returns_empty_dataframe(caplog):
135166
df = out.to_df()
136167

137168
assert df.empty
169+
assert isinstance(df.index, pd.DatetimeIndex)
170+
assert str(df.index.tz) == "UTC"
138171
assert list(df.columns) == ["BE.BELGIUM"]
139172
assert "returning empty DataFrame" in caplog.text
140173
assert "url=datadownload" in caplog.text
141174
assert "day-ahead-prices" in caplog.text
142175
assert "202301010300" in caplog.text
143176

144177

178+
def test_empty_chart_csv_to_df_applies_rename_columns(caplog):
179+
out = ChartCSV(
180+
"Datetime,BE.BELGIUM\n,EUR/MWh\n",
181+
"datadownload",
182+
{},
183+
"csv",
184+
"day-ahead-prices",
185+
None,
186+
None,
187+
"hourly",
188+
"UTC",
189+
"EUR",
190+
False,
191+
)
192+
193+
with caplog.at_level(logging.WARNING):
194+
df = out.to_df(
195+
rename_columns=["be_dap"],
196+
unit_in_columns=True,
197+
)
198+
199+
assert df.empty
200+
assert isinstance(df.index, pd.DatetimeIndex)
201+
assert str(df.index.tz) == "UTC"
202+
assert list(df.columns) == ["be_dap (EUR/MWh)"]
203+
204+
145205
def test_chart_empty_warning_uses_full_url(client: "EnAppSys", monkeypatch, caplog):
146206
def fake_get(url, params):
147207
assert url == "datadownload"

0 commit comments

Comments
 (0)