How to query data from the ENTSO-E transparency platform using Python?
A step-by-step guide to install the Python API for the ENTSO-E transparency platform and sample code on how to query data.
Most of the people working in the energy field know the ENTSO-E (European network of transmission system operators for electricity) transparency platform, which is an open-source collection of electricity generation, transportation, and consumption data for the pan-European market. Data can be downloaded directly on the platform, or by using the convenient Python API, which I will discuss here.
Preliminaries
To use the Python API, you need to complete the following three steps:
- Download and install the Python client for the ENTSO-E platform first. Link to the Github repository.
- Register on the ENTSO-E transparency platform (click login at the top right of the page): https://transparency.entsoe.eu/dashboard/show
- Request an API key by sending an email to transparency@entsoe.eu with “Restful API access” in the subject line. In the email body state your registered email address. You will receive an email when you have been provided with the API key. The key is then visible in your ENTSO-E account under “Web API Security Token”.
Once you have completed the above steps, you are ready to query data from the transparency platform with Python. It is quite handy if you want to do electricity market analysis as you get the data in tabular format and for a customizable time range. Below an example of the generation per power plant (in MW).
Query data with Python
Now let’s see how to query data from the transparency platform. Below you can find the Python code to query most of the available data. The start/end time and the respective time zone can be selected as well as the desired countries.
Important: Before executing the script you must fill in your API key as indicated!
"""
Created January 2021
@author: Michael Pertl,
michael@thesmartinsights.com
www.thesmartinsights.com
Query data from ENTSO-E transparency portal
------------------------------------------------------------------------------
DISCLAIMER:
You may use the Code for any private or commercial purpose. However, you may not sell,
sub-license, rent, lease, lend, assign or otherwise transfer, duplicate or otherwise
reproduce, directly or indirectly, the Code in whole or in part.
You acknowledge that the Code is provided “AS IS” and thesmartinsights.com expressly
disclaims all warranties and conditions including, but not limited to, any implied
warranties for suitability of the Code for a particular purpose, or any form of warranty
that operation of the Code will be error-free.
You acknowledge that in no event shall thesmartinsights.com or any of its affiliates be
liable for any damages arising out of the use of the Code or otherwise in connection with
this agreement, including, without limitation, any direct, indirect special, incidental
or consequential damages, whether any claim for such recovery is based on theories of
contract, negligence, and even if thesmartinsights.com has knowledge of the possibility
of potential loss or damage.
-------------------------------------------------------------------------------
"""
import pandas as pd
from entsoe import EntsoePandasClient
import pandas as pd
from entsoe import EntsoePandasClient
# %% parameter definitions
# client = EntsoePandasClient(api_key='YOUR API KEY GOES HERE')
start = pd.Timestamp('20201201', tz ='UTC')
end = pd.Timestamp('20201202', tz ='UTC')
country_code_1 = 'AT' #
country_code_2 = 'DE_LU' #
country_code_3 = 'CZ' #
#day-ahead market prices (€/MWh)
DA_prices = client.query_day_ahead_prices(country_code_1, start=start,end=end)
#generation (MW)
generation = client.query_generation(country_code_1, start=start,end=end)
generation_per_plant = client.query_generation_per_plant(country_code_1, start=start,end=end)
generation_forecast = client.query_generation_forecast(country_code_1, start=start,end=end)
wind_solar_forecast = client.query_wind_and_solar_forecast(country_code_1, start=start,end=end, psr_type=None)
installed_generation_capacity = client.query_installed_generation_capacity(country_code_1, start=start,end=end)
installed_generation_capacity_per_unit = client.query_installed_generation_capacity_per_unit(country_code_1, start=start,end=end)
#load and load forecast (MW)
load = client.query_load(country_code_1, start=start,end=end)
load_forecast = client.query_load_forecast(country_code_1, start=start,end=end)
#day-ahead scheduled (commercial) exchanges (MW)
scheduled_exchanges = client.query_scheduled_exchanges(country_code_1, country_code_2, start=start,end=end)
#cross-border flows (physical) (MW): to get resulting flow both directions need to be considerd, e.g netflow_AT_DE = (AT-DE) - (DE-AT)
crossborder_flows_1 = client.query_crossborder_flows(country_code_1, country_code_2, start=start,end=end)
crossborder_flows_2 = client.query_crossborder_flows( country_code_2,country_code_1, start=start,end=end)
crossborder_flow_net = crossborder_flows_1 - crossborder_flows_2
#works only for countries without flow-based border (MW)
net_transfer_capacity_dayahead = client.query_net_transfer_capacity_dayahead(country_code_1, country_code_3, start=start,end=end)
net_transfer_capacity_monthahead = client.query_net_transfer_capacity_monthahead(country_code_1, country_code_3, start=start,end=end)
net_transfer_capacity_weekahead = client.query_net_transfer_capacity_weekahead(country_code_1, country_code_3, start=start,end=end)
net_transfer_capacity_yearahead = client.query_net_transfer_capacity_yearahead(country_code_1, country_code_3, start=start,end=end)
#contracted reserves (MW) and prices (€/MW/period)
contracted_reserve_amount = client.query_contracted_reserve_amount(country_code_1, start=start, end=end, type_marketagreement_type='A01')
contracted_reserve_prices = client.query_contracted_reserve_prices(country_code_1, start=start, end=end, type_marketagreement_type='A01')
#unavailability of generation and production units
unavailability_of_generation_units = client.query_unavailability_of_generation_units(country_code_1, start=start,end=end)
unavailability_of_production_units = client.query_unavailability_of_production_units(country_code_1, start=start,end=end)
Country codes
Below you can find a table with the available country codes and corresponding country/control area which can be entered in the script as shown in the code above, e.g. country_code_1 = ‘AT’ for Austria.
Code | Country/Control Area | Code | Country/Control Area |
---|---|---|---|
DE_50HZ | 50Hertz CA | IT_NORD_SI | IT-North-SI BZ |
AL | Albania | IT_PRGP | IT-Priolo BZ |
DE_AMPRION | Amprion CA | IT_ROSN | IT-Rossano BZ |
AT | Austria | IT_SARD | IT-Sardinia BZ |
BY | Belarus BZ / CA / MBA | IT_SICI | IT-Sicily BZ |
BE | Belgium | IT_SUD | IT-South BZ |
BA | Bosnia Herzegovina | RU_KGD | Kaliningrad BZ / CA / MBA |
BG | Bulgaria | LV | Latvia |
CZ_DE_SK | BZ CZ+DE+SK BZ / BZA | LT | Lithuania |
HR | Croatia | LU | Luxembourg |
CWE | CWE Region | MT | Malta |
CY | Cyprus | ME | Montenegro |
CZ | Czech Republic | GB | National Grid BZ / CA/ MBA |
DE_AT_LU | DE-AT-LU BZ | NL | Netherlands |
DE_LU | DE-LU BZ / MBA | NO_1 | NO1 BZ / MBA |
DK | Denmark | NO_2 | NO2 BZ / MBA |
DK_1 | DK1 BZ / MBA | NO_3 | NO3 BZ / MBA |
DK_2 | DK2 BZ / MBA | NO_4 | NO4 BZ / MBA |
DK_CA | Denmark | NO_5 | NO5 BZ / MBA |
EE | Estonia | NO | Norway |
FI | Finland | PL_CZ | PL-CZ BZA / CA |
MK | Former Yugoslav Republic of Macedonia | PL | Poland |
FR | France | PT | Portugal |
DE | Germany | MD | Republic of Moldova |
GR | Greece | RO | Romania |
HU | Hungary | RU | Russia BZ / CA / MBA |
IS | Iceland | SE_1 | SE1 BZ / MBA |
IE_SEM | Ireland (SEM) BZ / MBA | SE_2 | SE2 BZ / MBA |
IE | Ireland | SE_3 | SE3 BZ / MBA |
IT | Italy | SE_4 | SE4 BZ / MBA |
IT_SACO_AC | Italy_Saco_AC | RS | Serbia |
IT_SACO_DC | Italy_Saco_DC | SK | Slovakia |
IT_BRNN | IT-Brindisi BZ | SI | Slovenia |
IT_CNOR | IT-Centre-North BZ | GB_NIR | Northern Ireland |
IT_CSUD | IT-Centre-South BZ | ES | Spain |
IT_FOGN | IT-Foggia BZ | SE | Sweden |
IT_GR | IT-GR BZ | CH | Switzerland |
IT_MACRO_NORTH | IT-MACROZONE NORTH MBA | DE_TENNET | TenneT GER CA |
IT_MACRO_SOUTH | IT-MACROZONE SOUTH MBA | DE_TRANSNET | TransnetBW CA |
IT_MALTA | IT-Malta BZ | TR | Turkey BZ / CA / MBA |
IT_NORD | IT-North BZ | UA | Ukraine |
IT_NORD_AT | IT-North-AT BZ | UA_DOBTPP | Ukraine-DobTPP CTA |
IT_NORD_CH | IT-North-CH BZ | UA_BEI | Ukraine BEI CTA |
IT_NORD_FR | IT-North-FR BZ | UA_IPS | Ukraine IPS CTA |
Additional documentation on the API can be found here.
I hope you find this article insightful. Consider leaving a comment to let me know your thoughts on the topic.
More insights within energy are to follow in the next article.
Michael
Thank you very much. Very useful!
Great article. Thanks a lot! Will try to follow the instructions and hopefully it’ll work.