python-eia 0.2.1__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eia/.agents/skills/eia/SKILL.md +115 -119
- eia/__init__.py +3 -1
- eia/cache.py +399 -0
- eia/catalog.py +137 -0
- eia/catalog_manager.py +464 -0
- eia/cli/app.py +4 -0
- eia/cli/cache_cmd.py +53 -0
- eia/cli/catalog_cmd.py +186 -0
- eia/client.py +309 -19
- {python_eia-0.2.1.dist-info → python_eia-0.3.0.dist-info}/METADATA +7 -3
- python_eia-0.3.0.dist-info/RECORD +22 -0
- python_eia-0.2.1.dist-info/RECORD +0 -17
- {python_eia-0.2.1.dist-info → python_eia-0.3.0.dist-info}/WHEEL +0 -0
- {python_eia-0.2.1.dist-info → python_eia-0.3.0.dist-info}/entry_points.txt +0 -0
eia/.agents/skills/eia/SKILL.md
CHANGED
|
@@ -1,56 +1,139 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eia
|
|
3
3
|
description: Query U.S. energy data (EIA API v2). Use when the user asks about U.S. electricity, petroleum, natural gas, or coal data from the EIA.
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# EIA Data Assistant
|
|
8
8
|
|
|
9
|
-
You have access to the `python-eia`
|
|
9
|
+
You have access to the `python-eia` library and CLI for querying the U.S. Energy Information Administration (EIA) API v2.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## When to use what
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
- **Python scripts** (default): reproducible, composable, saveable. Use for any data work the user will want to keep or iterate on.
|
|
14
|
+
- **CLI**: quick one-shot lookups, exploration, sanity checks. Use when the user wants a fast answer they won't need again.
|
|
15
|
+
- **If unsure**: ask the user whether they want a script or a quick CLI check.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
## Built-in Catalog (OFFLINE — no API calls)
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
The library ships with a YAML catalog containing full API schema for curated routes: columns, frequencies, periods, and **all facet values**. Always check the catalog first to avoid unnecessary API calls.
|
|
20
|
+
|
|
21
|
+
### Cataloged Routes
|
|
22
|
+
|
|
23
|
+
| Route | Description | Frequency |
|
|
24
|
+
|-------|-------------|-----------|
|
|
25
|
+
| `electricity/rto/fuel-type-data` | Real-time grid generation by fuel type | hourly |
|
|
26
|
+
| `electricity/rto/region-data` | Real-time grid demand/generation by region | hourly |
|
|
27
|
+
| `electricity/rto/interchange-data` | Real-time interchange between regions | hourly |
|
|
28
|
+
| `electricity/retail-sales` | Retail electricity sales by state/sector | monthly |
|
|
29
|
+
| `petroleum/pri/spt` | Spot petroleum prices (crude, gasoline, etc.) | daily |
|
|
30
|
+
| `natural-gas/pri/sum` | Natural gas prices summary | monthly |
|
|
31
|
+
| `natural-gas/move/expc` | US natural gas exports by country | monthly |
|
|
32
|
+
| `natural-gas/move/impc` | US natural gas imports by country | monthly |
|
|
33
|
+
| `total-energy/data` | Total energy overview (production, consumption, etc.) | monthly |
|
|
34
|
+
|
|
35
|
+
For routes **not** in the catalog, use `eia routes` (CLI) to discover and `eia meta` to inspect.
|
|
36
|
+
|
|
37
|
+
## Python Library (default)
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from eia import EIAClient
|
|
41
|
+
|
|
42
|
+
client = EIAClient() # reads config file, then EIA_API_KEY env var
|
|
43
|
+
|
|
44
|
+
# --- Catalog access (offline, no API calls) ---
|
|
20
45
|
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
# Get endpoint with cached schema — no API metadata call
|
|
47
|
+
data = client.get_data_endpoint("electricity/rto/fuel-type-data")
|
|
48
|
+
|
|
49
|
+
# Inspect metadata (all cached for cataloged routes)
|
|
50
|
+
data.facets # FacetContainer with attribute access
|
|
51
|
+
data.frequencies # List[FrequencyInfo]
|
|
52
|
+
data.data_columns # Dict[str, DataColumnInfo]
|
|
53
|
+
data.start_period # "2019-01-01T00"
|
|
54
|
+
data.end_period # "2026-03-04T07"
|
|
55
|
+
|
|
56
|
+
# Facet values — cached, no API call
|
|
57
|
+
respondents = data.facets.respondent.get_values()
|
|
58
|
+
# [FacetValue(id='CISO', name='California ISO'), ...]
|
|
59
|
+
|
|
60
|
+
fuel_types = data.facets.fueltype.get_values()
|
|
61
|
+
# [FacetValue(id='SUN', name='Solar'), ...]
|
|
62
|
+
|
|
63
|
+
# Or access catalog directly
|
|
64
|
+
from eia.catalog import get_route, list_routes
|
|
65
|
+
route = get_route("electricity/rto/fuel-type-data")
|
|
66
|
+
route.data_columns # (DataColumn(id='value', units='megawatthours', ...),)
|
|
67
|
+
route.frequencies # (Frequency(id='hourly', ...), Frequency(id='local-hourly', ...))
|
|
68
|
+
route.facets[0].values # {'CISO': 'California ISO', 'PJM': 'PJM Interconnection LLC', ...}
|
|
69
|
+
|
|
70
|
+
# --- Fetch data (hits API) ---
|
|
71
|
+
|
|
72
|
+
df = data.get(
|
|
73
|
+
data_columns=["value"],
|
|
74
|
+
facets={"respondent": "CISO"},
|
|
75
|
+
frequency="hourly",
|
|
76
|
+
start="2024-01-01",
|
|
77
|
+
end="2024-01-31",
|
|
78
|
+
sort=[{"column": "period", "direction": "desc"}],
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Multiple facet values
|
|
82
|
+
df = data.get(
|
|
83
|
+
data_columns=["revenue", "sales"],
|
|
84
|
+
facets={"stateid": "CA", "sectorid": ["RES", "COM"]},
|
|
85
|
+
frequency="monthly",
|
|
86
|
+
start="2024-01-01",
|
|
87
|
+
end="2024-12-31",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# --- Route tree navigation (for discovery — hits API) ---
|
|
91
|
+
route = client.route("electricity/rto/fuel-type-data")
|
|
92
|
+
route.routes # Dict of child routes (if branch node)
|
|
93
|
+
route.data # Data object (if leaf node)
|
|
25
94
|
```
|
|
26
95
|
|
|
27
|
-
###
|
|
96
|
+
### Facet conventions
|
|
97
|
+
|
|
98
|
+
- **Common facets**: `respondent` (grid operator), `fueltype`, `stateid`, `sectorid`, `series`
|
|
99
|
+
- **Multiple values**: pass a list — `facets={"sectorid": ["RES", "COM"]}`
|
|
100
|
+
- **Prefer catalog** for facet discovery: `get_route().facets[i].values` has all valid values offline
|
|
101
|
+
|
|
102
|
+
### Key conventions
|
|
103
|
+
|
|
104
|
+
- The `period` column is auto-converted to datetime (UTC for non-local frequencies)
|
|
105
|
+
- The `value` column is auto-converted to numeric
|
|
106
|
+
- Pagination is automatic by default (fetches all pages)
|
|
107
|
+
- API page limit is 5000 rows per request
|
|
108
|
+
- Custom exception: `EIAError` (includes HTTP status code and API error code)
|
|
109
|
+
|
|
110
|
+
## CLI Reference (quick lookups)
|
|
111
|
+
|
|
112
|
+
### Catalog (offline)
|
|
28
113
|
|
|
29
114
|
```bash
|
|
30
|
-
|
|
31
|
-
eia
|
|
32
|
-
eia
|
|
33
|
-
eia
|
|
115
|
+
eia catalog routes # List all cataloged routes
|
|
116
|
+
eia catalog show electricity/rto/fuel-type-data # Full details (columns, frequencies, facet values)
|
|
117
|
+
eia catalog recipes # Pre-configured query recipes
|
|
118
|
+
eia catalog recipe lng-exports-europe # Show a specific recipe
|
|
119
|
+
eia catalog refresh --apply # Refresh schema from API
|
|
34
120
|
```
|
|
35
121
|
|
|
36
|
-
###
|
|
122
|
+
### Explore (hits API)
|
|
37
123
|
|
|
38
124
|
```bash
|
|
39
|
-
#
|
|
40
|
-
eia
|
|
41
|
-
eia
|
|
42
|
-
eia facets
|
|
125
|
+
eia routes # Top-level routes
|
|
126
|
+
eia routes electricity/rto # Navigate deeper
|
|
127
|
+
eia meta electricity/rto/fuel-type-data # Endpoint metadata
|
|
128
|
+
eia facets electricity/rto/fuel-type-data respondent # Facet values
|
|
43
129
|
```
|
|
44
130
|
|
|
45
131
|
### Fetch data
|
|
46
132
|
|
|
47
133
|
```bash
|
|
48
|
-
# Basic query
|
|
49
134
|
eia get electricity/rto/fuel-type-data \
|
|
50
135
|
--start 2024-06-01 --end 2024-06-08 \
|
|
51
|
-
--frequency hourly
|
|
52
|
-
--facet respondent=CISO \
|
|
53
|
-
--data value
|
|
136
|
+
--frequency hourly --facet respondent=CISO --data value
|
|
54
137
|
|
|
55
138
|
# Multiple facet values (repeat --facet)
|
|
56
139
|
eia get electricity/retail-sales \
|
|
@@ -58,119 +141,32 @@ eia get electricity/retail-sales \
|
|
|
58
141
|
--facet stateid=CA --facet sectorid=RES --facet sectorid=COM \
|
|
59
142
|
--data revenue --data sales
|
|
60
143
|
|
|
61
|
-
# Export
|
|
144
|
+
# Export
|
|
62
145
|
eia get petroleum/pri/spt --start 2024-01-01 --end 2024-06-01 \
|
|
63
146
|
--format csv --output prices.csv
|
|
64
|
-
|
|
65
|
-
# Sort
|
|
66
|
-
eia get electricity/rto/fuel-type-data \
|
|
67
|
-
--start 2024-06-01 --end 2024-06-02 \
|
|
68
|
-
--frequency hourly --facet respondent=CISO --data value \
|
|
69
|
-
--sort period --sort-dir desc
|
|
70
147
|
```
|
|
71
148
|
|
|
72
|
-
###
|
|
149
|
+
### Exec (ad-hoc pandas)
|
|
73
150
|
|
|
74
151
|
```bash
|
|
75
|
-
# Descriptive stats
|
|
76
|
-
eia exec electricity/rto/fuel-type-data \
|
|
77
|
-
--start 2024-06-01 --end 2024-06-08 \
|
|
78
|
-
--frequency hourly --facet respondent=CISO --data value \
|
|
79
|
-
-x "df.describe()"
|
|
80
|
-
|
|
81
|
-
# Group by fuel type
|
|
82
152
|
eia exec electricity/rto/fuel-type-data \
|
|
83
153
|
--start 2024-06-01 --end 2024-06-08 \
|
|
84
154
|
--frequency hourly --facet respondent=CISO --data value \
|
|
85
155
|
-x "df.groupby('fueltype')['value'].mean()"
|
|
86
|
-
|
|
87
|
-
# Daily aggregation
|
|
88
|
-
eia exec natural-gas/pri/sum \
|
|
89
|
-
--start 2024-01-01 --end 2024-06-01 \
|
|
90
|
-
-x "df.groupby('process')['value'].mean().sort_values(ascending=False)"
|
|
91
156
|
```
|
|
92
157
|
|
|
93
|
-
### Output options
|
|
158
|
+
### Output options
|
|
94
159
|
|
|
95
160
|
```
|
|
96
161
|
--format table|csv|json (default: table)
|
|
97
162
|
--output file.csv (write to file instead of stdout)
|
|
98
163
|
```
|
|
99
164
|
|
|
100
|
-
## Common Routes
|
|
101
|
-
|
|
102
|
-
| Route | Description |
|
|
103
|
-
|-------|-------------|
|
|
104
|
-
| `electricity/rto/fuel-type-data` | Real-time grid generation by fuel type |
|
|
105
|
-
| `electricity/rto/region-data` | Real-time grid demand/generation by region |
|
|
106
|
-
| `electricity/rto/interchange-data` | Real-time interchange between regions |
|
|
107
|
-
| `electricity/retail-sales` | Retail electricity sales (monthly/annual) |
|
|
108
|
-
| `electricity/electric-power-operational-data` | Power plant operational data |
|
|
109
|
-
| `petroleum/pri/spt` | Spot petroleum prices (crude, gasoline, etc.) |
|
|
110
|
-
| `petroleum/sum/sndw` | Weekly petroleum supply/demand |
|
|
111
|
-
| `natural-gas/pri/sum` | Natural gas prices summary |
|
|
112
|
-
| `natural-gas/sum/lsum` | Natural gas supply/demand summary |
|
|
113
|
-
| `coal/shipments/receipts` | Coal shipments and receipts |
|
|
114
|
-
| `total-energy/data` | Total energy overview (monthly/annual) |
|
|
115
|
-
|
|
116
|
-
Use `eia routes` to discover more. Use `eia meta <route>` to see exact facets and frequencies.
|
|
117
|
-
|
|
118
|
-
## Facet Conventions
|
|
119
|
-
|
|
120
|
-
- **Format**: `--facet key=value` (repeatable)
|
|
121
|
-
- **Multiple values**: repeat the flag — `--facet sectorid=RES --facet sectorid=COM`
|
|
122
|
-
- **Common facets**: `respondent` (grid operator), `fueltype`, `stateid`, `sectorid`, `series`
|
|
123
|
-
- Each endpoint has different facets — use `eia meta` and `eia facets` to discover them
|
|
124
|
-
|
|
125
|
-
## Python Library
|
|
126
|
-
|
|
127
|
-
```python
|
|
128
|
-
from eia import EIAClient
|
|
129
|
-
|
|
130
|
-
client = EIAClient() # reads config file, then EIA_API_KEY env var
|
|
131
|
-
|
|
132
|
-
# Navigate the route tree
|
|
133
|
-
route = client.route("electricity/rto/fuel-type-data")
|
|
134
|
-
route.routes # Dict of child routes (if branch node)
|
|
135
|
-
route.data # Data object (if leaf node)
|
|
136
|
-
|
|
137
|
-
# Inspect metadata
|
|
138
|
-
route.data.facets # FacetContainer with attribute access
|
|
139
|
-
route.data.frequencies # List[FrequencyInfo]
|
|
140
|
-
route.data.data_columns # Dict[str, DataColumnInfo]
|
|
141
|
-
route.data.facets.respondent.get_values() # List[FacetValue]
|
|
142
|
-
|
|
143
|
-
# Direct access to a data endpoint
|
|
144
|
-
data = client.get_data_endpoint("electricity/rto/fuel-type-data")
|
|
145
|
-
|
|
146
|
-
# Fetch data as DataFrame
|
|
147
|
-
df = data.get(
|
|
148
|
-
data_columns=["value"],
|
|
149
|
-
facets={"respondent": "CISO"},
|
|
150
|
-
frequency="hourly",
|
|
151
|
-
start="2024-01-01",
|
|
152
|
-
end="2024-01-31",
|
|
153
|
-
sort=[{"column": "period", "direction": "desc"}],
|
|
154
|
-
)
|
|
155
|
-
```
|
|
156
|
-
|
|
157
165
|
## Configuration
|
|
158
166
|
|
|
159
167
|
```bash
|
|
160
|
-
# Store
|
|
161
|
-
eia config
|
|
162
|
-
|
|
163
|
-
# Verify it's stored
|
|
164
|
-
eia config get api-key
|
|
168
|
+
eia config set api-key YOUR_KEY # Store API key
|
|
169
|
+
eia config get api-key # Verify
|
|
165
170
|
```
|
|
166
171
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
## Key Conventions
|
|
170
|
-
|
|
171
|
-
- The `period` column is auto-converted to datetime (UTC for non-local frequencies)
|
|
172
|
-
- The `value` column is auto-converted to numeric
|
|
173
|
-
- Pagination is automatic by default (fetches all pages)
|
|
174
|
-
- API key resolution: config file (`~/.config/eia/config.toml`) > `EIA_API_KEY` env var
|
|
175
|
-
- API page limit is 5000 rows per request
|
|
176
|
-
- Custom exception: `EIAError` (includes HTTP status code and API error code)
|
|
172
|
+
Config file: `~/.config/eia/config.toml`. API key resolution: config file > `EIA_API_KEY` env var.
|
eia/__init__.py
CHANGED
|
@@ -5,6 +5,8 @@ A Python client for interacting with the U.S. Energy Information Administration
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from .client import EIAClient, EIAError
|
|
8
|
+
from .cache import CacheConfig
|
|
9
|
+
from . import catalog
|
|
8
10
|
|
|
9
11
|
__version__ = "0.1.0"
|
|
10
|
-
__all__ = ["EIAClient", "EIAError"]
|
|
12
|
+
__all__ = ["EIAClient", "EIAError", "CacheConfig", "catalog"]
|