python-entsoe 0.4.1__tar.gz → 0.6.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.
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/.github/workflows/publish.yml +18 -4
- python_entsoe-0.6.0/.release-please-manifest.json +3 -0
- python_entsoe-0.6.0/CHANGELOG.md +30 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/PKG-INFO +7 -2
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/pyproject.toml +10 -2
- python_entsoe-0.6.0/release-please-config.json +19 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/.agents/skills/entsoe/SKILL.md +91 -117
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/__init__.py +5 -2
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/_mappings.py +147 -0
- python_entsoe-0.6.0/src/entsoe/cache.py +398 -0
- python_entsoe-0.6.0/src/entsoe/catalog.py +51 -0
- python_entsoe-0.6.0/src/entsoe/cli/_resolve.py +149 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/app.py +6 -4
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/balancing.py +21 -10
- python_entsoe-0.6.0/src/entsoe/cli/cache_cmd.py +73 -0
- python_entsoe-0.6.0/src/entsoe/cli/catalog_cmd.py +148 -0
- python_entsoe-0.6.0/src/entsoe/cli/exec_cmd.py +256 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/generation.py +35 -31
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/load.py +21 -10
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/prices.py +14 -5
- python_entsoe-0.6.0/src/entsoe/cli/transmission.py +104 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/client.py +41 -9
- python_entsoe-0.6.0/src/entsoe/namespaces/_base.py +396 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/namespaces/balancing.py +6 -2
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/namespaces/generation.py +32 -11
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/namespaces/load.py +6 -2
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/namespaces/prices.py +5 -3
- python_entsoe-0.6.0/src/entsoe/namespaces/transmission.py +215 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/uv.lock +64 -8
- python_entsoe-0.4.1/skills/entsoe/SKILL.md +0 -202
- python_entsoe-0.4.1/src/entsoe/cli/exec_cmd.py +0 -113
- python_entsoe-0.4.1/src/entsoe/cli/transmission.py +0 -75
- python_entsoe-0.4.1/src/entsoe/namespaces/_base.py +0 -112
- python_entsoe-0.4.1/src/entsoe/namespaces/transmission.py +0 -131
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/.gitignore +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/.python-version +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/CLAUDE.md +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/README.md +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/docs/data-availability.md +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/examples/balancing.ipynb +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/examples/generation.ipynb +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/examples/generation_per_plant.ipynb +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/examples/load.ipynb +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/examples/prices.ipynb +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/examples/transmission.ipynb +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/scripts/generate_notebooks.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/_http.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/_xml.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/__init__.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/_output.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/config.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/cli/config_cmd.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/exceptions.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/namespaces/__init__.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/src/entsoe/py.typed +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/__init__.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/conftest.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/test_balancing.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/test_generation.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/test_load.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/test_multi.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/test_prices.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/test_transmission.py +0 -0
- {python_entsoe-0.4.1 → python_entsoe-0.6.0}/tests/test_validation.py +0 -0
|
@@ -1,14 +1,30 @@
|
|
|
1
|
-
name:
|
|
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
|
|
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,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.6.0](https://github.com/datons/python-entsoe/compare/python-entsoe-v0.5.0...python-entsoe-v0.6.0) (2026-03-04)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add built-in data catalog with CLI and Python API ([987bb18](https://github.com/datons/python-entsoe/commit/987bb181f0d1b6a8d18578b25902b77c7029ac6f))
|
|
9
|
+
* migrate catalog from hardcoded Python to YAML-backed manager ([dcc35f7](https://github.com/datons/python-entsoe/commit/dcc35f7aa6359f49ef9f870d942c6d860c319597))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* update skill with correct exec syntax and Python-first approach ([bd6dca7](https://github.com/datons/python-entsoe/commit/bd6dca7a9a8ac74c0f855719cc660a93a918eaf4))
|
|
15
|
+
|
|
16
|
+
## [0.5.0](https://github.com/datons/python-entsoe/compare/python-entsoe-v0.4.2...python-entsoe-v0.5.0) (2026-03-04)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* add CLI, skill file, and publish-on-push workflow ([dd63f6a](https://github.com/datons/python-entsoe/commit/dd63f6ae5f5eb083fb77e8f15d5a2063f2c54cfc))
|
|
22
|
+
* add parquet caching, multi-value support, and CLI improvements ([da64471](https://github.com/datons/python-entsoe/commit/da64471186551e4f19273fe08f96c21d02ec2d4f))
|
|
23
|
+
* multi-value parameters — pass lists to country, psr_type, country_from/to ([9c6ae6d](https://github.com/datons/python-entsoe/commit/9c6ae6d671fa8fe2be16b1c78f75818da072098f))
|
|
24
|
+
* rename Client to ENTSOEClient, keep Client as alias ([c35b8a5](https://github.com/datons/python-entsoe/commit/c35b8a529c874fa54352754d6566730c9c346f44))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* lower requires-python to >=3.10 and sync pyproject.toml version to 0.4.0 ([50b7f94](https://github.com/datons/python-entsoe/commit/50b7f940eb8001c6530f4344b4d90f817f643175))
|
|
30
|
+
* restore correct author email to datons.com ([86ec008](https://github.com/datons/python-entsoe/commit/86ec0083eead4a94c40235225e5fd59a3e7b0326))
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-entsoe
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Python client for the ENTSO-E Transparency Platform API
|
|
5
|
+
Project-URL: Homepage, https://github.com/datons/python-entsoe
|
|
5
6
|
Project-URL: Repository, https://github.com/datons/python-entsoe
|
|
6
|
-
|
|
7
|
+
Project-URL: Issues, https://github.com/datons/python-entsoe/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/datons/python-entsoe/releases
|
|
9
|
+
Author-email: Jesús López <jesus.lopez@datons.com>
|
|
7
10
|
License-Expression: MIT
|
|
8
11
|
Keywords: api,electricity,energy,entsoe,transparency
|
|
9
12
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -17,6 +20,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
20
|
Classifier: Topic :: Scientific/Engineering
|
|
18
21
|
Requires-Python: >=3.10
|
|
19
22
|
Requires-Dist: pandas>=2.0
|
|
23
|
+
Requires-Dist: pyarrow>=23.0.1
|
|
24
|
+
Requires-Dist: pyyaml>=6.0
|
|
20
25
|
Requires-Dist: requests>=2.28
|
|
21
26
|
Requires-Dist: rich>=13.0
|
|
22
27
|
Requires-Dist: typer>=0.9
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-entsoe"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.0"
|
|
4
4
|
description = "Python client for the ENTSO-E Transparency Platform API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
authors = [
|
|
8
|
-
{ name = "
|
|
8
|
+
{ name = "Jesús López", email = "jesus.lopez@datons.com" },
|
|
9
9
|
]
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
keywords = ["entsoe", "energy", "electricity", "api", "transparency"]
|
|
@@ -22,16 +22,21 @@ classifiers = [
|
|
|
22
22
|
]
|
|
23
23
|
dependencies = [
|
|
24
24
|
"pandas>=2.0",
|
|
25
|
+
"pyyaml>=6.0",
|
|
25
26
|
"requests>=2.28",
|
|
26
27
|
"typer>=0.9",
|
|
27
28
|
"rich>=13.0",
|
|
29
|
+
"pyarrow>=23.0.1",
|
|
28
30
|
]
|
|
29
31
|
|
|
30
32
|
[project.scripts]
|
|
31
33
|
entsoe = "entsoe.cli:app"
|
|
32
34
|
|
|
33
35
|
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/datons/python-entsoe"
|
|
34
37
|
Repository = "https://github.com/datons/python-entsoe"
|
|
38
|
+
Issues = "https://github.com/datons/python-entsoe/issues"
|
|
39
|
+
Changelog = "https://github.com/datons/python-entsoe/releases"
|
|
35
40
|
|
|
36
41
|
[build-system]
|
|
37
42
|
requires = ["hatchling"]
|
|
@@ -42,6 +47,9 @@ packages = ["src/entsoe"]
|
|
|
42
47
|
|
|
43
48
|
[tool.pytest.ini_options]
|
|
44
49
|
testpaths = ["tests"]
|
|
50
|
+
markers = [
|
|
51
|
+
"integration: tests that hit real APIs (deselect with -m 'not integration')",
|
|
52
|
+
]
|
|
45
53
|
|
|
46
54
|
[dependency-groups]
|
|
47
55
|
dev = [
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packages": {
|
|
3
|
+
".": {
|
|
4
|
+
"release-type": "python",
|
|
5
|
+
"package-name": "python-entsoe",
|
|
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
|
+
}
|
|
@@ -1,105 +1,61 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: entsoe
|
|
3
3
|
description: Query European electricity market data (ENTSO-E Transparency Platform). Use when the user asks about electricity prices, load, generation, transmission, or balancing data for European countries.
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# ENTSO-E Data Assistant
|
|
8
8
|
|
|
9
|
-
You have access to the `python-entsoe`
|
|
9
|
+
You have access to the `python-entsoe` library and CLI for querying the ENTSO-E Transparency Platform (European electricity market data).
|
|
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
|
-
|
|
16
|
-
# Day-ahead prices for one country
|
|
17
|
-
entsoe prices day-ahead -s 2024-06-01 -e 2024-06-08 --country FR
|
|
18
|
-
|
|
19
|
-
# Multi-country
|
|
20
|
-
entsoe prices day-ahead -s 2024-06-01 -e 2024-06-08 --country FR --country ES
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Load
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# Actual total system load
|
|
27
|
-
entsoe load actual -s 2024-06-01 -e 2024-06-08 --country FR
|
|
28
|
-
|
|
29
|
-
# Day-ahead load forecast
|
|
30
|
-
entsoe load forecast -s 2024-06-01 -e 2024-06-08 --country FR
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Generation
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# Actual generation per type (all types)
|
|
37
|
-
entsoe generation actual -s 2024-06-01 -e 2024-06-08 --country FR
|
|
38
|
-
|
|
39
|
-
# Filter by PSR type
|
|
40
|
-
entsoe generation actual -s 2024-06-01 -e 2024-06-08 --country FR --psr solar --psr wind_onshore
|
|
17
|
+
## Python Library (default)
|
|
41
18
|
|
|
42
|
-
|
|
43
|
-
entsoe
|
|
44
|
-
|
|
45
|
-
# Installed capacity
|
|
46
|
-
entsoe generation capacity -s 2024-06-01 -e 2024-06-08 --country FR
|
|
47
|
-
|
|
48
|
-
# Per production unit
|
|
49
|
-
entsoe generation per-plant -s 2024-06-01 -e 2024-06-08 --country FR
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Transmission
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
# Physical cross-border flows
|
|
56
|
-
entsoe transmission flows -s 2024-06-01 -e 2024-06-08 --from FR --to ES
|
|
57
|
-
|
|
58
|
-
# Scheduled commercial exchanges
|
|
59
|
-
entsoe transmission exchanges -s 2024-06-01 -e 2024-06-08 --from FR --to ES
|
|
60
|
-
|
|
61
|
-
# Net transfer capacity
|
|
62
|
-
entsoe transmission capacity -s 2024-06-01 -e 2024-06-08 --from FR --to ES
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Balancing
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
# Imbalance prices
|
|
69
|
-
entsoe balancing prices -s 2024-06-01 -e 2024-06-08 --country FR
|
|
70
|
-
|
|
71
|
-
# Imbalance volumes
|
|
72
|
-
entsoe balancing volumes -s 2024-06-01 -e 2024-06-08 --country FR
|
|
73
|
-
```
|
|
19
|
+
```python
|
|
20
|
+
from entsoe import Client
|
|
74
21
|
|
|
75
|
-
|
|
22
|
+
client = Client() # reads config file, then ENTSOE_API_KEY env var
|
|
76
23
|
|
|
77
|
-
|
|
24
|
+
# --- Prices ---
|
|
25
|
+
df = client.prices.day_ahead("2024-06-01", "2024-06-08", country="FR")
|
|
26
|
+
df = client.prices.day_ahead("2024-06-01", "2024-06-08", country=["FR", "ES"])
|
|
78
27
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
28
|
+
# --- Load ---
|
|
29
|
+
df = client.load.actual("2024-06-01", "2024-06-08", country="FR")
|
|
30
|
+
df = client.load.forecast("2024-06-01", "2024-06-08", country="FR")
|
|
82
31
|
|
|
83
|
-
#
|
|
84
|
-
|
|
32
|
+
# --- Generation ---
|
|
33
|
+
df = client.generation.actual("2024-06-01", "2024-06-08", country="FR")
|
|
34
|
+
df = client.generation.actual("2024-06-01", "2024-06-08", country="FR", psr_type="solar")
|
|
35
|
+
df = client.generation.actual("2024-06-01", "2024-06-08", country="FR", psr_type=["solar", "wind_onshore"])
|
|
36
|
+
df = client.generation.forecast("2024-06-01", "2024-06-08", country="FR")
|
|
37
|
+
df = client.generation.installed_capacity("2024-06-01", "2024-06-08", country="FR")
|
|
38
|
+
df = client.generation.per_plant("2024-06-01", "2024-06-08", country="FR")
|
|
85
39
|
|
|
86
|
-
#
|
|
87
|
-
|
|
40
|
+
# --- Transmission ---
|
|
41
|
+
df = client.transmission.crossborder_flows("2024-06-01", "2024-06-08", country_from="FR", country_to="ES")
|
|
42
|
+
df = client.transmission.scheduled_exchanges("2024-06-01", "2024-06-08", country_from="FR", country_to="ES")
|
|
43
|
+
df = client.transmission.net_transfer_capacity("2024-06-01", "2024-06-08", country_from="FR", country_to="ES")
|
|
88
44
|
|
|
89
|
-
#
|
|
90
|
-
|
|
45
|
+
# --- Balancing ---
|
|
46
|
+
df = client.balancing.imbalance_prices("2024-06-01", "2024-06-08", country="FR")
|
|
47
|
+
df = client.balancing.imbalance_volumes("2024-06-01", "2024-06-08", country="FR")
|
|
91
48
|
```
|
|
92
49
|
|
|
93
|
-
###
|
|
50
|
+
### Key conventions
|
|
94
51
|
|
|
95
|
-
All
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```
|
|
52
|
+
- **Timezone**: All string dates are interpreted in Europe/Brussels (CET) by default
|
|
53
|
+
- **Auto year-splitting**: Date ranges > 1 year are automatically split into yearly API requests
|
|
54
|
+
- **Rate limiting**: ENTSO-E has a 400-request/minute limit; the library handles retries
|
|
55
|
+
- **Multi-value support**: Pass lists for `country` or `psr_type` to get combined results with label columns
|
|
56
|
+
- **Transmission**: Uses `country_from`/`country_to`; multi-value adds a `border` column
|
|
57
|
+
- **No caching**: Data is fetched fresh on each request
|
|
58
|
+
- **Custom exceptions**: `ENTSOEError`, `AuthenticationError`, `APIResponseError`, `InvalidParameterError`, `NetworkError`
|
|
103
59
|
|
|
104
60
|
## Country Codes
|
|
105
61
|
|
|
@@ -143,60 +99,78 @@ Bidding zones: `DK_1`, `DK_2`, `NO_1`–`NO_5`, `SE_1`–`SE_4`, `IT_NORTH`, `IT
|
|
|
143
99
|
| waste | Waste | B17 |
|
|
144
100
|
| other | Other | B20 |
|
|
145
101
|
|
|
146
|
-
Use shorthands with `--psr` (e.g.
|
|
102
|
+
Use shorthands with `psr_type=` (Python) or `--psr` (CLI), e.g. `psr_type="solar"` or `--psr solar`.
|
|
147
103
|
|
|
148
|
-
##
|
|
104
|
+
## CLI Reference (quick lookups)
|
|
149
105
|
|
|
150
|
-
|
|
151
|
-
from entsoe import Client
|
|
106
|
+
### Catalog (offline)
|
|
152
107
|
|
|
153
|
-
|
|
108
|
+
```bash
|
|
109
|
+
entsoe catalog list # All data categories and endpoints
|
|
110
|
+
entsoe catalog show prices # Detailed info for a category
|
|
111
|
+
entsoe catalog countries # Country/bidding zone codes
|
|
112
|
+
entsoe catalog psr # PSR (generation) types
|
|
113
|
+
entsoe catalog borders # Border groups and interconnections
|
|
114
|
+
```
|
|
154
115
|
|
|
116
|
+
### Fetch data
|
|
117
|
+
|
|
118
|
+
```bash
|
|
155
119
|
# Prices
|
|
156
|
-
|
|
157
|
-
|
|
120
|
+
entsoe prices day-ahead -s 2024-06-01 -e 2024-06-08 -c FR
|
|
121
|
+
entsoe prices day-ahead -P week -c FR,ES # Period shorthand
|
|
158
122
|
|
|
159
123
|
# Load
|
|
160
|
-
|
|
161
|
-
|
|
124
|
+
entsoe load actual -P month -c FR
|
|
125
|
+
entsoe load forecast -s 2024-06-01 -e 2024-06-08 -c FR
|
|
162
126
|
|
|
163
127
|
# Generation
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
df = client.generation.installed_capacity("2024-06-01", "2024-06-08", country="FR")
|
|
169
|
-
df = client.generation.per_plant("2024-06-01", "2024-06-08", country="FR")
|
|
128
|
+
entsoe generation actual -P week -c FR --psr solar --psr wind_onshore
|
|
129
|
+
entsoe generation forecast -P week -c FR
|
|
130
|
+
entsoe generation capacity -s 2024-01-01 -e 2024-12-31 -c FR
|
|
131
|
+
entsoe generation per-plant -P week -c FR
|
|
170
132
|
|
|
171
133
|
# Transmission
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
df = client.transmission.net_transfer_capacity("2024-06-01", "2024-06-08", country_from="FR", country_to="ES")
|
|
134
|
+
entsoe transmission flows -P week --from FR --to ES
|
|
135
|
+
entsoe transmission exchanges -P week --border ES-*,FR-*
|
|
175
136
|
|
|
176
137
|
# Balancing
|
|
177
|
-
|
|
178
|
-
|
|
138
|
+
entsoe balancing prices -P week -c FR
|
|
139
|
+
entsoe balancing volumes -P week -c FR
|
|
179
140
|
```
|
|
180
141
|
|
|
181
|
-
|
|
142
|
+
### Exec (ad-hoc pandas)
|
|
143
|
+
|
|
144
|
+
`exec` is a subcommand **within each namespace**:
|
|
182
145
|
|
|
183
146
|
```bash
|
|
184
|
-
|
|
185
|
-
entsoe
|
|
147
|
+
entsoe prices exec day-ahead -P week -c FR -x "df.describe()"
|
|
148
|
+
entsoe load exec actual -P 7d -c FR -x "df.resample('D').mean()"
|
|
149
|
+
entsoe generation exec actual -P month -c FR --psr solar -x "df.head(20)"
|
|
150
|
+
entsoe transmission exec flows -P week --from FR --to ES -x "df.describe()"
|
|
151
|
+
entsoe balancing exec prices -P week -c NL -x "df.describe()"
|
|
152
|
+
```
|
|
186
153
|
|
|
187
|
-
|
|
188
|
-
|
|
154
|
+
### Period shorthand (`-P`)
|
|
155
|
+
|
|
156
|
+
All data commands support `-P` as an alternative to `--start`/`--end`:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
-P today, -P yesterday, -P week, -P month, -P ytd, -P 14d
|
|
189
160
|
```
|
|
190
161
|
|
|
191
|
-
|
|
162
|
+
### Output options
|
|
192
163
|
|
|
193
|
-
|
|
164
|
+
```
|
|
165
|
+
--format table|csv|json (default: table)
|
|
166
|
+
--output file.csv (write to file instead of stdout)
|
|
167
|
+
```
|
|
194
168
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
169
|
+
## Configuration
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
entsoe config set api-key YOUR_KEY
|
|
173
|
+
entsoe config get api-key
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Config file: `~/.config/entsoe/config.toml`. API key resolution: config file > `ENTSOE_API_KEY` env var.
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
"""ENTSO-E Transparency Platform API client library."""
|
|
2
2
|
|
|
3
|
-
from .client import Client
|
|
3
|
+
from .client import Client, ENTSOEClient
|
|
4
4
|
from .exceptions import ENTSOEError, InvalidParameterError, NoDataError, RateLimitError
|
|
5
5
|
from ._mappings import COUNTRY_NAMES, PSR_CODES, country_name, psr_name
|
|
6
|
+
from . import catalog
|
|
6
7
|
|
|
7
|
-
__version__ = "0.4.
|
|
8
|
+
__version__ = "0.4.2"
|
|
8
9
|
__all__ = [
|
|
9
10
|
"Client",
|
|
10
11
|
"COUNTRY_NAMES",
|
|
12
|
+
"ENTSOEClient",
|
|
11
13
|
"ENTSOEError",
|
|
12
14
|
"InvalidParameterError",
|
|
13
15
|
"NoDataError",
|
|
14
16
|
"PSR_CODES",
|
|
15
17
|
"RateLimitError",
|
|
18
|
+
"catalog",
|
|
16
19
|
"country_name",
|
|
17
20
|
"psr_name",
|
|
18
21
|
]
|
|
@@ -354,3 +354,150 @@ def psr_name(identifier: str) -> str:
|
|
|
354
354
|
"""
|
|
355
355
|
code = lookup_psr(identifier)
|
|
356
356
|
return PSR_TYPES[code]
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
# ── Border / neighbour data (for CLI --border flag) ───────────────────────
|
|
360
|
+
|
|
361
|
+
# Direct interconnections between bidding zones used by ENTSO-E.
|
|
362
|
+
# Each key maps to the set of zones it has a physical border with.
|
|
363
|
+
NEIGHBOURS: dict[str, set[str]] = {
|
|
364
|
+
"ES": {"FR", "PT"},
|
|
365
|
+
"FR": {"ES", "BE", "CH", "DE_LU", "GB", "IT_NORTH"},
|
|
366
|
+
"PT": {"ES"},
|
|
367
|
+
"BE": {"FR", "NL", "DE_LU", "GB"},
|
|
368
|
+
"NL": {"BE", "DE_LU", "GB", "NO_2", "DK_1"},
|
|
369
|
+
"DE_LU": {"FR", "BE", "NL", "AT", "CH", "CZ", "DK_1", "DK_2", "PL", "SE_4", "NO_2"},
|
|
370
|
+
"AT": {"DE_LU", "CH", "CZ", "HU", "SI", "IT_NORTH"},
|
|
371
|
+
"CH": {"FR", "DE_LU", "AT", "IT_NORTH"},
|
|
372
|
+
"IT_NORTH": {"FR", "CH", "AT", "SI"},
|
|
373
|
+
"GB": {"FR", "BE", "NL", "IE_SEM", "NO_2"},
|
|
374
|
+
"IE_SEM": {"GB"},
|
|
375
|
+
"DK_1": {"DE_LU", "NL", "NO_2", "SE_3", "DK_2"},
|
|
376
|
+
"DK_2": {"DE_LU", "DK_1", "SE_4"},
|
|
377
|
+
"NO_1": {"NO_2", "NO_3", "NO_5", "SE_3"},
|
|
378
|
+
"NO_2": {"NO_1", "NO_5", "NL", "DK_1", "DE_LU", "GB"},
|
|
379
|
+
"NO_3": {"NO_1", "NO_4", "NO_5", "SE_2"},
|
|
380
|
+
"NO_4": {"NO_3", "SE_1", "SE_2", "FI"},
|
|
381
|
+
"NO_5": {"NO_1", "NO_2", "NO_3"},
|
|
382
|
+
"SE_1": {"NO_4", "SE_2", "FI"},
|
|
383
|
+
"SE_2": {"NO_3", "NO_4", "SE_1", "SE_3"},
|
|
384
|
+
"SE_3": {"NO_1", "DK_1", "SE_2", "SE_4", "FI"},
|
|
385
|
+
"SE_4": {"DE_LU", "DK_2", "SE_3", "PL", "LT"},
|
|
386
|
+
"FI": {"NO_4", "SE_1", "SE_3", "EE"},
|
|
387
|
+
"EE": {"FI", "LV"},
|
|
388
|
+
"LV": {"EE", "LT"},
|
|
389
|
+
"LT": {"LV", "SE_4", "PL"},
|
|
390
|
+
"PL": {"DE_LU", "CZ", "SK", "LT", "SE_4"},
|
|
391
|
+
"CZ": {"DE_LU", "AT", "PL", "SK"},
|
|
392
|
+
"SK": {"CZ", "PL", "HU"},
|
|
393
|
+
"HU": {"AT", "SK", "RO", "HR", "SI", "RS"},
|
|
394
|
+
"SI": {"AT", "IT_NORTH", "HU", "HR"},
|
|
395
|
+
"HR": {"HU", "SI", "RS", "BA"},
|
|
396
|
+
"RS": {"HU", "HR", "BA", "RO", "BG", "MK", "ME", "AL"},
|
|
397
|
+
"BA": {"HR", "RS", "ME"},
|
|
398
|
+
"RO": {"HU", "RS", "BG"},
|
|
399
|
+
"BG": {"RO", "RS", "MK", "GR", "TR"},
|
|
400
|
+
"MK": {"RS", "BG", "GR", "AL"},
|
|
401
|
+
"GR": {"BG", "MK", "AL", "IT_SUD", "TR"},
|
|
402
|
+
"IT_SUD": {"GR"},
|
|
403
|
+
"AL": {"RS", "MK", "GR", "ME"},
|
|
404
|
+
"ME": {"RS", "BA", "AL"},
|
|
405
|
+
"TR": {"BG", "GR"},
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
# Named border groups for convenient CLI usage.
|
|
409
|
+
# ── Border parsing (library-level) ────────────────────────────────────────
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def parse_borders(specs: str | list[str]) -> list[tuple[str, str]]:
|
|
413
|
+
"""Parse border specifications into deduplicated (from, to) pairs.
|
|
414
|
+
|
|
415
|
+
Supported formats:
|
|
416
|
+
|
|
417
|
+
- ``"ES-FR"`` — single border
|
|
418
|
+
- ``"ES-FR,ES-PT"`` — comma-separated within a string
|
|
419
|
+
- ``["ES-*", "FR-*"]`` — list with wildcards (all neighbours)
|
|
420
|
+
- ``"iberian"`` — named group
|
|
421
|
+
|
|
422
|
+
Deduplicates pairs while preserving insertion order, so
|
|
423
|
+
``"ES-*,FR-*"`` won't produce ``(ES, FR)`` and ``(FR, ES)`` twice
|
|
424
|
+
if both wildcards expand to include each other.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
specs: A single spec string or list of spec strings.
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
Deduplicated list of ``(country_from, country_to)`` tuples.
|
|
431
|
+
|
|
432
|
+
Raises:
|
|
433
|
+
InvalidParameterError: On unknown country or invalid spec format.
|
|
434
|
+
"""
|
|
435
|
+
from .exceptions import InvalidParameterError
|
|
436
|
+
|
|
437
|
+
if isinstance(specs, str):
|
|
438
|
+
specs = [specs]
|
|
439
|
+
|
|
440
|
+
flat = [v.strip() for raw in specs for v in raw.split(",") if v.strip()]
|
|
441
|
+
seen: set[tuple[str, str]] = set()
|
|
442
|
+
pairs: list[tuple[str, str]] = []
|
|
443
|
+
|
|
444
|
+
def _add(pair: tuple[str, str]) -> None:
|
|
445
|
+
if pair not in seen:
|
|
446
|
+
seen.add(pair)
|
|
447
|
+
pairs.append(pair)
|
|
448
|
+
|
|
449
|
+
for spec in flat:
|
|
450
|
+
low = spec.lower()
|
|
451
|
+
|
|
452
|
+
# Named group
|
|
453
|
+
if low in BORDER_GROUPS:
|
|
454
|
+
for p in BORDER_GROUPS[low]:
|
|
455
|
+
_add(p)
|
|
456
|
+
continue
|
|
457
|
+
|
|
458
|
+
# Pair: A-B or A-*
|
|
459
|
+
if "-" in spec:
|
|
460
|
+
parts = spec.split("-", 1)
|
|
461
|
+
a, b = parts[0].strip().upper(), parts[1].strip().upper()
|
|
462
|
+
if b == "*":
|
|
463
|
+
if a not in NEIGHBOURS:
|
|
464
|
+
raise InvalidParameterError(
|
|
465
|
+
f"No known neighbours for '{a}'. "
|
|
466
|
+
f"Available: {', '.join(sorted(NEIGHBOURS.keys()))}"
|
|
467
|
+
)
|
|
468
|
+
for n in sorted(NEIGHBOURS[a]):
|
|
469
|
+
_add((a, n))
|
|
470
|
+
else:
|
|
471
|
+
_add((a, b))
|
|
472
|
+
continue
|
|
473
|
+
|
|
474
|
+
raise InvalidParameterError(
|
|
475
|
+
f"Invalid border spec '{spec}'. Use A-B, A-*, or a group name "
|
|
476
|
+
f"({', '.join(sorted(BORDER_GROUPS.keys()))})."
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
return pairs
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
BORDER_GROUPS: dict[str, list[tuple[str, str]]] = {
|
|
483
|
+
"iberian": [("ES", "FR"), ("ES", "PT"), ("PT", "ES"), ("FR", "ES")],
|
|
484
|
+
"nordic": [
|
|
485
|
+
("NO_1", "NO_2"), ("NO_1", "NO_3"), ("NO_1", "NO_5"), ("NO_1", "SE_3"),
|
|
486
|
+
("NO_2", "NO_1"), ("NO_2", "NO_5"), ("NO_2", "NL"), ("NO_2", "DK_1"), ("NO_2", "DE_LU"), ("NO_2", "GB"),
|
|
487
|
+
("NO_3", "NO_1"), ("NO_3", "NO_4"), ("NO_3", "NO_5"), ("NO_3", "SE_2"),
|
|
488
|
+
("NO_4", "NO_3"), ("NO_4", "SE_1"), ("NO_4", "SE_2"), ("NO_4", "FI"),
|
|
489
|
+
("NO_5", "NO_1"), ("NO_5", "NO_2"), ("NO_5", "NO_3"),
|
|
490
|
+
("SE_1", "NO_4"), ("SE_1", "SE_2"), ("SE_1", "FI"),
|
|
491
|
+
("SE_2", "NO_3"), ("SE_2", "NO_4"), ("SE_2", "SE_1"), ("SE_2", "SE_3"),
|
|
492
|
+
("SE_3", "NO_1"), ("SE_3", "DK_1"), ("SE_3", "SE_2"), ("SE_3", "SE_4"), ("SE_3", "FI"),
|
|
493
|
+
("SE_4", "DE_LU"), ("SE_4", "DK_2"), ("SE_4", "SE_3"), ("SE_4", "PL"), ("SE_4", "LT"),
|
|
494
|
+
("DK_1", "DK_2"), ("DK_1", "DE_LU"), ("DK_1", "NL"), ("DK_1", "NO_2"), ("DK_1", "SE_3"),
|
|
495
|
+
("DK_2", "DK_1"), ("DK_2", "DE_LU"), ("DK_2", "SE_4"),
|
|
496
|
+
("FI", "NO_4"), ("FI", "SE_1"), ("FI", "SE_3"), ("FI", "EE"),
|
|
497
|
+
],
|
|
498
|
+
"baltic": [
|
|
499
|
+
("EE", "FI"), ("EE", "LV"),
|
|
500
|
+
("LV", "EE"), ("LV", "LT"),
|
|
501
|
+
("LT", "LV"), ("LT", "SE_4"), ("LT", "PL"),
|
|
502
|
+
],
|
|
503
|
+
}
|