ceps-api 0.1.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.
- ceps_api-0.1.0/.github/dependabot.yml +13 -0
- ceps_api-0.1.0/.github/workflows/publish.yml +75 -0
- ceps_api-0.1.0/.github/workflows/tests.yml +42 -0
- ceps_api-0.1.0/.gitignore +34 -0
- ceps_api-0.1.0/CHANGELOG.md +22 -0
- ceps_api-0.1.0/LICENSE +21 -0
- ceps_api-0.1.0/PKG-INFO +346 -0
- ceps_api-0.1.0/README.md +320 -0
- ceps_api-0.1.0/pyproject.toml +55 -0
- ceps_api-0.1.0/scripts/ceps_catalog.py +206 -0
- ceps_api-0.1.0/src/ceps_api/__init__.py +29 -0
- ceps_api-0.1.0/src/ceps_api/catalog.py +231 -0
- ceps_api-0.1.0/src/ceps_api/client.py +346 -0
- ceps_api-0.1.0/src/ceps_api/convert.py +88 -0
- ceps_api-0.1.0/src/ceps_api/models.py +63 -0
- ceps_api-0.1.0/src/ceps_api/parsing.py +251 -0
- ceps_api-0.1.0/src/ceps_api/py.typed +0 -0
- ceps_api-0.1.0/src/ceps_api/soap.py +99 -0
- ceps_api-0.1.0/src/ceps_api/validation.py +77 -0
- ceps_api-0.1.0/tests/data/codes_data_version.xml +1 -0
- ceps_api-0.1.0/tests/data/estimated_price_dst.xml +1 -0
- ceps_api-0.1.0/tests/data/fault_generation.xml +1 -0
- ceps_api-0.1.0/tests/data/message_emergency_exchange_acer.xml +32 -0
- ceps_api-0.1.0/tests/data/series_imbalance_qh_dst.xml +1 -0
- ceps_api-0.1.0/tests/data/table_emergency_exchange.xml +1 -0
- ceps_api-0.1.0/tests/test_client.py +247 -0
- ceps_api-0.1.0/uv.lock +984 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Keeps the actions in .github/workflows up to date, including the ones pinned to a commit SHA.
|
|
2
|
+
version: 2
|
|
3
|
+
updates:
|
|
4
|
+
- package-ecosystem: github-actions
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: weekly
|
|
8
|
+
# Offer a new version only a week after its release, so a compromised release has time to be caught.
|
|
9
|
+
cooldown:
|
|
10
|
+
default-days: 7
|
|
11
|
+
groups:
|
|
12
|
+
actions:
|
|
13
|
+
patterns: ["*"]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Runs the tests, builds the package and uploads it with Trusted Publishing, so no token is stored anywhere:
|
|
2
|
+
# run by hand (Actions -> publish -> Run workflow) -> TestPyPI, to try a release out
|
|
3
|
+
# a GitHub Release is published -> PyPI
|
|
4
|
+
# Both need a (pending) publisher for this repo, this workflow and the environment on the index.
|
|
5
|
+
name: publish
|
|
6
|
+
on:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
release:
|
|
9
|
+
types: [published]
|
|
10
|
+
|
|
11
|
+
permissions: {}
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
tests:
|
|
15
|
+
uses: ./.github/workflows/tests.yml
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
build:
|
|
20
|
+
needs: tests
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v7
|
|
26
|
+
with:
|
|
27
|
+
persist-credentials: false
|
|
28
|
+
- name: Check that the release tag matches the version in pyproject.toml
|
|
29
|
+
if: github.event_name == 'release'
|
|
30
|
+
env:
|
|
31
|
+
TAG: ${{ github.event.release.tag_name }}
|
|
32
|
+
run: |
|
|
33
|
+
version=$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')
|
|
34
|
+
if [ "v$version" != "$TAG" ]; then
|
|
35
|
+
echo "::error::Release tag $TAG does not match version $version in pyproject.toml"
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
39
|
+
- run: uv build
|
|
40
|
+
- uses: actions/upload-artifact@v7
|
|
41
|
+
with:
|
|
42
|
+
name: dist
|
|
43
|
+
path: dist/
|
|
44
|
+
|
|
45
|
+
testpypi:
|
|
46
|
+
if: github.event_name == 'workflow_dispatch'
|
|
47
|
+
needs: build
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
environment: testpypi
|
|
50
|
+
permissions:
|
|
51
|
+
id-token: write
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/download-artifact@v8
|
|
54
|
+
with:
|
|
55
|
+
name: dist
|
|
56
|
+
path: dist/
|
|
57
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
58
|
+
with:
|
|
59
|
+
repository-url: https://test.pypi.org/legacy/
|
|
60
|
+
# A version cannot be uploaded twice, so a second try of the same version would fail.
|
|
61
|
+
skip-existing: true
|
|
62
|
+
|
|
63
|
+
pypi:
|
|
64
|
+
if: github.event_name == 'release'
|
|
65
|
+
needs: build
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
environment: pypi
|
|
68
|
+
permissions:
|
|
69
|
+
id-token: write
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/download-artifact@v8
|
|
72
|
+
with:
|
|
73
|
+
name: dist
|
|
74
|
+
path: dist/
|
|
75
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Lint and offline tests on every push to main and every pull request; publish.yml runs them before a release.
|
|
2
|
+
# The live tests are left out, so a ČEPS outage does not fail the build.
|
|
3
|
+
name: tests
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
# A newer commit cancels the run of an older one. The event is part of the group, so a run called
|
|
14
|
+
# from publish.yml and a push run on the same branch do not cancel each other.
|
|
15
|
+
concurrency:
|
|
16
|
+
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ${{ matrix.os }}
|
|
22
|
+
timeout-minutes: 15
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: false
|
|
25
|
+
matrix:
|
|
26
|
+
os: [ubuntu-latest]
|
|
27
|
+
python-version: ["3.10", "3.12", "3.14"]
|
|
28
|
+
include:
|
|
29
|
+
# Windows needs tzdata for zoneinfo; one Python version is enough to cover that.
|
|
30
|
+
- os: windows-latest
|
|
31
|
+
python-version: "3.14"
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v7
|
|
34
|
+
with:
|
|
35
|
+
persist-credentials: false
|
|
36
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
37
|
+
with:
|
|
38
|
+
python-version: ${{ matrix.python-version }}
|
|
39
|
+
- run: uv sync --locked
|
|
40
|
+
- run: uv run ruff check .
|
|
41
|
+
- run: uv run mypy
|
|
42
|
+
- run: uv run pytest -m "not live"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Secrets and local config
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
.claude/
|
|
5
|
+
|
|
6
|
+
# Python
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.venv/
|
|
11
|
+
build/
|
|
12
|
+
dist/
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
htmlcov/
|
|
17
|
+
.ipynb_checkpoints/
|
|
18
|
+
|
|
19
|
+
# Generated by scripts/ceps_catalog.py, reviewed and copied over by hand
|
|
20
|
+
scripts/ceps_methods_generated.py
|
|
21
|
+
|
|
22
|
+
# Downloaded data
|
|
23
|
+
*.csv
|
|
24
|
+
*.parquet
|
|
25
|
+
|
|
26
|
+
# CEPS interface documentation, kept locally only.
|
|
27
|
+
# Download it from https://www.ceps.cz/cs/webove-sluzby
|
|
28
|
+
webove-sluzby-dokumentace/
|
|
29
|
+
|
|
30
|
+
# Editors and OS
|
|
31
|
+
.vscode/
|
|
32
|
+
.idea/
|
|
33
|
+
.DS_Store
|
|
34
|
+
Thumbs.db
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
|
+
and the project follows [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
<!-- At a release: rename [Unreleased] to [X.Y.Z] - YYYY-MM-DD, add an empty [Unreleased] above it,
|
|
8
|
+
and point the links below at the release tag (releases/tag/vX.Y.Z) and at compare/vX.Y.Z...HEAD. -->
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
## [0.1.0] - 2026-10-19
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `Ceps` with a wrapper returning a pandas DataFrame for each of the 21 methods of the ČEPS web service.
|
|
17
|
+
- `Ceps.parameters()` listing the methods and the arguments and values each accepts.
|
|
18
|
+
- Checks of methods, aggregations, functions, versions and filter values before a request is sent.
|
|
19
|
+
- Dates taken as Czech local time; time series indexed in `Europe/Prague`, unique across DST changes.
|
|
20
|
+
|
|
21
|
+
[Unreleased]: https://github.com/Frantis3k/ceps-api/compare/v0.1.0...HEAD
|
|
22
|
+
[0.1.0]: https://github.com/Frantis3k/ceps-api/releases/tag/v0.1.0
|
ceps_api-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Frantis3k
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ceps_api-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: ceps-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial Python client for the ČEPS (Czech TSO) data web service, returning pandas DataFrames.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Frantis3k/ceps-api
|
|
6
|
+
Project-URL: Issues, https://github.com/Frantis3k/ceps-api/issues
|
|
7
|
+
Project-URL: Changelog, https://github.com/Frantis3k/ceps-api/blob/main/CHANGELOG.md
|
|
8
|
+
Author: Frantis3k
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ceps,czech,electricity,energy,imbalance,tso
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: pandas>=2.3
|
|
24
|
+
Requires-Dist: tzdata; sys_platform == 'win32'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# ČEPS-api
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/ceps-api/)
|
|
30
|
+
[](https://pypi.org/project/ceps-api/)
|
|
31
|
+
[](https://github.com/Frantis3k/ceps-api/actions/workflows/tests.yml)
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="https://raw.githubusercontent.com/Frantis3k/ceps-api/main/docs/ceps-api-demo.gif" alt="ceps-api demo" width="700">
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
[Jump to English version](#english)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
Neoficiální Python klient webové služby [ČEPS](https://www.ceps.cz/cs/webove-sluzby), provozovatele české
|
|
41
|
+
přenosové soustavy. Stahuje systémovou odchylku, aktivovanou regulační energii a její ceny, odhad ceny
|
|
42
|
+
odchylky, výrobu, zatížení, přeshraniční toky a další data. Každá metoda služby má na třídě `Ceps`
|
|
43
|
+
stejnojmennou metodu, která vrací pandas DataFrame.
|
|
44
|
+
|
|
45
|
+
Projekt je neoficiální, podrobnosti viz [Disclaimer](#disclaimer).
|
|
46
|
+
|
|
47
|
+
### Instalace
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
pip install ceps-api
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Vyžaduje Python 3.10 nebo novější. Služba nepotřebuje žádný klíč ani registraci.
|
|
54
|
+
|
|
55
|
+
### Rychlý start
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from ceps_api import Ceps
|
|
59
|
+
|
|
60
|
+
ceps = Ceps()
|
|
61
|
+
df = ceps.AktualniSystemovaOdchylkaCR("2026-10-16", "2026-10-16T23:59", aggregation="QH")
|
|
62
|
+
print(df.head())
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
Aktuální odchylka [MW]
|
|
67
|
+
timestamp
|
|
68
|
+
2026-10-16 00:00:00+02:00 -56.98927
|
|
69
|
+
2026-10-16 00:15:00+02:00 -70.02203
|
|
70
|
+
2026-10-16 00:30:00+02:00 -63.87983
|
|
71
|
+
2026-10-16 00:45:00+02:00 -75.59872
|
|
72
|
+
2026-10-16 01:00:00+02:00 -23.32196
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Datum jde zadat i jako `datetime`, například `datetime(2026, 10, 16, 23, 59)`.
|
|
76
|
+
|
|
77
|
+
### Dostupné metody a jejich parametry
|
|
78
|
+
|
|
79
|
+
Seznam metod je v [tabulce na konci](#metody--methods). `Ceps.parameters()` vypíše všechny dostupné metody
|
|
80
|
+
a jejich argumenty. S názvem metody ukáže i povolené hodnoty: agregace (např. `QH`, `HR`), funkce
|
|
81
|
+
(`AVG`, `MIN`, `MAX`, `SUM`), verze dat a speciální parametry jako `param1`.
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
print(Ceps.parameters()) # všechny metody a jejich argumenty
|
|
85
|
+
print(Ceps.parameters("AktualniSystemovaOdchylkaCR")) # parametry a povolené hodnoty jedné metody
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Čas a časová pásma
|
|
89
|
+
|
|
90
|
+
- `start` a `end` jsou český místní čas: `date`, `datetime` nebo ISO řetězec (`"2026-10-16"`,
|
|
91
|
+
`"2026-10-16T10:00"`). Čas s časovou zónou se nejdřív převede na český čas.
|
|
92
|
+
- Oba konce se počítají: celý den je `start="2026-10-16"`, `end="2026-10-16T23:59"`.
|
|
93
|
+
- Časové řady mají index `timestamp`, tedy začátek kroku v pásmu `Europe/Prague`. Index zůstává
|
|
94
|
+
jednoznačný i přes změnu času: den, kdy se čas posouvá zpět, má 100 čtvrthodin a hodina 02:00–03:00
|
|
95
|
+
je v něm dvakrát, jednou s posunem `+02:00` a jednou s `+01:00`.
|
|
96
|
+
- `aggregation` je délka kroku (`MI` minuta, `QH` čtvrthodina, `HR` hodina, …) a `function` způsob,
|
|
97
|
+
jak se hodnoty v kroku kombinují (`AVG` výchozí, `MIN`, `MAX`, `SUM`).
|
|
98
|
+
|
|
99
|
+
### Aktuálnost dat
|
|
100
|
+
|
|
101
|
+
Ne všechna data jsou v reálném čase. Každá metoda je zveřejňuje s jiným zpožděním, takže pokud pro
|
|
102
|
+
poslední minuty nebo čtvrthodiny nic nepřijde, nemusí jít o chybu, data jen ještě nejsou k dispozici.
|
|
103
|
+
|
|
104
|
+
Nejčerstvější data má minutová řada `AktualniSystemovaOdchylkaCR` (bez `aggregation`), zpožděná
|
|
105
|
+
obvykle jen o minutu nebo dvě. Například odchylka za posledních 15 minut:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from datetime import datetime, timedelta
|
|
109
|
+
from zoneinfo import ZoneInfo
|
|
110
|
+
|
|
111
|
+
now = datetime.now(ZoneInfo("Europe/Prague"))
|
|
112
|
+
df = ceps.AktualniSystemovaOdchylkaCR(now - timedelta(minutes=15), now)
|
|
113
|
+
print(df.tail())
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Zpoždění se může měnit, ČEPS ho nijak nezaručuje.
|
|
117
|
+
|
|
118
|
+
### Chyby
|
|
119
|
+
|
|
120
|
+
Neznámou metodu, agregaci nebo hodnotu filtru odmítne `ValueError` ještě před odesláním požadavku.
|
|
121
|
+
Služba totiž na neznámou hodnotu často neodpoví chybou, ale vrátí prázdná nebo nefiltrovaná data.
|
|
122
|
+
Chybu služby nebo sítě hlásí `CepsError`.
|
|
123
|
+
|
|
124
|
+
### Jak to funguje
|
|
125
|
+
|
|
126
|
+
Třída `Ceps` v `client.py` pošle každé volání přes tyto moduly:
|
|
127
|
+
|
|
128
|
+
1. `convert.py` převede data na český místní čas a `validation.py` zkontroluje parametry podle `catalog.py`,
|
|
129
|
+
2. `soap.py` pošle SOAP požadavek a vrátí syrové XML,
|
|
130
|
+
3. `parsing.py` z XML udělá pythonní data, která `convert.py` převede na DataFrame.
|
|
131
|
+
|
|
132
|
+
### Alternativy
|
|
133
|
+
|
|
134
|
+
Pokud vám tato knihovna nevyhovuje, data ČEPS jsou dostupná i jinak:
|
|
135
|
+
|
|
136
|
+
- [Keboola konektor ČEPS](https://help.keboola.com/components/extractors/other/ceps/), extraktor
|
|
137
|
+
pro platformu Keboola,
|
|
138
|
+
- [ceps-ote](https://github.com/whipeeer-creator/ceps-ote) od progrunners, další Python wrapper,
|
|
139
|
+
- [data na ceps.cz](https://www.ceps.cz/cs/data), původní zdroj přímo od ČEPS.
|
|
140
|
+
|
|
141
|
+
### Licence
|
|
142
|
+
|
|
143
|
+
Kód je pod licencí [MIT](https://github.com/Frantis3k/ceps-api/blob/main/LICENSE). Na co se licence vztahuje, viz [Disclaimer](#disclaimer).
|
|
144
|
+
|
|
145
|
+
### Disclaimer
|
|
146
|
+
|
|
147
|
+
Projekt je neoficiální. Nemá žádnou vazbu na společnost ČEPS, a.s., která ho nevyvíjí,
|
|
148
|
+
nepodporuje ani neschvaluje. Název ČEPS je použit pouze k označení webové služby,
|
|
149
|
+
se kterou knihovna komunikuje.
|
|
150
|
+
|
|
151
|
+
Data poskytuje a vlastní ČEPS, a.s. Tento balíček je jen volá přes veřejnou webovou službu a nic
|
|
152
|
+
z nich neukládá. Licence MIT se vztahuje pouze na kód této knihovny, nikoli na data. Podmínky užití
|
|
153
|
+
dat stanovuje ČEPS, a.s., a za dodržení podmínek užití webové služby i publikovaných dat odpovídá
|
|
154
|
+
uživatel.
|
|
155
|
+
|
|
156
|
+
Knihovna je poskytována „tak, jak je“, bez jakékoli záruky. Autor neodpovídá za správnost,
|
|
157
|
+
úplnost ani aktuálnost stažených dat a nenese odpovědnost za škody vzniklé jejich použitím.
|
|
158
|
+
Data mohou být chybná, zpožděná nebo neúplná, například kvůli změnám ve webové službě
|
|
159
|
+
nebo chybám v této knihovně. Pokud data používáte k obchodování, vyúčtování nebo jiným
|
|
160
|
+
závazným účelům, ověřte je u primárního zdroje.
|
|
161
|
+
|
|
162
|
+
Buďte ke službě ohleduplní: nestahujte velké objemy paralelně a delší období si raději ukládejte.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## English
|
|
167
|
+
|
|
168
|
+
Unofficial Python client for the web service of [ČEPS](https://www.ceps.cz/en/web-services), the Czech
|
|
169
|
+
transmission system operator. It downloads system imbalance, activated balancing energy and its prices,
|
|
170
|
+
the estimated imbalance price, generation, load, cross-border flows and more. Every method of the
|
|
171
|
+
service has a method of the same name on `Ceps`, which returns a pandas DataFrame.
|
|
172
|
+
|
|
173
|
+
This project is unofficial, see the [Disclaimer](#disclaimer-1) for details.
|
|
174
|
+
|
|
175
|
+
### Installation
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
pip install ceps-api
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Requires Python 3.10 or newer. The service needs no key and no registration.
|
|
182
|
+
|
|
183
|
+
### Quick start
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from ceps_api import Ceps
|
|
187
|
+
|
|
188
|
+
ceps = Ceps()
|
|
189
|
+
df = ceps.AktualniSystemovaOdchylkaCR("2026-10-16", "2026-10-16T23:59", aggregation="QH")
|
|
190
|
+
print(df.head())
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
Aktuální odchylka [MW]
|
|
195
|
+
timestamp
|
|
196
|
+
2026-10-16 00:00:00+02:00 -56.98927
|
|
197
|
+
2026-10-16 00:15:00+02:00 -70.02203
|
|
198
|
+
2026-10-16 00:30:00+02:00 -63.87983
|
|
199
|
+
2026-10-16 00:45:00+02:00 -75.59872
|
|
200
|
+
2026-10-16 01:00:00+02:00 -23.32196
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
A date can also be given as a `datetime`, for example `datetime(2026, 10, 16, 23, 59)`.
|
|
204
|
+
|
|
205
|
+
### Available methods and their parameters
|
|
206
|
+
|
|
207
|
+
The methods are listed in the [table at the end](#metody--methods). `Ceps.parameters()` shows every
|
|
208
|
+
available method and its arguments. Given a method name, it also shows the allowed values: aggregations
|
|
209
|
+
(e.g. `QH`, `HR`), functions (`AVG`, `MIN`, `MAX`, `SUM`), data versions and special parameters such
|
|
210
|
+
as `param1`.
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
print(Ceps.parameters()) # all methods and their arguments
|
|
214
|
+
print(Ceps.parameters("AktualniSystemovaOdchylkaCR")) # parameters and allowed values of one method
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Time and time zones
|
|
218
|
+
|
|
219
|
+
- `start` and `end` are Czech local time: a `date`, a `datetime` or an ISO string (`"2026-10-16"`,
|
|
220
|
+
`"2026-10-16T10:00"`). A time with a time zone is converted to Czech time first.
|
|
221
|
+
- Both ends are included: a whole day is `start="2026-10-16"`, `end="2026-10-16T23:59"`.
|
|
222
|
+
- Time series are indexed by `timestamp`, the start of the step in `Europe/Prague`. The index stays
|
|
223
|
+
unique across the clock change: the day the clocks go back has 100 quarter hours, with 02:00–03:00
|
|
224
|
+
twice, once at `+02:00` and once at `+01:00`.
|
|
225
|
+
- `aggregation` is the time step (`MI` minute, `QH` quarter hour, `HR` hour, …) and `function` how
|
|
226
|
+
the values within it are combined (`AVG` by default, `MIN`, `MAX`, `SUM`).
|
|
227
|
+
|
|
228
|
+
### How recent the data is
|
|
229
|
+
|
|
230
|
+
Not all data is real time. Each method publishes its data with a different delay, so if nothing
|
|
231
|
+
comes back for the last few minutes or quarter hours, it is not necessarily an error: the data is
|
|
232
|
+
just not available yet.
|
|
233
|
+
|
|
234
|
+
The freshest data comes from the per-minute series of `AktualniSystemovaOdchylkaCR` (without
|
|
235
|
+
`aggregation`), usually only a minute or two behind. For example, the imbalance over the last
|
|
236
|
+
15 minutes:
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from datetime import datetime, timedelta
|
|
240
|
+
from zoneinfo import ZoneInfo
|
|
241
|
+
|
|
242
|
+
now = datetime.now(ZoneInfo("Europe/Prague"))
|
|
243
|
+
df = ceps.AktualniSystemovaOdchylkaCR(now - timedelta(minutes=15), now)
|
|
244
|
+
print(df.tail())
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The delays can change; ČEPS does not guarantee them.
|
|
248
|
+
|
|
249
|
+
### Errors
|
|
250
|
+
|
|
251
|
+
An unknown method, aggregation or filter value raises `ValueError` before any request is sent, since
|
|
252
|
+
the service often answers an unknown value with empty or unfiltered data instead of an error. A failure
|
|
253
|
+
of the service or the network raises `CepsError`.
|
|
254
|
+
|
|
255
|
+
### How it works
|
|
256
|
+
|
|
257
|
+
The `Ceps` class in `client.py` passes every call through these modules:
|
|
258
|
+
|
|
259
|
+
1. `convert.py` converts the dates to Czech local time and `validation.py` checks the parameters against `catalog.py`,
|
|
260
|
+
2. `soap.py` sends the SOAP request and returns the raw XML,
|
|
261
|
+
3. `parsing.py` turns the XML into plain Python, which `convert.py` turns into a DataFrame.
|
|
262
|
+
|
|
263
|
+
### Alternatives
|
|
264
|
+
|
|
265
|
+
If this library does not suit you, the ČEPS data is also available elsewhere:
|
|
266
|
+
|
|
267
|
+
- [Keboola ČEPS connector](https://help.keboola.com/components/extractors/other/ceps/), an extractor
|
|
268
|
+
for the Keboola platform,
|
|
269
|
+
- [ceps-ote](https://github.com/whipeeer-creator/ceps-ote) by progrunners, another Python wrapper,
|
|
270
|
+
- [data on ceps.cz](https://www.ceps.cz/en/all-data), the original source straight from ČEPS.
|
|
271
|
+
|
|
272
|
+
### Licence
|
|
273
|
+
|
|
274
|
+
The code is under the [MIT licence](https://github.com/Frantis3k/ceps-api/blob/main/LICENSE). For what it covers, see the [Disclaimer](#disclaimer-1).
|
|
275
|
+
|
|
276
|
+
### Disclaimer
|
|
277
|
+
|
|
278
|
+
This project is unofficial. It is not affiliated with ČEPS, a.s., which does not develop,
|
|
279
|
+
support or endorse it. The name ČEPS is used only to identify the web service the library
|
|
280
|
+
communicates with.
|
|
281
|
+
|
|
282
|
+
The data is provided and owned by ČEPS, a.s. This package only calls the public web service and stores
|
|
283
|
+
nothing. The MIT licence covers only the code of this library, not the data. The terms of use of the
|
|
284
|
+
data are set by ČEPS, a.s., and you are responsible for complying with the terms of use of the web
|
|
285
|
+
service and the data it publishes.
|
|
286
|
+
|
|
287
|
+
The library is provided "as is", without warranty of any kind. The author is not responsible
|
|
288
|
+
for the accuracy, completeness or timeliness of the downloaded data and accepts no liability
|
|
289
|
+
for any damage arising from its use. The data may be wrong, delayed or incomplete, for example
|
|
290
|
+
because of changes to the web service or bugs in this library. If you use the data for trading,
|
|
291
|
+
settlement or other binding purposes, verify it against the primary source.
|
|
292
|
+
|
|
293
|
+
Please be gentle with the service: do not download large volumes in parallel, and store longer
|
|
294
|
+
periods rather than downloading them again.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Metody / Methods
|
|
299
|
+
|
|
300
|
+
Popisy jsou kvůli přehlednosti zkrácené. Úplný popis metod je v dokumentaci ČEPS na
|
|
301
|
+
[ceps.cz/cs/webove-sluzby](https://www.ceps.cz/cs/webove-sluzby), v souboru
|
|
302
|
+
*ČEPSVIP_Popis rozhraní strukturovaná data 3.2.docx*.
|
|
303
|
+
|
|
304
|
+
The descriptions are shortened for an overview. The full description of the methods is in the ČEPS
|
|
305
|
+
documentation at [ceps.cz/cs/webove-sluzby](https://www.ceps.cz/cs/webove-sluzby), in the file
|
|
306
|
+
*ČEPSVIP_Popis rozhraní strukturovaná data 3.2.docx*.
|
|
307
|
+
|
|
308
|
+
| Method | Data | Arguments |
|
|
309
|
+
|---|---|---|
|
|
310
|
+
| `AktivaceSVRvCR` | Activated balancing energy (aFRR+/-, mFRR+/-, mFRR5), [MW] | start, end, aggregation, function, param1 |
|
|
311
|
+
| `AktualniCenaRE` | Price of activated regulating energy (aFRR, mFRR+/-, mFRR5), [EUR/MWh] | start, end, param1 |
|
|
312
|
+
| `AktualniSystemovaOdchylkaCR` | Current system imbalance of the Czech control area, [MW] | start, end, aggregation, function |
|
|
313
|
+
| `CrossborderPowerFlows` | Actual and planned flows per neighbouring operator, [MW] | start, end, aggregation, function, version |
|
|
314
|
+
| `DataAgregation` | Lists the aggregation codes. Not a time series | |
|
|
315
|
+
| `DataVersion` | Lists the version codes. Not a time series | |
|
|
316
|
+
| `EmergencyExchange` | Emergency assistance, redispatch and regulating energy from abroad, a row per border and direction. Only has rows when something happened | start, end, aggregation, function, version, param1, param2 |
|
|
317
|
+
| `EmergencyExchangeACER` | Emergency exchange as an ACER message. Not a time series | start, end, param1, param2 |
|
|
318
|
+
| `Emise` | CO2 intensity of generation, [g CO2/kWh]. Always per quarter hour, the service ignores the aggregation | start, end, aggregation, function, version, param1 |
|
|
319
|
+
| `ExportImportSVR` | Exchange with the European balancing platforms (imbalance netting, MARI, PICASSO) | start, end, aggregation, function, param1 |
|
|
320
|
+
| `ExportImportVykonu` | Export (+) and import (-) of power within the European platforms and foreign assistance, [MW]. Data from 2022-05-20 to 2023-08-25, then ExportImportSVR | start, end, aggregation, function |
|
|
321
|
+
| `Frekvence` | System frequency, [Hz] | start, end |
|
|
322
|
+
| `Generation` | Gross generation by plant type, [MW] | start, end, aggregation, function, version, param1 |
|
|
323
|
+
| `GenerationPlan` | Planned gross generation, [MW] | start, end, aggregation, function, version |
|
|
324
|
+
| `GenerationRES` | Estimated wind and solar generation, [MW] | start, end, aggregation, function, version, param1 |
|
|
325
|
+
| `Load` | Load with and without pumping, [MW]; load is gross generation + import - export - pumping. The forecast versions have it without pumping only | start, end, aggregation, function, version |
|
|
326
|
+
| `MaximalniCenySVRnaDT` | Maximum prices of balancing services on the day-ahead market, a row per day and currency. Data from 2022-08-26 to 2024-07-04 | start, end |
|
|
327
|
+
| `NepredvidatelneOdmitnuteNabidky` | Unforeseeably rejected bids of one product (aFRR+ if none is given): per hour and bid the price offered [Kč] and the power not accepted [MW] | start, end, param1 |
|
|
328
|
+
| `OdhadovanaCenaOdchylky` | Estimated imbalance price, [Kč/MWh]. Not a plain time series | start, end |
|
|
329
|
+
| `OfferPrices` | Offer prices of regulating energy: per hour and bid the price [Kč] and the power [MW]. Data from November 2017 to 2022-03-31 | start, end, version, param1 |
|
|
330
|
+
| `PowerBalance` | Yearly forecast of the power balance: domestic sources, outages, reserve of ancillary services and load, [MW] | start, end, aggregation, function, version, param1 |
|
|
331
|
+
|
|
332
|
+
## Vývoj / Development
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
git clone https://github.com/Frantis3k/ceps-api.git
|
|
336
|
+
cd ceps-api
|
|
337
|
+
uv sync
|
|
338
|
+
uv run ruff check .
|
|
339
|
+
uv run mypy
|
|
340
|
+
uv run pytest -m "not live" # offline, against responses saved in tests/data
|
|
341
|
+
uv run pytest -m live # calls the real service
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
When ČEPS changes the service, `uv run scripts/ceps_catalog.py` writes a fresh catalog to
|
|
345
|
+
`scripts/ceps_methods_generated.py` for review; it is copied over `CEPS_METHODS` in
|
|
346
|
+
`src/ceps_api/catalog.py` by hand.
|