python-eia 0.2.1__tar.gz → 0.3.0__tar.gz

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.
Files changed (39) hide show
  1. {python_eia-0.2.1 → python_eia-0.3.0}/.github/workflows/publish.yml +18 -4
  2. python_eia-0.3.0/.release-please-manifest.json +3 -0
  3. python_eia-0.3.0/CHANGELOG.md +16 -0
  4. {python_eia-0.2.1 → python_eia-0.3.0}/PKG-INFO +7 -3
  5. {python_eia-0.2.1 → python_eia-0.3.0}/pyproject.toml +13 -5
  6. python_eia-0.3.0/release-please-config.json +19 -0
  7. python_eia-0.3.0/src/eia/.agents/skills/eia/SKILL.md +172 -0
  8. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/__init__.py +3 -1
  9. python_eia-0.3.0/src/eia/cache.py +399 -0
  10. python_eia-0.3.0/src/eia/catalog.py +137 -0
  11. python_eia-0.3.0/src/eia/catalog_manager.py +464 -0
  12. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/app.py +4 -0
  13. python_eia-0.3.0/src/eia/cli/cache_cmd.py +53 -0
  14. python_eia-0.3.0/src/eia/cli/catalog_cmd.py +186 -0
  15. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/client.py +309 -19
  16. python_eia-0.3.0/tests/__init__.py +0 -0
  17. python_eia-0.3.0/tests/conftest.py +33 -0
  18. python_eia-0.3.0/tests/test_catalog.py +55 -0
  19. python_eia-0.3.0/tests/test_cli.py +60 -0
  20. python_eia-0.3.0/tests/test_client.py +65 -0
  21. python_eia-0.3.0/uv.lock +1284 -0
  22. python_eia-0.2.1/eia/.agents/skills/eia/SKILL.md +0 -176
  23. python_eia-0.2.1/skills/eia/SKILL.md +0 -176
  24. {python_eia-0.2.1 → python_eia-0.3.0}/.github/workflows/publish-to-pypi.yml +0 -0
  25. {python_eia-0.2.1 → python_eia-0.3.0}/.gitignore +0 -0
  26. {python_eia-0.2.1 → python_eia-0.3.0}/README.md +0 -0
  27. {python_eia-0.2.1 → python_eia-0.3.0}/examples/1_Generic/fuel-type-data/1_Download.ipynb +0 -0
  28. {python_eia-0.2.1 → python_eia-0.3.0}/examples/1_Generic/fuel-type-data/2_Analysis.ipynb +0 -0
  29. {python_eia-0.2.1 → python_eia-0.3.0}/examples/1_Generic/steps/1_Download.ipynb +0 -0
  30. {python_eia-0.2.1 → python_eia-0.3.0}/examples/1_Generic/steps/2_Analysis.ipynb +0 -0
  31. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/__init__.py +0 -0
  32. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/_output.py +0 -0
  33. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/config.py +0 -0
  34. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/config_cmd.py +0 -0
  35. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/exec_cmd.py +0 -0
  36. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/facets_cmd.py +0 -0
  37. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/get_cmd.py +0 -0
  38. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/meta_cmd.py +0 -0
  39. {python_eia-0.2.1 → python_eia-0.3.0/src}/eia/cli/routes_cmd.py +0 -0
@@ -1,14 +1,30 @@
1
- name: Publish to PyPI
1
+ name: Release Please
2
2
 
3
3
  on:
4
4
  push:
5
5
  branches: [main]
6
6
 
7
+ permissions:
8
+ contents: write
9
+ pull-requests: write
10
+
7
11
  jobs:
12
+ release-please:
13
+ runs-on: ubuntu-latest
14
+ outputs:
15
+ release_created: ${{ steps.release.outputs.release_created }}
16
+ steps:
17
+ - uses: googleapis/release-please-action@v4
18
+ id: release
19
+ with:
20
+ token: ${{ secrets.GITHUB_TOKEN }}
21
+
8
22
  publish:
23
+ needs: release-please
24
+ if: needs.release-please.outputs.release_created == 'true'
9
25
  runs-on: ubuntu-latest
10
26
  permissions:
11
- id-token: write # Required for trusted publishing
27
+ id-token: write
12
28
  steps:
13
29
  - uses: actions/checkout@v4
14
30
 
@@ -24,5 +40,3 @@ jobs:
24
40
 
25
41
  - name: Publish to PyPI
26
42
  uses: pypa/gh-action-pypi-publish@release/v1
27
- with:
28
- skip-existing: true
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.3.0"
3
+ }
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## [0.3.0](https://github.com/datons/python-eia/compare/python-eia-v0.2.1...python-eia-v0.3.0) (2026-03-04)
4
+
5
+
6
+ ### Features
7
+
8
+ * add CLI, skill file, bump to 0.2.0, publish-on-push workflow ([b766f71](https://github.com/datons/python-eia/commit/b766f71a5eb08e4a6d2ddb77b38cb9f6a69f1bfa))
9
+ * add data catalog, fix tz comparison and gap date formatting bugs ([f609aab](https://github.com/datons/python-eia/commit/f609aab23b7d0ac4ff01c38e7b1ede5be6c89476))
10
+ * add full API schema caching to YAML catalog ([5947cf1](https://github.com/datons/python-eia/commit/5947cf121dc61c960e3887669b768d103752fcf0))
11
+ * add parquet cache for offline-first data access ([5f7338b](https://github.com/datons/python-eia/commit/5f7338bb0533cc3a197df6514d996b85c460d639))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * correct author email to datons.com ([d62f40d](https://github.com/datons/python-eia/commit/d62f40d3569cee661251bb93d627dbb664a88c81))
@@ -1,12 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-eia
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: A Python client for the U.S. Energy Information Administration (EIA) API v2
5
5
  Project-URL: Homepage, https://github.com/datons/python-eia
6
- Project-URL: Repository, https://github.com/datons/python-eia.git
6
+ Project-URL: Repository, https://github.com/datons/python-eia
7
7
  Project-URL: Issues, https://github.com/datons/python-eia/issues
8
- Author-email: Jesus Lopez <jesus.lopez@datons.ai>
8
+ Project-URL: Changelog, https://github.com/datons/python-eia/releases
9
+ Author-email: Jesús López <jesus.lopez@datons.com>
9
10
  License-Expression: MIT
11
+ Keywords: api,eia,electricity,energy,gas,oil,usa
10
12
  Classifier: Development Status :: 3 - Alpha
11
13
  Classifier: Intended Audience :: Developers
12
14
  Classifier: Intended Audience :: Science/Research
@@ -20,6 +22,8 @@ Classifier: Programming Language :: Python :: 3.13
20
22
  Classifier: Topic :: Scientific/Engineering
21
23
  Requires-Python: >=3.10
22
24
  Requires-Dist: pandas>=2.0
25
+ Requires-Dist: pyarrow>=14.0
26
+ Requires-Dist: pyyaml>=6.0
23
27
  Requires-Dist: requests>=2.31.0
24
28
  Requires-Dist: rich>=13.0
25
29
  Requires-Dist: typer>=0.9
@@ -4,12 +4,13 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "python-eia"
7
- version = "0.2.1"
7
+ version = "0.3.0"
8
8
  description = "A Python client for the U.S. Energy Information Administration (EIA) API v2"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = "MIT"
12
- authors = [{ name = "Jesus Lopez", email = "jesus.lopez@datons.ai" }]
12
+ authors = [{ name = "Jesús López", email = "jesus.lopez@datons.com" }]
13
+ keywords = ["eia", "energy", "electricity", "oil", "gas", "api", "usa"]
13
14
  classifiers = [
14
15
  "Development Status :: 3 - Alpha",
15
16
  "Intended Audience :: Developers",
@@ -23,7 +24,7 @@ classifiers = [
23
24
  "Programming Language :: Python :: 3.13",
24
25
  "Topic :: Scientific/Engineering",
25
26
  ]
26
- dependencies = ["requests>=2.31.0", "urllib3>=2.0.0", "pandas>=2.0", "typer>=0.9", "rich>=13.0"]
27
+ dependencies = ["requests>=2.31.0", "urllib3>=2.0.0", "pandas>=2.0", "pyarrow>=14.0", "typer>=0.9", "rich>=13.0", "pyyaml>=6.0"]
27
28
 
28
29
  [project.scripts]
29
30
  eia = "eia.cli:app"
@@ -41,8 +42,15 @@ dev = [
41
42
 
42
43
  [project.urls]
43
44
  Homepage = "https://github.com/datons/python-eia"
44
- Repository = "https://github.com/datons/python-eia.git"
45
+ Repository = "https://github.com/datons/python-eia"
45
46
  Issues = "https://github.com/datons/python-eia/issues"
47
+ Changelog = "https://github.com/datons/python-eia/releases"
46
48
 
47
49
  [tool.hatch.build.targets.wheel]
48
- packages = ["eia"]
50
+ packages = ["src/eia"]
51
+
52
+ [tool.pytest.ini_options]
53
+ testpaths = ["tests"]
54
+ markers = [
55
+ "integration: tests that hit real APIs (deselect with -m 'not integration')",
56
+ ]
@@ -0,0 +1,19 @@
1
+ {
2
+ "packages": {
3
+ ".": {
4
+ "release-type": "python",
5
+ "package-name": "python-eia",
6
+ "extra-files": [
7
+ "pyproject.toml"
8
+ ],
9
+ "changelog-sections": [
10
+ { "type": "feat", "section": "Features" },
11
+ { "type": "fix", "section": "Bug Fixes" },
12
+ { "type": "perf", "section": "Performance" },
13
+ { "type": "docs", "section": "Documentation", "hidden": true },
14
+ { "type": "chore", "section": "Miscellaneous", "hidden": true }
15
+ ]
16
+ }
17
+ },
18
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
19
+ }
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: eia
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: 2.0.0
5
+ ---
6
+
7
+ # EIA Data Assistant
8
+
9
+ You have access to the `python-eia` library and CLI for querying the U.S. Energy Information Administration (EIA) API v2.
10
+
11
+ ## When to use what
12
+
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.
16
+
17
+ ## Built-in Catalog (OFFLINE — no API calls)
18
+
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) ---
45
+
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)
94
+ ```
95
+
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)
113
+
114
+ ```bash
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
120
+ ```
121
+
122
+ ### Explore (hits API)
123
+
124
+ ```bash
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
129
+ ```
130
+
131
+ ### Fetch data
132
+
133
+ ```bash
134
+ eia get electricity/rto/fuel-type-data \
135
+ --start 2024-06-01 --end 2024-06-08 \
136
+ --frequency hourly --facet respondent=CISO --data value
137
+
138
+ # Multiple facet values (repeat --facet)
139
+ eia get electricity/retail-sales \
140
+ --start 2024-01-01 --end 2024-12-31 \
141
+ --facet stateid=CA --facet sectorid=RES --facet sectorid=COM \
142
+ --data revenue --data sales
143
+
144
+ # Export
145
+ eia get petroleum/pri/spt --start 2024-01-01 --end 2024-06-01 \
146
+ --format csv --output prices.csv
147
+ ```
148
+
149
+ ### Exec (ad-hoc pandas)
150
+
151
+ ```bash
152
+ eia exec electricity/rto/fuel-type-data \
153
+ --start 2024-06-01 --end 2024-06-08 \
154
+ --frequency hourly --facet respondent=CISO --data value \
155
+ -x "df.groupby('fueltype')['value'].mean()"
156
+ ```
157
+
158
+ ### Output options
159
+
160
+ ```
161
+ --format table|csv|json (default: table)
162
+ --output file.csv (write to file instead of stdout)
163
+ ```
164
+
165
+ ## Configuration
166
+
167
+ ```bash
168
+ eia config set api-key YOUR_KEY # Store API key
169
+ eia config get api-key # Verify
170
+ ```
171
+
172
+ Config file: `~/.config/eia/config.toml`. API key resolution: config file > `EIA_API_KEY` env var.
@@ -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"]