# 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:
- [`EntsoeRawClient`](#EntsoeRawClient): Returns data in its raw format, usually XML or a ZIP-file containing XML's
- [`EntsoePandasClient`](#EntsoePandasClient): Returns data parsed as a Pandas Series or DataFrame
### <a name="EntsoeRawClient"></a>EntsoeRawClient
```python
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_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)
# methods that return ZIP (bytes)
client.query_imbalance_prices(country_code, start, 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
```python
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
```python
params = {
'documentType': 'A44',
'in_Domain': '10YBE----------2',
'out_Domain': '10YBE----------2'
}
response = client._base_request(params=params, start=start, end=end)
print(response.text)
```
### <a name="EntsoePandasClient"></a>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
```python
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_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_imbalance_prices(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_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
```python
ts = client.query_day_ahead_prices(country_code, start=start, end=end)
ts.to_csv('outfile.csv')
```
### Mappings
These lists are always evolving, so let us know if something's inaccurate!
All mappings can be found in ```mappings.py``` [here](https://github.com/EnergieID/entsoe-py/blob/master/entsoe/mappings.py)
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 |
Raw data
{
"_id": null,
"home_page": "https://github.com/EnergieID/entsoe-py",
"name": "entsoe-py",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "ENTSO-E data api energy",
"author": "EnergieID.be, Frank Boerman",
"author_email": "jan@energieid.be, frank@fboerman.nl",
"download_url": "https://files.pythonhosted.org/packages/9c/01/8800876f300d0e595ee75734179604158df86728497dafa02a4c6d87dd53/entsoe_py-0.6.16.tar.gz",
"platform": null,
"description": "# entsoe-py\nPython client for the ENTSO-E API (european network of transmission system operators for electricity)\n\nDocumentation of the API found on https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html\n\n## Installation\n`python3 -m pip install entsoe-py`\n\n## Usage\nThe package comes with 2 clients:\n- [`EntsoeRawClient`](#EntsoeRawClient): Returns data in its raw format, usually XML or a ZIP-file containing XML's\n- [`EntsoePandasClient`](#EntsoePandasClient): Returns data parsed as a Pandas Series or DataFrame\n### <a name=\"EntsoeRawClient\"></a>EntsoeRawClient\n```python\nfrom entsoe import EntsoeRawClient\nimport pandas as pd\n\nclient = EntsoeRawClient(api_key=<YOUR API KEY>)\n\nstart = pd.Timestamp('20171201', tz='Europe/Brussels')\nend = pd.Timestamp('20180101', tz='Europe/Brussels')\ncountry_code = 'BE' # Belgium\ncountry_code_from = 'FR' # France\ncountry_code_to = 'DE_LU' # Germany-Luxembourg\ntype_marketagreement_type = 'A01'\ncontract_marketagreement_type = 'A01'\nprocess_type = 'A51'\n\n# methods that return XML\nclient.query_day_ahead_prices(country_code, start, end)\nclient.query_net_position(country_code, start, end, dayahead=True)\nclient.query_load(country_code, start, end)\nclient.query_load_forecast(country_code, start, end)\nclient.query_wind_and_solar_forecast(country_code, start, end, psr_type=None)\nclient.query_intraday_wind_and_solar_forecast(country_code, start, end, psr_type=None)\nclient.query_generation_forecast(country_code, start, end)\nclient.query_generation(country_code, start, end, psr_type=None)\nclient.query_generation_per_plant(country_code, start, end, psr_type=None)\nclient.query_installed_generation_capacity(country_code, start, end, psr_type=None)\nclient.query_installed_generation_capacity_per_unit(country_code, start, end, psr_type=None)\nclient.query_crossborder_flows(country_code_from, country_code_to, start, end)\nclient.query_scheduled_exchanges(country_code_from, country_code_to, start, end, dayahead=False)\nclient.query_net_transfer_capacity_dayahead(country_code_from, country_code_to, start, end)\nclient.query_net_transfer_capacity_weekahead(country_code_from, country_code_to, start, end)\nclient.query_net_transfer_capacity_monthahead(country_code_from, country_code_to, start, end)\nclient.query_net_transfer_capacity_yearahead(country_code_from, country_code_to, start, end)\nclient.query_intraday_offered_capacity(country_code_from, country_code_to, start, end, implicit=True)\nclient.query_offered_capacity(country_code_from, country_code_to, start, end, contract_marketagreement_type, implicit=True)\nclient.query_contracted_reserve_prices(country_code, start, end, type_marketagreement_type, psr_type=None)\nclient.query_contracted_reserve_prices_procured_capacity(country_code, start, end, process_type type_marketagreement_type, psr_type=None)\nclient.query_contracted_reserve_amount(country_code, start, end, type_marketagreement_type, psr_type=None)\nclient.query_procured_balancing_capacity(country_code, start, end, process_type, type_marketagreement_type=None)\nclient.query_aggregate_water_reservoirs_and_hydro_storage(country_code, start, end)\n\n# methods that return ZIP (bytes)\nclient.query_imbalance_prices(country_code, start, end, psr_type=None)\nclient.query_unavailability_of_generation_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)\nclient.query_unavailability_of_production_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)\nclient.query_unavailability_transmission(country_code_from, country_code_to, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)\nclient.query_unavailability_of_offshore_grid(area_code, start, end)\nclient.query_withdrawn_unavailability_of_generation_units(country_code, start, end)\n```\n#### Dump result to file\n```python\nxml_string = client.query_day_ahead_prices(country_code, start, end)\nwith open('outfile.xml', 'w') as f:\n f.write(xml_string)\n\nzip_bytes = client.query_unavailability_of_generation_units(country_code, start, end)\nwith open('outfile.zip', 'wb') as f:\n f.write(zip_bytes)\n```\n#### Making another request\nIs the API-call you want not in the list, you can lookup the parameters yourself in the API documentation\n```python\nparams = {\n 'documentType': 'A44',\n 'in_Domain': '10YBE----------2',\n 'out_Domain': '10YBE----------2'\n}\nresponse = client._base_request(params=params, start=start, end=end)\nprint(response.text)\n```\n\n### <a name=\"EntsoePandasClient\"></a>EntsoePandasClient\nThe Pandas Client works similar to the Raw Client, with extras:\n- Time periods that span more than 1 year are automatically dealt with\n- Requests of large numbers of files are split over multiple API calls\n\nPlease note that this client requires you to specifically set a start= and end= parameter which should be a pandas timestamp with timezone.\nIf not it will throw an exception\n```python\nfrom entsoe import EntsoePandasClient\nimport pandas as pd\n\nclient = EntsoePandasClient(api_key=<YOUR API KEY>)\n\nstart = pd.Timestamp('20171201', tz='Europe/Brussels')\nend = pd.Timestamp('20180101', tz='Europe/Brussels')\ncountry_code = 'BE' # Belgium\ncountry_code_from = 'FR' # France\ncountry_code_to = 'DE_LU' # Germany-Luxembourg\ntype_marketagreement_type = 'A01'\ncontract_marketagreement_type = \"A01\"\nprocess_type = 'A51'\n\n# methods that return Pandas Series\nclient.query_day_ahead_prices(country_code, start=start, end=end)\nclient.query_net_position(country_code, start=start, end=end, dayahead=True)\nclient.query_crossborder_flows(country_code_from, country_code_to, start=start, end=end)\nclient.query_scheduled_exchanges(country_code_from, country_code_to, start=start, end=end, dayahead=False)\nclient.query_net_transfer_capacity_dayahead(country_code_from, country_code_to, start=start, end=end)\nclient.query_net_transfer_capacity_weekahead(country_code_from, country_code_to, start=start, end=end)\nclient.query_net_transfer_capacity_monthahead(country_code_from, country_code_to, start=start, end=end)\nclient.query_net_transfer_capacity_yearahead(country_code_from, country_code_to, start=start, end=end)\nclient.query_intraday_offered_capacity(country_code_from, country_code_to, start=start, end=end, implicit=True)\nclient.query_offered_capacity(country_code_from, country_code_to, contract_marketagreement_type, start=start, end=end, implicit=True)\nclient.query_aggregate_water_reservoirs_and_hydro_storage(country_code, start=start, end=end)\n\n# methods that return Pandas DataFrames\nclient.query_load(country_code, start=start, end=end)\nclient.query_load_forecast(country_code, start=start, end=end)\nclient.query_load_and_forecast(country_code, start=start, end=end)\nclient.query_generation_forecast(country_code, start=start, end=end)\nclient.query_wind_and_solar_forecast(country_code, start=start, end=end, psr_type=None)\nclient.query_intraday_wind_and_solar_forecast(country_code, start=start, end=end, psr_type=None)\nclient.query_generation(country_code, start=start, end=end, psr_type=None)\nclient.query_generation_per_plant(country_code, start=start, end=end, psr_type=None, include_eic=False)\nclient.query_installed_generation_capacity(country_code, start=start, end=end, psr_type=None)\nclient.query_installed_generation_capacity_per_unit(country_code, start=start, end=end, psr_type=None)\nclient.query_imbalance_prices(country_code, start=start, end=end, psr_type=None)\nclient.query_contracted_reserve_prices(country_code, type_marketagreement_type, start=start, end=end, psr_type=None)\nclient.query_contracted_reserve_amount(country_code, type_marketagreement_type, start=start, end=end, psr_type=None)\nclient.query_unavailability_of_generation_units(country_code, start=start, end=end, docstatus=None, periodstartupdate=None, periodendupdate=None)\nclient.query_unavailability_of_production_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None)\nclient.query_unavailability_transmission(country_code_from, country_code_to, start=start, end=end, docstatus=None, periodstartupdate=None, periodendupdate=None)\nclient.query_withdrawn_unavailability_of_generation_units(country_code, start, end)\nclient.query_unavailability_of_offshore_grid(area_code, start, end)\nclient.query_physical_crossborder_allborders(country_code, start, end, export=True)\nclient.query_generation_import(country_code, start, end)\nclient.query_procured_balancing_capacity(country_code, process_type, start=start, end=end, type_marketagreement_type=None)\n\n```\n#### Dump result to file\nSee a list of all IO-methods on https://pandas.pydata.org/pandas-docs/stable/io.html\n```python\nts = client.query_day_ahead_prices(country_code, start=start, end=end)\nts.to_csv('outfile.csv')\n```\n\n### Mappings\nThese lists are always evolving, so let us know if something's inaccurate!\n\nAll mappings can be found in ```mappings.py``` [here](https://github.com/EnergieID/entsoe-py/blob/master/entsoe/mappings.py)\n\nFor bidding zone that have changed (splitted/merged) some codes are only valid for certain times. The below table shows these cases.\n\n| | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 |\n| -- | -- | -- | -- | -- | -- | -- | -- |\n| DE_AT_LU | yes | yes | yes | yes | No Value | No Value | No Value |\n| DE | No Value | No Value | No Value | No Value | No Value | No Value | No Value |\n| DE_LU | No Value | No Value | No Value | yes | yes | yes | yes |\n| AT | No Value | No Value | No Value | yes | yes | yes | yes |\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A python API wrapper for ENTSO-E",
"version": "0.6.16",
"project_urls": {
"Homepage": "https://github.com/EnergieID/entsoe-py"
},
"split_keywords": [
"entso-e",
"data",
"api",
"energy"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "2f8620ce63d94e634442348782d1d3595219ad4c1fa0ff7cf174f53454be5962",
"md5": "b5b739860d3bfa885640c4f8d9928188",
"sha256": "748ed1510a81817ba576774f5cea69529194674f222ef96c93d8b62cd745d554"
},
"downloads": -1,
"filename": "entsoe_py-0.6.16-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b5b739860d3bfa885640c4f8d9928188",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 1614616,
"upload_time": "2024-11-06T12:47:54",
"upload_time_iso_8601": "2024-11-06T12:47:54.711311Z",
"url": "https://files.pythonhosted.org/packages/2f/86/20ce63d94e634442348782d1d3595219ad4c1fa0ff7cf174f53454be5962/entsoe_py-0.6.16-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "9c018800876f300d0e595ee75734179604158df86728497dafa02a4c6d87dd53",
"md5": "d32f8c45dd4ee8a2742b6b6e140e3de6",
"sha256": "67fb865d5af94b0b841f75ed30accde9ed82923a6b0160ce9c604ae50abb4c0d"
},
"downloads": -1,
"filename": "entsoe_py-0.6.16.tar.gz",
"has_sig": false,
"md5_digest": "d32f8c45dd4ee8a2742b6b6e140e3de6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 1592052,
"upload_time": "2024-11-06T12:47:57",
"upload_time_iso_8601": "2024-11-06T12:47:57.412744Z",
"url": "https://files.pythonhosted.org/packages/9c/01/8800876f300d0e595ee75734179604158df86728497dafa02a4c6d87dd53/entsoe_py-0.6.16.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-06 12:47:57",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "EnergieID",
"github_project": "entsoe-py",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "requests",
"specs": []
},
{
"name": "pytz",
"specs": []
},
{
"name": "beautifulsoup4",
"specs": [
[
">=",
"4.11.1"
]
]
},
{
"name": "pandas",
"specs": [
[
">=",
"2.2.0"
]
]
}
],
"lcname": "entsoe-py"
}