entsoe-py

A Python client for the ENTSO-E API (European Network of Transmission System Operators for Electricity).
https://github.com/EnergieID/entsoe-py

Category: Energy Systems
Sub Category: Energy Data Accessibility and Integration

Keywords from Contributors

power energy-system-modelling energy-systems

Last synced: about 8 hours ago
JSON representation

Repository metadata

Python client for the ENTSO-E API (european network of transmission system operators for electricity)

README.md

entsoe-py

Python client for the ENTSO-E API (european network of transmission system operators for electricity)

Documentation of the API found on https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html

Installation

python3 -m pip install entsoe-py

Usage

The package comes with 2 clients for the REST API:

  • EntsoeRawClient: Returns data in its raw format, usually XML or a ZIP-file containing XML's
  • EntsoePandasClient: Returns data parsed as a Pandas Series or DataFrame

EntsoeRawClient

from entsoe import EntsoeRawClient
import pandas as pd

client = EntsoeRawClient(api_key=<YOUR API KEY>)

start = pd.Timestamp('20171201', tz='Europe/Brussels')
end = pd.Timestamp('20180101', tz='Europe/Brussels')
country_code = 'BE'  # Belgium
country_code_from = 'FR'  # France
country_code_to = 'DE_LU' # Germany-Luxembourg
type_marketagreement_type = 'A01'
contract_marketagreement_type = 'A01'
process_type = 'A51'

# methods that return XML
client.query_day_ahead_prices(country_code, start, end)
client.query_aggregated_bids(country_code, start, end, process_type)
client.query_net_position(country_code, start, end, dayahead=True)
client.query_load(country_code, start, end)
client.query_load_forecast(country_code, start, end)
client.query_wind_and_solar_forecast(country_code, start, end, psr_type=None)
client.query_intraday_wind_and_solar_forecast(country_code, start, end, psr_type=None)
client.query_generation_forecast(country_code, start, end)
client.query_generation(country_code, start, end, psr_type=None)
client.query_generation_per_plant(country_code, start, end, psr_type=None)
client.query_installed_generation_capacity(country_code, start, end, psr_type=None)
client.query_installed_generation_capacity_per_unit(country_code, start, end, psr_type=None)
client.query_crossborder_flows(country_code_from, country_code_to, start, end)
client.query_scheduled_exchanges(country_code_from, country_code_to, start, end, dayahead=False)
client.query_net_transfer_capacity_dayahead(country_code_from, country_code_to, start, end)
client.query_net_transfer_capacity_weekahead(country_code_from, country_code_to, start, end)
client.query_net_transfer_capacity_monthahead(country_code_from, country_code_to, start, end)
client.query_net_transfer_capacity_yearahead(country_code_from, country_code_to, start, end)
client.query_intraday_offered_capacity(country_code_from, country_code_to, start, end, implicit=True)
client.query_offered_capacity(country_code_from, country_code_to, start, end, contract_marketagreement_type, implicit=True)
client.query_contracted_reserve_prices(country_code, start, end, type_marketagreement_type, psr_type=None)
client.query_contracted_reserve_prices_procured_capacity(country_code, start, end, process_type type_marketagreement_type, psr_type=None)
client.query_contracted_reserve_amount(country_code, start, end, type_marketagreement_type, psr_type=None)
client.query_procured_balancing_capacity(country_code, start, end, process_type, type_marketagreement_type=None)
client.query_aggregate_water_reservoirs_and_hydro_storage(country_code, start, end)
client.query_activated_balancing_energy_prices(country_code, start, end, process_type='A16', psr_type=None, business_type=None, standard_market_product=None, original_market_product=None)
client.query_activated_balancing_energy(country_code, start, end, business_type, psr_type=None)

# methods that return ZIP (bytes)
client.query_imbalance_prices(country_code, start, end, psr_type=None)
client.query_imbalance_volumes(country_code, start=start, end=end, psr_type=None)
client.query_unavailability_of_generation_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)
client.query_unavailability_of_production_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)
client.query_unavailability_transmission(country_code_from, country_code_to, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)
client.query_unavailability_of_offshore_grid(area_code, start, end)
client.query_withdrawn_unavailability_of_generation_units(country_code, start, end)

Dump result to file

xml_string = client.query_day_ahead_prices(country_code, start, end)
with open('outfile.xml', 'w') as f:
    f.write(xml_string)

zip_bytes = client.query_unavailability_of_generation_units(country_code, start, end)
with open('outfile.zip', 'wb') as f:
    f.write(zip_bytes)

Making another request

Is the API-call you want not in the list, you can lookup the parameters yourself in the API documentation

params = {
    'documentType': 'A44',
    'in_Domain': '10YBE----------2',
    'out_Domain': '10YBE----------2'
}
response = client._base_request(params=params, start=start, end=end)
print(response.text)

EntsoePandasClient

The Pandas Client works similar to the Raw Client, with extras:

  • Time periods that span more than 1 year are automatically dealt with
  • Requests of large numbers of files are split over multiple API calls

Please note that this client requires you to specifically set a start= and end= parameter which should be a pandas timestamp with timezone.
If not it will throw an exception

from entsoe import EntsoePandasClient
import pandas as pd

client = EntsoePandasClient(api_key=<YOUR API KEY>)

start = pd.Timestamp('20171201', tz='Europe/Brussels')
end = pd.Timestamp('20180101', tz='Europe/Brussels')
country_code = 'BE'  # Belgium
country_code_from = 'FR'  # France
country_code_to = 'DE_LU' # Germany-Luxembourg
type_marketagreement_type = 'A01'
contract_marketagreement_type = "A01"
process_type = 'A51'

# methods that return Pandas Series
client.query_day_ahead_prices(country_code, start=start, end=end)
client.query_aggregated_bids(country_code, start=start, end=end, process_type)
client.query_net_position(country_code, start=start, end=end, dayahead=True)
client.query_crossborder_flows(country_code_from, country_code_to, start=start, end=end)
client.query_scheduled_exchanges(country_code_from, country_code_to, start=start, end=end, dayahead=False)
client.query_net_transfer_capacity_dayahead(country_code_from, country_code_to, start=start, end=end)
client.query_net_transfer_capacity_weekahead(country_code_from, country_code_to, start=start, end=end)
client.query_net_transfer_capacity_monthahead(country_code_from, country_code_to, start=start, end=end)
client.query_net_transfer_capacity_yearahead(country_code_from, country_code_to, start=start, end=end)
client.query_intraday_offered_capacity(country_code_from, country_code_to, start=start, end=end, implicit=True)
client.query_offered_capacity(country_code_from, country_code_to, contract_marketagreement_type, start=start, end=end, implicit=True)
client.query_aggregate_water_reservoirs_and_hydro_storage(country_code, start=start, end=end)

# methods that return Pandas DataFrames
client.query_load(country_code, start=start, end=end)
client.query_load_forecast(country_code, start=start, end=end)
client.query_load_and_forecast(country_code, start=start, end=end)
client.query_generation_forecast(country_code, start=start, end=end)
client.query_wind_and_solar_forecast(country_code, start=start, end=end, psr_type=None)
client.query_intraday_wind_and_solar_forecast(country_code, start=start, end=end, psr_type=None)
client.query_generation(country_code, start=start, end=end, psr_type=None)
client.query_generation_per_plant(country_code, start=start, end=end, psr_type=None, include_eic=False)
client.query_installed_generation_capacity(country_code, start=start, end=end, psr_type=None)
client.query_installed_generation_capacity_per_unit(country_code, start=start, end=end, psr_type=None)
client.query_activated_balancing_energy_prices(country_code, start=start, end=end, process_type='A16', psr_type=None, business_type=None, standard_market_product=None, original_market_product=None)
client.query_activated_balancing_energy(country_code, start=start, end=end, business_type, psr_type=None)
client.query_imbalance_prices(country_code, start=start, end=end, psr_type=None)
client.query_imbalance_volumes(country_code, start=start, end=end, psr_type=None)
client.query_contracted_reserve_prices(country_code, type_marketagreement_type, start=start, end=end, psr_type=None)
client.query_contracted_reserve_amount(country_code, type_marketagreement_type, start=start, end=end, psr_type=None)
client.query_unavailability_of_generation_units(country_code, start=start, end=end, docstatus=None, periodstartupdate=None, periodendupdate=None)
client.query_unavailability_of_production_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)
client.query_unavailability_transmission(country_code_from, country_code_to, start=start, end=end, docstatus=None, periodstartupdate=None, periodendupdate=None)
client.query_withdrawn_unavailability_of_generation_units(country_code, start, end)
client.query_unavailability_of_offshore_grid(area_code, start, end)
client.query_physical_crossborder_allborders(country_code, start, end, export=True)
client.query_import(country_code, start, end)
client.query_generation_import(country_code, start, end)
client.query_procured_balancing_capacity(country_code, process_type, start=start, end=end, type_marketagreement_type=None)

Dump result to file

See a list of all IO-methods on https://pandas.pydata.org/pandas-docs/stable/io.html

ts = client.query_day_ahead_prices(country_code, start=start, end=end)
ts.to_csv('outfile.csv')

Download from ENTSOE File Library

To download from the file libary, which replaced the old SFTP use the files subpackage with the EntsoeFileClient

from entsoe.files import EntsoeFileClient

client = EntsoeFileClient(username=<YOUR ENTSOE USERNAME>, pwd=<YOUR ENTSOE PASSWORD>)
# this returns a dict of {filename: unique_id}:
file_list = client.list_folder('AcceptedAggregatedOffers_17.1.D')

# either download one file by name:
df = client.download_single_file(folder='AcceptedAggregatedOffers_17.1.D', filename=list(file_list.keys())[0])

# or download multiple by unique_id:
df = client.download_multiple_files(['a1a82b3f-c453-4181-8d20-ad39c948d4b0', '64e47e15-bac6-4212-b2dd-9667bdf33b5d'])

Mappings

These lists are always evolving, so let us know if something's inaccurate!

All mappings can be found in mappings.py here

For bidding zone that have changed (splitted/merged) some codes are only valid for certain times. The below table shows these cases.

2015 2016 2017 2018 2019 2020 2021
DE_AT_LU yes yes yes yes No Value No Value No Value
DE No Value No Value No Value No Value No Value No Value No Value
DE_LU No Value No Value No Value yes yes yes yes
AT No Value No Value No Value yes yes yes yes

Environment variables

Variables Description
ENTSOE_ENDPOINT_URL Override the default ENTSO-E API endpoint URL.

Citation (CITATION.cff)

cff-version: 1.2.0
title: entsoe-py
message: >-
  "If you use this software, please cite it as
  below."
type: software
authors:
  - given-names: Jan
    family-names: Pecinovsky
    email: janpecinovsky@gmail.com
    affiliation: EnergieID
  - given-names: Frank
    family-names: Boerman
    email: frank@fboerman.nl

Owner metadata


GitHub Events

Total
Last Year

Committers metadata

Last synced: 3 days ago

Total Commits: 362
Total Committers: 75
Avg Commits per committer: 4.827
Development Distribution Score (DDS): 0.707

Commits in past year: 56
Committers in past year: 17
Avg Commits per committer in past year: 3.294
Development Distribution Score (DDS) in past year: 0.429

Name Email Commits
Frank Boerman f****k@f****l 106
Jan Pecinovsky j****y@g****m 92
Johan Paduart j****t@g****m 16
Gopakumar Mohandas g****r@P****U 9
Alexander Warsewa 3****a 8
Piotr Pocheć p****c@i****l 6
Li Chuang 1****t 5
shatteringlass f****o@g****m 5
Philipp Reuber p****r@f****e 5
Jean-Michel Reghem 2****h 5
Frank Boerman f****n@t****u 5
enrico.tesio e****o@d****m 5
maurerle f****r@o****e 4
mattsilb-epyr m****n@e****o 4
Lars Tellemann Sæther l****r@a****o 4
shuvo-cefalo m****s@c****m 3
jm-sm 4****m 3
jdtrebbien j****n@g****m 3
Vartan Ahrens Kayayan 3****n 3
drieshugaerts d****s@s****e 3
Fabio Genoese f****e@g****m 3
Francesc Ortiz f****z@f****m 2
Hans Böhm b****n 2
Jarrad Whitaker 1****g 2
Jiro Matsuzawa j****a@n****m 2
Lukas Pirl g****t@l****e 2
Paul p****o@n****m 2
leostimpfle l****e@i****m 2
waldemarmeier w****r@y****e 2
Lemuel Lee l****e@l****k 2
and 45 more...

Committer domains:


Issue and Pull Request metadata

Last synced: 4 days ago

Total issues: 313
Total pull requests: 161
Average time to close issues: 3 months
Average time to close pull requests: about 2 months
Total issue authors: 239
Total pull request authors: 92
Average comments per issue: 2.78
Average comments per pull request: 1.49
Merged pull request: 105
Bot issues: 0
Bot pull requests: 0

Past year issues: 67
Past year pull requests: 39
Past year average time to close issues: 19 days
Past year average time to close pull requests: 19 days
Past year issue authors: 56
Past year pull request authors: 23
Past year average comments per issue: 1.87
Past year average comments per pull request: 0.56
Past year merged pull request: 14
Past year bot issues: 0
Past year bot pull requests: 0

More stats: https://issues.ecosyste.ms/repositories/lookup?url=https://github.com/EnergieID/entsoe-py

Top Issue Authors

  • fleimgruber (5)
  • ThomasAuriel (5)
  • JrtPec (5)
  • AbiAfthab (5)
  • rablancomo (4)
  • FabianHofmann (3)
  • ThomasPade (3)
  • nhlong2701 (3)
  • huertamir (3)
  • Gilles-H (3)
  • jdtrebbien (3)
  • AlejandroElBecario (3)
  • jimich (3)
  • fgenoese (3)
  • mkaut (3)

Top Pull Request Authors

  • jpaduart (9)
  • pee-po (5)
  • maurerle (5)
  • jdtrebbien (4)
  • JrtPec (4)
  • gmohandas (4)
  • awarsewa (4)
  • fgenoese (4)
  • p-reuber (3)
  • mattsilb-epyr (3)
  • lpirl (3)
  • Pirez (2)
  • tomfelder94 (2)
  • LemuelKL (2)
  • jensrix (2)

Top Issue Labels

  • more info needed (18)
  • bug (11)
  • help wanted (9)
  • enhancement (6)
  • question (5)
  • server bug (4)
  • wontfix (1)

Top Pull Request Labels


Package metadata

pypi.org: entsoe-py

A python API wrapper for ENTSO-E

  • Homepage: https://github.com/EnergieID/entsoe-py
  • Documentation: https://entsoe-py.readthedocs.io/
  • Licenses: MIT
  • Latest release: 0.7.8 (published 11 days ago)
  • Last Synced: 2025-10-30T01:06:12.957Z (3 days ago)
  • Versions: 87
  • Dependent Packages: 8
  • Dependent Repositories: 26
  • Downloads: 296,095 Last month
  • Rankings:
    • Dependent packages count: 1.07%
    • Downloads: 1.608%
    • Average: 2.619%
    • Dependent repos count: 2.865%
    • Stargazers count: 3.534%
    • Forks count: 4.017%
  • Maintainers (2)
conda-forge.org: entsoe-py

  • Homepage: https://github.com/EnergieID/entsoe-py
  • Licenses: MIT
  • Latest release: 0.5.8 (published about 3 years ago)
  • Last Synced: 2025-10-01T07:58:28.626Z (about 1 month ago)
  • Versions: 9
  • Dependent Packages: 1
  • Dependent Repositories: 2
  • Rankings:
    • Forks count: 15.673%
    • Dependent repos count: 20.06%
    • Average: 21.988%
    • Stargazers count: 23.264%
    • Dependent packages count: 28.954%

Dependencies

.github/workflows/publish-to-test-pypi.yml actions
  • actions/checkout master composite
  • actions/setup-python v1 composite
  • pypa/gh-action-pypi-publish master composite
  • svenstaro/upload-release-action 2.2.1 composite
entsoe/geo/requirements.txt pypi
  • geojson-rewind *
  • geopandas *
  • plotly *
requirements.txt pypi
  • beautifulsoup4 *
  • pandas >=1.4.0
  • pytz *
  • requests *
setup.py pypi
  • beautifulsoup4 *
  • pandas >=1.4.0
  • pytz *
  • requests *

Score: 23.358595613574455