API reference¶
Module functions¶
The functions below use a shared default client; pass client=pse.Client(...) to change settings.
pse_opendata.get(report, start, end=None, *, client=None, **kwargs)
¶
Data of a report of the reports API; see :meth:Client.get.
pse_opendata.legacy(code, start, end=None, *, client=None, **kwargs)
¶
Hourly data of the legacy CSV export; see :meth:Client.legacy.
pse_opendata.history(series, start, end=None, *, client=None, **kwargs)
¶
Hourly series stitched from the legacy export and the API; see :meth:Client.history.
pse_opendata.rce(start, end=None, *, client=None, **kwargs)
¶
RCE price (rce-pln); see :meth:Client.rce.
pse_opendata.sdac(start, end=None, *, client=None, **kwargs)
¶
SDAC price for Poland (csdac-pln); see :meth:Client.sdac.
pse_opendata.fundamentals(start, end=None, *, client=None, **kwargs)
¶
Demand, generation and exchange (his-wlk-cal); see :meth:Client.fundamentals.
pse_opendata.imbalance_prices(start, end=None, *, client=None, **kwargs)
¶
Imbalance and balancing energy prices (crb-rozl); see :meth:Client.imbalance_prices.
pse_opendata.balancing_capacity(start, end=None, *, client=None, **kwargs)
¶
Balancing capacity prices and volumes; see :meth:Client.balancing_capacity.
pse_opendata.reports(legacy=False)
¶
The catalogue as a frame: one row per report of the reports API (or of the legacy export).
pse_opendata.to_hourly(frame, key=())
¶
Hourly means of a sub-hourly frame (e.g. 15-minute).
An hour gets a value only when all its sub-intervals are present and not empty (four quarter-hours for a
15-minute frame); otherwise the value is NaN. Text columns other than key are dropped. Hours are clock hours
in UTC, which are also clock hours in Polish time (the offset is a whole number of hours).
pse_opendata.splice_factor(legacy, api, days=14)
¶
Level ratio legacy / API over days before and after the seam, matched by local weekday and hour.
Both series are hourly values indexed by interval start (tz-aware). Only (weekday, hour) slots present on both sides are used. Multiply the API part by the result to bring it to the legacy level.
Client¶
pse_opendata.Client(*, cache_dir=_DEFAULT, refresh=False, offline=False, allow_stale=False, revision_days=None, timeout=60.0, retries=4, min_interval=0.2, legacy_min_interval=15.0, page_size=20000, session=None, now=None, sleep=None)
¶
Client for the public data of PSE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cache_dir
|
str | Path | None
|
directory of the monthly Parquet cache; default |
_DEFAULT
|
refresh
|
bool
|
download again even months that the cache holds as final. |
False
|
offline
|
bool
|
use the cache only; a missing month raises :class: |
False
|
allow_stale
|
bool
|
when a download fails, use the cached copy of the month (with a warning) instead of raising. |
False
|
revision_days
|
int | None
|
override the per-report number of days after the end of a month during which the cache
re-downloads it (see :attr: |
None
|
timeout
|
float
|
seconds per request (at least 180 for the legacy export). |
60.0
|
retries
|
int
|
retries per request, with exponential backoff, on network errors, HTTP 429 and 5xx. |
4
|
min_interval
|
float
|
pause in seconds between requests to the reports API. |
0.2
|
legacy_min_interval
|
float
|
pause in seconds between requests to the legacy export (it rate-limits hard). |
15.0
|
page_size
|
int
|
rows per page of the reports API ( |
20000
|
session
|
Session | None
|
a |
None
|
now
|
Callable[[], datetime] | None
|
function returning the current time (UTC), for tests. |
None
|
sleep
|
Callable[[float], None] | None
|
replacement for |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
loads |
list[MonthLoad]
|
one :class: |
records(endpoint, *, filter=None, select=None, orderby=None, page_size=None, single_page=False)
¶
Raw records of any endpoint of the reports API, following nextLink pages.
filter and orderby are OData expressions, e.g. filter="business_date eq '2025-01-01'".
Works for endpoints that are not in the catalogue too; no parsing and no cache. single_page=True raises
instead of following nextLink (for reports whose paging can skip rows).
get(report, start, end=None, *, fields=None, dropna=False)
¶
Data of one report for business dates start..end (inclusive, Polish local days).
Returns a frame with start_utc, end_utc, start_local, end_local, business_date, the
row keys of the report (if any) and the value fields (all of them, or fields), one row per interval.
end defaults to start. Dates before the first date of the report are skipped.
dropna=True drops rows in which all requested values are empty (e.g. future intervals of today).
legacy(code, start, end=None, *, fields=None)
¶
Hourly data of a legacy export report (e.g. "PL_WYK_KSE") for business dates start..end.
Same columns as :meth:get. Dates outside the range of the export are skipped. The server is slow (about
a minute per month) and requests are spaced by legacy_min_interval seconds; months are cached for good.
history(series, start, end=None, *, rescale=False)
¶
Hourly series across the switch from the legacy export to the reports API (2024-06-14).
series is one of "rce", "demand", "wind", "pv" (see :data:pse_opendata.stitch.SERIES).
Columns: the five time columns, the series (named like series) and source ("legacy" or
"api"). With rescale=True the API part is multiplied by :func:splice_factor, computed on the two
weeks either side of the seam; the factor is stored in frame.attrs["splice_factor"].
rce(start, end=None, **kwargs)
¶
RCE price, PLN/MWh (report rce-pln).
sdac(start, end=None, **kwargs)
¶
SDAC day-ahead price for Poland, PLN/MWh (report csdac-pln).
fundamentals(start, end=None, **kwargs)
¶
Demand, generation (wind wi, PV pv, ...) and exchange balance, MW (report his-wlk-cal).
imbalance_prices(start, end=None, **kwargs)
¶
Imbalance price CEN and balancing energy prices, PLN/MWh (report crb-rozl).
balancing_capacity(start, end=None, procurement='primary')
¶
Balancing capacity prices and volumes per reserve product in one frame.
procurement="primary" (day-ahead, hourly: cmbp-tp and mbp-tp) or "supplementary"
(15-minute: cmbu-tu and mbu-tu). Columns <product>_price (PLN/MW/h) and <product>_mw (MW),
e.g. afrr_g_price and afrr_g_mw.
pse_opendata.MonthLoad(source, name, month, status, fetched_utc, rows)
dataclass
¶
How one calendar month of one report was loaded; see :attr:Client.loads.
status is "cached" (a final or offline copy from the cache), "downloaded" or "stale" (the
download failed and allow_stale used the cached copy). fetched_utc is when the data were downloaded
(for cached and stale months, when the cached copy was). rows counts the rows of the requested days.
Catalogue¶
pse_opendata.catalog.Report(name, title, title_pl, group, resolution, fields, first_date, description, key=(), unique_key=True, notes=(), revision_days=3, time_field='dtime_utc')
dataclass
¶
A report of the reports API (https://api.raporty.pse.pl/api/
resolution is the length of one interval; the API stamps each row with the interval END (time_field).
key lists the fields that, with the interval, identify a row when a report has several rows per interval
(the entity key in the OpenAPI description, e.g. one row per cross-section); rows are sorted on the interval
and these fields and de-duplicated on them.
unique_key=False marks reports whose rows can repeat in every field (identical anonymous offers). The keyset
paging of the API skips rows at page boundaries for them, so they are requested one business date at a time in
a single page, and nothing is de-duplicated.
revision_days: PSE republishes some reports after corrections; this is how many days after the end of a
month the data may still change (latest republication observed for Sep 2025 - Oct 2026, rounded up). The cache
treats a month as final only when it was downloaded at least this long after the month ended.
value_fields
property
¶
Fields that are not row keys.
pse_opendata.catalog.Field(name, description, unit=None, unit_verified=True, dtype='float')
dataclass
¶
One column of a report.
pse_opendata.catalog.LegacyReport(code, title, title_pl, page, columns, first_date, description, notes=(), last_date=LEGACY_END, resolution='1h')
dataclass
¶
A report of the legacy export https://www.pse.pl/getcsv/-/export/csv//data_od/
Hourly rows, local time (hour 1 = 00:00-01:00, extra autumn hour 2A), ;-separated, decimal comma, cp1250.
pse_opendata.catalog.get_report(name)
¶
Catalogue entry of a report, e.g. get_report("rce-pln").
pse_opendata.catalog.get_legacy_report(code)
¶
Catalogue entry of a legacy export report, e.g. get_legacy_report("PL_WYK_KSE").
Exceptions¶
pse_opendata.exceptions
¶
Exceptions raised by pse-opendata. All of them derive from :class:PseError.
PseError
¶
Bases: Exception
Base class of every error raised by this package.
PseApiError(message, *, status=None, code=None, url=None)
¶
Bases: PseError
An HTTP request to a PSE server failed (after retries, where retrying makes sense).
Attributes:
| Name | Type | Description |
|---|---|---|
status |
HTTP status code, or |
|
code |
error code from the JSON error body of the reports API (e.g. |
|
url |
the requested URL. |