Skip to content

Commit 9fe6467

Browse files
committed
Fix openei/utility_rates.py
1 parent efbfa39 commit 9fe6467

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

tariff_fetch/openei/base.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import datetime
12
from typing import Any
23
from urllib.parse import urljoin
34

@@ -11,12 +12,17 @@ def convert_params(input: dict[str, Any]) -> dict[str, Any]:
1112

1213

1314
def _convert_param(value):
14-
return {True: "true", False: "false"}.get(value, value)
15+
if isinstance(value, datetime.datetime):
16+
return int(value.timestamp())
17+
return value
18+
# return {True: "true", False: "false"}.get(value, value)
1519

1620

1721
def api_request_json(path: str, api_key: str, **params) -> dict | list:
1822
params_ = {"api_key": api_key, **convert_params(params)}
1923
url = urljoin(BASE_URL, path)
24+
print(url)
25+
print(params_)
2026
response = requests.get(url, params=params_)
2127
response.raise_for_status()
2228
return response.json()

tariff_fetch/openei/utility_rates.py

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import datetime
2+
from collections.abc import Iterator
13
from typing import Any, Literal, TypeAlias, TypedDict, cast
24

35
from typing_extensions import Unpack
@@ -17,6 +19,9 @@
1719
DistributedGenerationRule: TypeAlias = Literal[
1820
"Net Metering", "Net Billing Instantaneous", "Net Billing Hourly", "Buy All Sell All"
1921
]
22+
UtilityRateSector: TypeAlias = (
23+
Literal["Residential"] | Literal["Commercial"] | Literal["Industrial"] | Literal["Lighting"]
24+
)
2025
ScheduleMatrix: TypeAlias = list[list[int]]
2126
AttributeList: TypeAlias = list[dict[str, Any]]
2227

@@ -56,36 +61,58 @@ class EnergyRateTier(TypedDict, total=False):
5661
class UtilityRatesParams(TypedDict, total=False):
5762
"""Parameters for utility rates api"""
5863

64+
modified_after: datetime.datetime | int
65+
"Modified after, datetime or seconds since 1970-01-01T00:00:00, UTC. "
5966
limit: int
60-
" Maximum record count 500. "
61-
offset: int
62-
"The offset from which to start retrieving records."
67+
"Maximum record count 500"
6368
getpage: str
64-
"""Get a specific page name, i.e. getpage=535aeca39bef511109580ee1.
65-
This is referred to as 'label' in the results."""
69+
"""
70+
Get a specific page name, i.e. getpage=535aeca39bef511109580ee1.
71+
This is referred to as 'label' in the results.
72+
"""
6673
ratesforutility: str
67-
"""Get rates for a specific utility page name, i.e. ratesforutility=Detroit Edison Co.
68-
This value can be re-used from the "label" value in the utility_companies results."""
74+
"""
75+
Get rates for a specific utility page name, i.e. ratesforutility=Detroit Edison Co.
76+
This value can be re-used from the "label" value in the utility_companies results.
77+
"""
78+
offset: int
79+
"The offset from which to start retrieving records."
6980
orderby: str
70-
"Field to use to sort results. Default: label"
81+
"Field to use to sort results."
7182
direction: Literal["asc"] | Literal["desc"]
7283
"Direction to order results, ascending or descending."
73-
sector: Literal["Residential"] | Literal["Commercial"] | Literal["Industrial"] | Literal["Lighting"]
84+
effective_on_date: datetime.datetime | int
85+
"Effective on date, datetime or seconds since 1970-01-01T00:00:00, UTC."
86+
sector: UtilityRateSector
7487
"Shows only those rates matching the given sector."
7588
approved: bool
7689
"Shows only those rates whose approval status matches the given value."
90+
is_default: bool
91+
"Shows only those rates whose 'Is Default' status matches the given value."
92+
country: str
93+
"ISO 3 character country code, i.e. country=USA."
7794
address: str
7895
"Address for rate, see Google Geocoding API for details. Address or lat/lon may be used, but not both."
7996
lat: int
8097
"Latitude for rate. If set, lon must also be set and address must not."
8198
lon: int
8299
"Longitude for rate. If set, lat must also be set and address must not."
100+
radius: int
101+
"Radius to include surrounding search result, in miles. (min 0, max 200)"
102+
co_limit: int
103+
"Maximum number of companies to include in a geographic search (using lat/lon, or address)."
83104
eia: int
84105
"EIA Id to look up."
106+
callback: str
107+
"callback=<mycallback> - set mycallback as the json callback."
85108
detail: Literal["full"] | Literal["minimal"]
109+
"""
110+
detail=full - returns every variable. Since this results in a lot of data that can time-out
111+
returning to your server, use a limit=500 and set an offset (e.g. 501) if you want more data.
112+
"""
86113

87114

88-
class UtilityRatesResponse(TypedDict, total=False):
115+
class UtilityRatesResponseItem(TypedDict, total=False):
89116
label: str
90117
"Page label"
91118
utility: str
@@ -104,7 +131,7 @@ class UtilityRatesResponse(TypedDict, total=False):
104131
"End date timestamp"
105132
supercedes: str
106133
"Label of the rate this rate supercedes."
107-
sector: Literal["Residential"] | Literal["Commercial"] | Literal["Industrial"] | Literal["Lighting"]
134+
sector: UtilityRateSector
108135
"Sector"
109136
servicetype: ServiceType
110137
"Service type"
@@ -196,12 +223,33 @@ class UtilityRatesResponse(TypedDict, total=False):
196223
"Fixed charge attribute key/value pairs"
197224

198225

226+
class UtilityRatesResponse(TypedDict):
227+
items: list[UtilityRatesResponseItem]
228+
229+
230+
def iter_utility_rates(
231+
api_key: str,
232+
iter_offset: int = 0,
233+
format: Literal["json"] | Literal["json_plain"] | Literal["csv"] = "json",
234+
version: str = "latest",
235+
**kwargs: Unpack[UtilityRatesParams],
236+
) -> Iterator[UtilityRatesResponseItem]:
237+
offset = iter_offset
238+
rows = 1
239+
while rows:
240+
response = utility_rates(api_key, format, version, **{**kwargs, "offset": offset})
241+
items = response["items"]
242+
rows = len(items)
243+
offset += rows
244+
yield from items
245+
246+
199247
def utility_rates(
200248
api_key: str,
201249
format: Literal["json"] | Literal["json_plain"] | Literal["csv"] = "json",
202250
version: str = "latest",
203251
**kwargs: Unpack[UtilityRatesParams],
204-
) -> list:
252+
) -> UtilityRatesResponse:
205253
"""Access utility rate structure information from the U.S. Utility Rate Database
206254
207255
Args:
@@ -217,5 +265,6 @@ def utility_rates(
217265
in version 3 or greater.
218266
"""
219267
return cast(
220-
list, api_request_json(path=UTILITY_RATES_API_PATH, api_key=api_key, format=format, version=version, **kwargs)
268+
UtilityRatesResponse,
269+
api_request_json(path=UTILITY_RATES_API_PATH, api_key=api_key, format=format, version=version, **kwargs),
221270
)

0 commit comments

Comments
 (0)