python-entsoe 0.6.0__tar.gz → 0.6.1__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 (61) hide show
  1. python_entsoe-0.6.1/.release-please-manifest.json +3 -0
  2. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/CHANGELOG.md +7 -0
  3. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/PKG-INFO +1 -2
  4. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/pyproject.toml +1 -5
  5. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/_mappings.py +0 -1
  6. python_entsoe-0.6.1/src/entsoe/catalog.py +228 -0
  7. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/client.py +0 -3
  8. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/uv.lock +1 -3
  9. python_entsoe-0.6.0/.release-please-manifest.json +0 -3
  10. python_entsoe-0.6.0/src/entsoe/catalog.py +0 -51
  11. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/.github/workflows/publish.yml +0 -0
  12. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/.gitignore +0 -0
  13. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/.python-version +0 -0
  14. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/CLAUDE.md +0 -0
  15. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/README.md +0 -0
  16. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/docs/data-availability.md +0 -0
  17. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/examples/balancing.ipynb +0 -0
  18. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/examples/generation.ipynb +0 -0
  19. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/examples/generation_per_plant.ipynb +0 -0
  20. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/examples/load.ipynb +0 -0
  21. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/examples/prices.ipynb +0 -0
  22. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/examples/transmission.ipynb +0 -0
  23. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/release-please-config.json +0 -0
  24. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/scripts/generate_notebooks.py +0 -0
  25. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/.agents/skills/entsoe/SKILL.md +0 -0
  26. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/__init__.py +0 -0
  27. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/_http.py +0 -0
  28. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/_xml.py +0 -0
  29. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cache.py +0 -0
  30. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/__init__.py +0 -0
  31. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/_output.py +0 -0
  32. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/_resolve.py +0 -0
  33. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/app.py +0 -0
  34. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/balancing.py +0 -0
  35. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/cache_cmd.py +0 -0
  36. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/catalog_cmd.py +0 -0
  37. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/config.py +0 -0
  38. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/config_cmd.py +0 -0
  39. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/exec_cmd.py +0 -0
  40. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/generation.py +0 -0
  41. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/load.py +0 -0
  42. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/prices.py +0 -0
  43. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/cli/transmission.py +0 -0
  44. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/exceptions.py +0 -0
  45. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/namespaces/__init__.py +0 -0
  46. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/namespaces/_base.py +0 -0
  47. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/namespaces/balancing.py +0 -0
  48. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/namespaces/generation.py +0 -0
  49. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/namespaces/load.py +0 -0
  50. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/namespaces/prices.py +0 -0
  51. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/namespaces/transmission.py +0 -0
  52. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/src/entsoe/py.typed +0 -0
  53. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/__init__.py +0 -0
  54. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/conftest.py +0 -0
  55. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/test_balancing.py +0 -0
  56. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/test_generation.py +0 -0
  57. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/test_load.py +0 -0
  58. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/test_multi.py +0 -0
  59. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/test_prices.py +0 -0
  60. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/test_transmission.py +0 -0
  61. {python_entsoe-0.6.0 → python_entsoe-0.6.1}/tests/test_validation.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.6.1"
3
+ }
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.1](https://github.com/datons/python-entsoe/compare/python-entsoe-v0.6.0...python-entsoe-v0.6.1) (2026-05-16)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * restore catalog imports broken by incomplete refactor in dcc35f7 ([74c0814](https://github.com/datons/python-entsoe/commit/74c0814bbdd3bd8d43981e77a1ab573ddf80a483))
9
+
3
10
  ## [0.6.0](https://github.com/datons/python-entsoe/compare/python-entsoe-v0.5.0...python-entsoe-v0.6.0) (2026-03-04)
4
11
 
5
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-entsoe
3
- Version: 0.6.0
3
+ Version: 0.6.1
4
4
  Summary: Python client for the ENTSO-E Transparency Platform API
5
5
  Project-URL: Homepage, https://github.com/datons/python-entsoe
6
6
  Project-URL: Repository, https://github.com/datons/python-entsoe
@@ -21,7 +21,6 @@ Classifier: Topic :: Scientific/Engineering
21
21
  Requires-Python: >=3.10
22
22
  Requires-Dist: pandas>=2.0
23
23
  Requires-Dist: pyarrow>=23.0.1
24
- Requires-Dist: pyyaml>=6.0
25
24
  Requires-Dist: requests>=2.28
26
25
  Requires-Dist: rich>=13.0
27
26
  Requires-Dist: typer>=0.9
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-entsoe"
3
- version = "0.6.0"
3
+ version = "0.6.1"
4
4
  description = "Python client for the ENTSO-E Transparency Platform API"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -22,7 +22,6 @@ classifiers = [
22
22
  ]
23
23
  dependencies = [
24
24
  "pandas>=2.0",
25
- "pyyaml>=6.0",
26
25
  "requests>=2.28",
27
26
  "typer>=0.9",
28
27
  "rich>=13.0",
@@ -47,9 +46,6 @@ packages = ["src/entsoe"]
47
46
 
48
47
  [tool.pytest.ini_options]
49
48
  testpaths = ["tests"]
50
- markers = [
51
- "integration: tests that hit real APIs (deselect with -m 'not integration')",
52
- ]
53
49
 
54
50
  [dependency-groups]
55
51
  dev = [
@@ -399,7 +399,6 @@ NEIGHBOURS: dict[str, set[str]] = {
399
399
  "BG": {"RO", "RS", "MK", "GR", "TR"},
400
400
  "MK": {"RS", "BG", "GR", "AL"},
401
401
  "GR": {"BG", "MK", "AL", "IT_SUD", "TR"},
402
- "IT_SUD": {"GR"},
403
402
  "AL": {"RS", "MK", "GR", "ME"},
404
403
  "ME": {"RS", "BA", "AL"},
405
404
  "TR": {"BG", "GR"},
@@ -0,0 +1,228 @@
1
+ """Built-in data catalog for ENTSO-E Transparency Platform.
2
+
3
+ Provides structured metadata about available data categories, endpoints,
4
+ country codes, PSR types, and border groups — so users don't need to
5
+ consult external documentation every time.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class Endpoint:
15
+ """A queryable data endpoint."""
16
+
17
+ name: str
18
+ description: str
19
+ method: str # Python client method name
20
+ cli: str # CLI command
21
+ resolution: str # e.g. "15min", "hourly", "daily"
22
+ columns: tuple[str, ...] # key columns returned
23
+ units: str
24
+ notes: str = ""
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class Category:
29
+ """A top-level data category grouping related endpoints."""
30
+
31
+ name: str
32
+ description: str
33
+ namespace: str # Python client namespace (e.g. "prices")
34
+ endpoints: tuple[Endpoint, ...]
35
+
36
+
37
+ # ── Prices ──────────────────────────────────────────────────────────────
38
+
39
+ PRICES = Category(
40
+ name="Prices",
41
+ description="Day-ahead electricity market prices",
42
+ namespace="prices",
43
+ endpoints=(
44
+ Endpoint(
45
+ name="Day-Ahead Prices",
46
+ description="Hourly day-ahead market clearing prices per bidding zone",
47
+ method="client.prices.day_ahead(start, end, country='FR')",
48
+ cli="entsoe prices day-ahead -s 2024-06-01 -e 2024-06-08 -c FR",
49
+ resolution="hourly",
50
+ columns=("timestamp", "country", "value", "currency", "quantity_unit"),
51
+ units="EUR/MWh",
52
+ ),
53
+ ),
54
+ )
55
+
56
+ # ── Load ────────────────────────────────────────────────────────────────
57
+
58
+ LOAD = Category(
59
+ name="Load",
60
+ description="Actual system load and day-ahead load forecasts",
61
+ namespace="load",
62
+ endpoints=(
63
+ Endpoint(
64
+ name="Actual Total Load",
65
+ description="Actual total electricity consumption per control area",
66
+ method="client.load.actual(start, end, country='FR')",
67
+ cli="entsoe load actual -s 2024-06-01 -e 2024-06-08 -c FR",
68
+ resolution="15min or hourly (varies by country)",
69
+ columns=("timestamp", "country", "value", "quantity_unit"),
70
+ units="MW",
71
+ ),
72
+ Endpoint(
73
+ name="Day-Ahead Load Forecast",
74
+ description="Day-ahead forecast of total electricity consumption",
75
+ method="client.load.forecast(start, end, country='FR')",
76
+ cli="entsoe load forecast -s 2024-06-01 -e 2024-06-08 -c FR",
77
+ resolution="15min or hourly (varies by country)",
78
+ columns=("timestamp", "country", "value", "quantity_unit"),
79
+ units="MW",
80
+ ),
81
+ ),
82
+ )
83
+
84
+ # ── Generation ──────────────────────────────────────────────────────────
85
+
86
+ GENERATION = Category(
87
+ name="Generation",
88
+ description="Actual generation, forecasts, installed capacity, and per-plant output",
89
+ namespace="generation",
90
+ endpoints=(
91
+ Endpoint(
92
+ name="Actual Generation per Type",
93
+ description="Actual electricity generation broken down by fuel/technology type (PSR)",
94
+ method="client.generation.actual(start, end, country='FR')",
95
+ cli="entsoe generation actual -s 2024-06-01 -e 2024-06-08 -c FR",
96
+ resolution="15min or hourly",
97
+ columns=("timestamp", "country", "psr_type", "value", "quantity_unit"),
98
+ units="MW",
99
+ notes="Filter by PSR type: --psr solar --psr wind_onshore",
100
+ ),
101
+ Endpoint(
102
+ name="Generation Forecast (Wind/Solar)",
103
+ description="Day-ahead forecast for wind and solar generation",
104
+ method="client.generation.forecast(start, end, country='FR')",
105
+ cli="entsoe generation forecast -s 2024-06-01 -e 2024-06-08 -c FR",
106
+ resolution="15min or hourly",
107
+ columns=("timestamp", "country", "psr_type", "value", "quantity_unit"),
108
+ units="MW",
109
+ ),
110
+ Endpoint(
111
+ name="Installed Generation Capacity",
112
+ description="Installed generation capacity per type (updated annually or on change)",
113
+ method="client.generation.installed_capacity(start, end, country='FR')",
114
+ cli="entsoe generation capacity -s 2024-06-01 -e 2024-06-08 -c FR",
115
+ resolution="yearly (point-in-time)",
116
+ columns=("timestamp", "country", "psr_type", "value", "quantity_unit"),
117
+ units="MW",
118
+ ),
119
+ Endpoint(
120
+ name="Actual Generation per Plant",
121
+ description="Generation output per individual production unit (>= 100 MW)",
122
+ method="client.generation.per_plant(start, end, country='FR')",
123
+ cli="entsoe generation per-plant -s 2024-06-01 -e 2024-06-08 -c FR",
124
+ resolution="15min or hourly",
125
+ columns=("timestamp", "country", "unit_name", "psr_type", "value", "quantity_unit"),
126
+ units="MW",
127
+ ),
128
+ ),
129
+ )
130
+
131
+ # ── Transmission ────────────────────────────────────────────────────────
132
+
133
+ TRANSMISSION = Category(
134
+ name="Transmission",
135
+ description="Cross-border physical flows, scheduled exchanges, and transfer capacity",
136
+ namespace="transmission",
137
+ endpoints=(
138
+ Endpoint(
139
+ name="Physical Cross-Border Flows",
140
+ description="Actual measured electricity flows between bidding zones",
141
+ method="client.transmission.crossborder_flows(start, end, country_from='FR', country_to='DE_LU')",
142
+ cli="entsoe transmission flows -s 2024-06-01 -e 2024-06-08 --from FR --to DE_LU",
143
+ resolution="15min or hourly",
144
+ columns=("timestamp", "in_domain", "value", "quantity_unit"),
145
+ units="MW",
146
+ notes="Use --border for multi-border queries: --border FR-*, --border iberian",
147
+ ),
148
+ Endpoint(
149
+ name="Scheduled Commercial Exchanges",
150
+ description="Day-ahead scheduled commercial power exchanges between zones",
151
+ method="client.transmission.scheduled_exchanges(start, end, country_from='FR', country_to='ES')",
152
+ cli="entsoe transmission exchanges -s 2024-06-01 -e 2024-06-08 --from FR --to ES",
153
+ resolution="hourly",
154
+ columns=("timestamp", "in_domain", "value", "quantity_unit"),
155
+ units="MW",
156
+ ),
157
+ Endpoint(
158
+ name="Net Transfer Capacity",
159
+ description="Available transfer capacity (NTC) between bidding zones",
160
+ method="client.transmission.net_transfer_capacity(start, end, country_from='FR', country_to='ES')",
161
+ cli="entsoe transmission capacity -s 2024-06-01 -e 2024-06-08 --from FR --to ES",
162
+ resolution="hourly",
163
+ columns=("timestamp", "in_domain", "value", "quantity_unit"),
164
+ units="MW",
165
+ ),
166
+ ),
167
+ )
168
+
169
+ # ── Balancing ───────────────────────────────────────────────────────────
170
+
171
+ BALANCING = Category(
172
+ name="Balancing",
173
+ description="System imbalance prices and volumes",
174
+ namespace="balancing",
175
+ endpoints=(
176
+ Endpoint(
177
+ name="Imbalance Prices",
178
+ description="System imbalance settlement prices",
179
+ method="client.balancing.imbalance_prices(start, end, country='FR')",
180
+ cli="entsoe balancing prices -s 2024-06-01 -e 2024-06-08 -c FR",
181
+ resolution="15min or hourly (varies by country)",
182
+ columns=("timestamp", "country", "value", "quantity_unit"),
183
+ units="EUR/MWh",
184
+ ),
185
+ Endpoint(
186
+ name="Imbalance Volumes",
187
+ description="Net system imbalance volumes",
188
+ method="client.balancing.imbalance_volumes(start, end, country='FR')",
189
+ cli="entsoe balancing volumes -s 2024-06-01 -e 2024-06-08 -c FR",
190
+ resolution="15min or hourly (varies by country)",
191
+ columns=("timestamp", "country", "value", "quantity_unit"),
192
+ units="MW",
193
+ ),
194
+ ),
195
+ )
196
+
197
+ # ── Full catalog ────────────────────────────────────────────────────────
198
+
199
+ CATEGORIES: dict[str, Category] = {
200
+ "prices": PRICES,
201
+ "load": LOAD,
202
+ "generation": GENERATION,
203
+ "transmission": TRANSMISSION,
204
+ "balancing": BALANCING,
205
+ }
206
+
207
+
208
+ def get_category(name: str) -> Category:
209
+ """Look up a category by name (case-insensitive)."""
210
+ key = name.lower().strip()
211
+ if key not in CATEGORIES:
212
+ raise KeyError(
213
+ f"Unknown category '{name}'. Available: {', '.join(CATEGORIES.keys())}"
214
+ )
215
+ return CATEGORIES[key]
216
+
217
+
218
+ def summary() -> str:
219
+ """Return a human-readable summary of all available data."""
220
+ lines = ["ENTSO-E Data Catalog", "=" * 50, ""]
221
+ for key, cat in CATEGORIES.items():
222
+ lines.append(f"{cat.name} ({cat.namespace})")
223
+ lines.append(f" {cat.description}")
224
+ for ep in cat.endpoints:
225
+ lines.append(f" - {ep.name}: {ep.description}")
226
+ lines.append(f" Resolution: {ep.resolution} | Units: {ep.units}")
227
+ lines.append("")
228
+ return "\n".join(lines)
@@ -7,7 +7,6 @@ from pathlib import Path
7
7
 
8
8
  from ._http import HttpClient
9
9
  from .cache import CacheConfig, CacheStore
10
- from .catalog_manager import ENTSOECatalogManager
11
10
  from .namespaces import (
12
11
  BalancingNamespace,
13
12
  GenerationNamespace,
@@ -101,8 +100,6 @@ class ENTSOEClient:
101
100
  self.transmission = TransmissionNamespace(http, tz=tz, cache=cache_store)
102
101
  self.balancing = BalancingNamespace(http, tz=tz, cache=cache_store)
103
102
 
104
- self.catalog = ENTSOECatalogManager(self)
105
-
106
103
  # Expose for CLI cache commands
107
104
  self._cache = cache_store
108
105
 
@@ -1705,13 +1705,12 @@ wheels = [
1705
1705
 
1706
1706
  [[package]]
1707
1707
  name = "python-entsoe"
1708
- version = "0.5.0"
1708
+ version = "0.4.1"
1709
1709
  source = { editable = "." }
1710
1710
  dependencies = [
1711
1711
  { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
1712
1712
  { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
1713
1713
  { name = "pyarrow" },
1714
- { name = "pyyaml" },
1715
1714
  { name = "requests" },
1716
1715
  { name = "rich" },
1717
1716
  { name = "typer" },
@@ -1729,7 +1728,6 @@ dev = [
1729
1728
  requires-dist = [
1730
1729
  { name = "pandas", specifier = ">=2.0" },
1731
1730
  { name = "pyarrow", specifier = ">=23.0.1" },
1732
- { name = "pyyaml", specifier = ">=6.0" },
1733
1731
  { name = "requests", specifier = ">=2.28" },
1734
1732
  { name = "rich", specifier = ">=13.0" },
1735
1733
  { name = "typer", specifier = ">=0.9" },
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.6.0"
3
- }
@@ -1,51 +0,0 @@
1
- """Built-in data catalog for ENTSO-E Transparency Platform.
2
-
3
- Provides structured metadata about available data categories, endpoints,
4
- country codes, PSR types, and border groups — so users don't need to
5
- consult external documentation every time.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- # Re-export dataclasses for backward compatibility
11
- from entsoe._models import Category, Endpoint
12
- from entsoe.catalog_manager import ENTSOECatalogManager as _Manager
13
-
14
- __all__ = ["Category", "Endpoint", "CATEGORIES", "get_category", "summary"]
15
-
16
- # ── Load categories from YAML ──────────────────────────────────────────
17
-
18
- _mgr = _Manager()
19
- _cats = {c.key: c for c in _mgr._load_categories()}
20
-
21
- CATEGORIES: dict[str, Category] = _cats
22
-
23
- # Individual constants for backward compatibility
24
- PRICES = CATEGORIES["prices"]
25
- LOAD = CATEGORIES["load"]
26
- GENERATION = CATEGORIES["generation"]
27
- TRANSMISSION = CATEGORIES["transmission"]
28
- BALANCING = CATEGORIES["balancing"]
29
-
30
-
31
- def get_category(name: str) -> Category:
32
- """Look up a category by name (case-insensitive)."""
33
- key = name.lower().strip()
34
- if key not in CATEGORIES:
35
- raise KeyError(
36
- f"Unknown category '{name}'. Available: {', '.join(CATEGORIES.keys())}"
37
- )
38
- return CATEGORIES[key]
39
-
40
-
41
- def summary() -> str:
42
- """Return a human-readable summary of all available data."""
43
- lines = ["ENTSO-E Data Catalog", "=" * 50, ""]
44
- for key, cat in CATEGORIES.items():
45
- lines.append(f"{cat.name} ({cat.namespace})")
46
- lines.append(f" {cat.description}")
47
- for ep in cat.endpoints:
48
- lines.append(f" - {ep.name}: {ep.description}")
49
- lines.append(f" Resolution: {ep.resolution} | Units: {ep.units}")
50
- lines.append("")
51
- return "\n".join(lines)
File without changes
File without changes
File without changes