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:

  1. Download and install the Python client for the ENTSO-E platform first. Link to the Github repository.
  2. Register on the ENTSO-E transparency platform (click login at the top right of the page): https://transparency.entsoe.eu/dashboard/show
  3. 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 of electric generation per power plant for Austria
Query of the generation per power plant (in MW) in Austria for December 01, 2020

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.

Small call to action download the code

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.

CodeCountry/Control AreaCodeCountry/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
Country codes and respective country/control area for the queries

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

Call to action download the code
Share this post:

Similar Posts

6 Comments

Leave a Reply