balancing-services 2.0.2__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. {balancing_services-2.0.2 → balancing_services-2.1.0}/PKG-INFO +1 -1
  2. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_capacity_bids.py +24 -8
  3. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_energy_bids.py +24 -8
  4. balancing_services-2.1.0/balancing_services/api/default/get_imbalance_price_forecasts.py +307 -0
  5. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/__init__.py +8 -0
  6. balancing_services-2.1.0/balancing_services/models/imbalance_price_forecast.py +111 -0
  7. balancing_services-2.1.0/balancing_services/models/imbalance_price_forecast_quantile.py +70 -0
  8. balancing_services-2.1.0/balancing_services/models/imbalance_price_forecasts.py +112 -0
  9. balancing_services-2.1.0/balancing_services/models/imbalance_price_forecasts_response.py +128 -0
  10. {balancing_services-2.0.2 → balancing_services-2.1.0}/pyproject.toml +1 -1
  11. {balancing_services-2.0.2 → balancing_services-2.1.0}/tests/test_basic.py +29 -0
  12. {balancing_services-2.0.2 → balancing_services-2.1.0}/tests/test_integration.py +200 -0
  13. {balancing_services-2.0.2 → balancing_services-2.1.0}/.env.sample +0 -0
  14. {balancing_services-2.0.2 → balancing_services-2.1.0}/.gitignore +0 -0
  15. {balancing_services-2.0.2 → balancing_services-2.1.0}/LICENSE +0 -0
  16. {balancing_services-2.0.2 → balancing_services-2.1.0}/PUBLISHING.md +0 -0
  17. {balancing_services-2.0.2 → balancing_services-2.1.0}/README.md +0 -0
  18. {balancing_services-2.0.2 → balancing_services-2.1.0}/RELEASE_CHECKLIST.md +0 -0
  19. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/__init__.py +0 -0
  20. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/__init__.py +0 -0
  21. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/__init__.py +0 -0
  22. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_capacity_demand.py +0 -0
  23. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_capacity_prices.py +0 -0
  24. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_capacity_procured_volumes.py +0 -0
  25. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_energy_activated_volumes.py +0 -0
  26. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_energy_demand.py +0 -0
  27. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_energy_offered_volumes.py +0 -0
  28. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_energy_prices.py +0 -0
  29. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_balancing_energy_satisfied_demand.py +0 -0
  30. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_cross_border_available_capacity.py +0 -0
  31. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_cross_border_energy_volumes.py +0 -0
  32. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_cross_border_marginal_prices.py +0 -0
  33. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_cross_zonal_capacity_allocation.py +0 -0
  34. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_current_imbalance_total_volumes.py +0 -0
  35. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_day_ahead_energy_prices.py +0 -0
  36. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_imbalance_prices.py +0 -0
  37. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/api/default/get_imbalance_total_volumes.py +0 -0
  38. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/client.py +0 -0
  39. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/errors.py +0 -0
  40. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/activation_type.py +0 -0
  41. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/area.py +0 -0
  42. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_bid_period.py +0 -0
  43. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_bids.py +0 -0
  44. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_bids_response.py +0 -0
  45. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_demand.py +0 -0
  46. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_demands.py +0 -0
  47. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_demands_response.py +0 -0
  48. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_price.py +0 -0
  49. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_prices.py +0 -0
  50. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_prices_response.py +0 -0
  51. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_volume.py +0 -0
  52. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_volumes.py +0 -0
  53. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_capacity_volumes_response.py +0 -0
  54. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_bid_period.py +0 -0
  55. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_bids.py +0 -0
  56. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_bids_response.py +0 -0
  57. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_price.py +0 -0
  58. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_prices.py +0 -0
  59. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_prices_response.py +0 -0
  60. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_volume.py +0 -0
  61. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_volumes.py +0 -0
  62. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/balancing_energy_volumes_response.py +0 -0
  63. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/bid_status.py +0 -0
  64. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/capacity_bid.py +0 -0
  65. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_available_capacity.py +0 -0
  66. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_available_capacity_response.py +0 -0
  67. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_available_capacity_value.py +0 -0
  68. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_energy_volumes.py +0 -0
  69. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_energy_volumes_response.py +0 -0
  70. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_marginal_price.py +0 -0
  71. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_marginal_prices.py +0 -0
  72. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_border_marginal_prices_response.py +0 -0
  73. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_zonal_capacity_allocation_response.py +0 -0
  74. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/cross_zonal_volumes.py +0 -0
  75. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/currency.py +0 -0
  76. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/day_ahead_energy_price.py +0 -0
  77. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/day_ahead_energy_prices.py +0 -0
  78. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/day_ahead_energy_prices_response.py +0 -0
  79. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/demand_basis.py +0 -0
  80. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/direction.py +0 -0
  81. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/eic_code.py +0 -0
  82. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/energy_bid.py +0 -0
  83. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/imbalance_direction.py +0 -0
  84. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/imbalance_price.py +0 -0
  85. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/imbalance_prices.py +0 -0
  86. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/imbalance_prices_response.py +0 -0
  87. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/imbalance_total_volumes.py +0 -0
  88. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/imbalance_total_volumes_response.py +0 -0
  89. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/period.py +0 -0
  90. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/problem.py +0 -0
  91. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/procurement.py +0 -0
  92. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/reserve_type.py +0 -0
  93. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/total_imbalance_direction.py +0 -0
  94. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/models/total_imbalance_volume.py +0 -0
  95. {balancing_services-2.0.2 → balancing_services-2.1.0}/balancing_services/types.py +0 -0
  96. {balancing_services-2.0.2 → balancing_services-2.1.0}/check.sh +0 -0
  97. {balancing_services-2.0.2 → balancing_services-2.1.0}/config.yaml +0 -0
  98. {balancing_services-2.0.2 → balancing_services-2.1.0}/examples/basic_usage.py +0 -0
  99. {balancing_services-2.0.2 → balancing_services-2.1.0}/examples/error_handling.py +0 -0
  100. {balancing_services-2.0.2 → balancing_services-2.1.0}/examples/pagination_example.py +0 -0
  101. {balancing_services-2.0.2 → balancing_services-2.1.0}/fix_enum_validator_casts.py +0 -0
  102. {balancing_services-2.0.2 → balancing_services-2.1.0}/generate-pyproject.sh +0 -0
  103. {balancing_services-2.0.2 → balancing_services-2.1.0}/generate.sh +0 -0
  104. {balancing_services-2.0.2 → balancing_services-2.1.0}/pyproject.toml.draft +0 -0
  105. {balancing_services-2.0.2 → balancing_services-2.1.0}/test-and-publish.sh +0 -0
  106. {balancing_services-2.0.2 → balancing_services-2.1.0}/tests/conftest.py +0 -0
  107. {balancing_services-2.0.2 → balancing_services-2.1.0}/tests/test_async.py +0 -0
  108. {balancing_services-2.0.2 → balancing_services-2.1.0}/tests/test_datetime_compat.py +0 -0
  109. {balancing_services-2.0.2 → balancing_services-2.1.0}/tests/test_procured_at_none_handling.py +0 -0
  110. {balancing_services-2.0.2 → balancing_services-2.1.0}/tests/test_readme_execution.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: balancing-services
3
- Version: 2.0.2
3
+ Version: 2.1.0
4
4
  Summary: Official Python client for accessing European electricity balancing market data via the Balancing Services REST API
5
5
  Project-URL: Homepage, https://balancing.services
6
6
  Project-URL: Documentation, https://api.balancing.services/v2/documentation
@@ -145,8 +145,12 @@ def sync_detailed(
145
145
  true the last period entry may continue on the next page, so merge entries on their group's
146
146
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
147
147
  guaranteed order — sort by price client-side if you need the merit order. When polling with
148
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
149
- necessarily contiguous.
148
+ `updated-since`, change is tracked per stored bid set rather than per bid — each procurement
149
+ round of a period is its own set: a changed set is re-delivered with its unchanged bids
150
+ included, so the period entries of a poll are not necessarily contiguous. A period entry may
151
+ span more than one set, and a set that changes again mid-drain is deferred to the next poll,
152
+ so a filtered response is not guaranteed to carry a period's complete bid set — re-fetch
153
+ without `updated-since` to reconcile withdrawals.
150
154
 
151
155
  Args:
152
156
  area (Area): Area code
@@ -209,8 +213,12 @@ def sync(
209
213
  true the last period entry may continue on the next page, so merge entries on their group's
210
214
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
211
215
  guaranteed order — sort by price client-side if you need the merit order. When polling with
212
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
213
- necessarily contiguous.
216
+ `updated-since`, change is tracked per stored bid set rather than per bid — each procurement
217
+ round of a period is its own set: a changed set is re-delivered with its unchanged bids
218
+ included, so the period entries of a poll are not necessarily contiguous. A period entry may
219
+ span more than one set, and a set that changes again mid-drain is deferred to the next poll,
220
+ so a filtered response is not guaranteed to carry a period's complete bid set — re-fetch
221
+ without `updated-since` to reconcile withdrawals.
214
222
 
215
223
  Args:
216
224
  area (Area): Area code
@@ -268,8 +276,12 @@ async def asyncio_detailed(
268
276
  true the last period entry may continue on the next page, so merge entries on their group's
269
277
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
270
278
  guaranteed order — sort by price client-side if you need the merit order. When polling with
271
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
272
- necessarily contiguous.
279
+ `updated-since`, change is tracked per stored bid set rather than per bid — each procurement
280
+ round of a period is its own set: a changed set is re-delivered with its unchanged bids
281
+ included, so the period entries of a poll are not necessarily contiguous. A period entry may
282
+ span more than one set, and a set that changes again mid-drain is deferred to the next poll,
283
+ so a filtered response is not guaranteed to carry a period's complete bid set — re-fetch
284
+ without `updated-since` to reconcile withdrawals.
273
285
 
274
286
  Args:
275
287
  area (Area): Area code
@@ -330,8 +342,12 @@ async def asyncio(
330
342
  true the last period entry may continue on the next page, so merge entries on their group's
331
343
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
332
344
  guaranteed order — sort by price client-side if you need the merit order. When polling with
333
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
334
- necessarily contiguous.
345
+ `updated-since`, change is tracked per stored bid set rather than per bid — each procurement
346
+ round of a period is its own set: a changed set is re-delivered with its unchanged bids
347
+ included, so the period entries of a poll are not necessarily contiguous. A period entry may
348
+ span more than one set, and a set that changes again mid-drain is deferred to the next poll,
349
+ so a filtered response is not guaranteed to carry a period's complete bid set — re-fetch
350
+ without `updated-since` to reconcile withdrawals.
335
351
 
336
352
  Args:
337
353
  area (Area): Area code
@@ -144,8 +144,12 @@ def sync_detailed(
144
144
  true the last period entry may continue on the next page, so merge entries on their group's
145
145
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
146
146
  guaranteed order — sort by price client-side if you need the merit order. When polling with
147
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
148
- necessarily contiguous.
147
+ `updated-since`, change is tracked per stored bid set rather than per bid: a changed set is
148
+ re-delivered with its unchanged bids included, so the period entries of a poll are not
149
+ necessarily contiguous. A period entry may span more than one tracked set, and a set that
150
+ changes again mid-drain is deferred to the next poll, so a filtered response is not guaranteed
151
+ to carry a period's complete bid set — re-fetch without `updated-since` to reconcile
152
+ withdrawals.
149
153
 
150
154
  Args:
151
155
  area (Area): Area code
@@ -207,8 +211,12 @@ def sync(
207
211
  true the last period entry may continue on the next page, so merge entries on their group's
208
212
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
209
213
  guaranteed order — sort by price client-side if you need the merit order. When polling with
210
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
211
- necessarily contiguous.
214
+ `updated-since`, change is tracked per stored bid set rather than per bid: a changed set is
215
+ re-delivered with its unchanged bids included, so the period entries of a poll are not
216
+ necessarily contiguous. A period entry may span more than one tracked set, and a set that
217
+ changes again mid-drain is deferred to the next poll, so a filtered response is not guaranteed
218
+ to carry a period's complete bid set — re-fetch without `updated-since` to reconcile
219
+ withdrawals.
212
220
 
213
221
  Args:
214
222
  area (Area): Area code
@@ -265,8 +273,12 @@ async def asyncio_detailed(
265
273
  true the last period entry may continue on the next page, so merge entries on their group's
266
274
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
267
275
  guaranteed order — sort by price client-side if you need the merit order. When polling with
268
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
269
- necessarily contiguous.
276
+ `updated-since`, change is tracked per stored bid set rather than per bid: a changed set is
277
+ re-delivered with its unchanged bids included, so the period entries of a poll are not
278
+ necessarily contiguous. A period entry may span more than one tracked set, and a set that
279
+ changes again mid-drain is deferred to the next poll, so a filtered response is not guaranteed
280
+ to carry a period's complete bid set — re-fetch without `updated-since` to reconcile
281
+ withdrawals.
270
282
 
271
283
  Args:
272
284
  area (Area): Area code
@@ -326,8 +338,12 @@ async def asyncio(
326
338
  true the last period entry may continue on the next page, so merge entries on their group's
327
339
  dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
328
340
  guaranteed order — sort by price client-side if you need the merit order. When polling with
329
- `updated-since`, a page holds only the bids that changed, so the period entries of a poll are not
330
- necessarily contiguous.
341
+ `updated-since`, change is tracked per stored bid set rather than per bid: a changed set is
342
+ re-delivered with its unchanged bids included, so the period entries of a poll are not
343
+ necessarily contiguous. A period entry may span more than one tracked set, and a set that
344
+ changes again mid-drain is deferred to the next poll, so a filtered response is not guaranteed
345
+ to carry a period's complete bid set — re-fetch without `updated-since` to reconcile
346
+ withdrawals.
331
347
 
332
348
  Args:
333
349
  area (Area): Area code
@@ -0,0 +1,307 @@
1
+ import datetime
2
+ from http import HTTPStatus
3
+ from typing import Any
4
+
5
+ import httpx
6
+
7
+ from ... import errors
8
+ from ...client import AuthenticatedClient, Client
9
+ from ...models.area import Area
10
+ from ...models.imbalance_price_forecasts_response import ImbalancePriceForecastsResponse
11
+ from ...models.problem import Problem
12
+ from ...types import UNSET, Response, Unset
13
+
14
+
15
+ def _get_kwargs(
16
+ *,
17
+ area: Area,
18
+ period_start_at: datetime.datetime,
19
+ period_end_at: datetime.datetime,
20
+ cursor: str | Unset = UNSET,
21
+ limit: int | Unset = 100,
22
+ updated_since: datetime.datetime | Unset = UNSET,
23
+ ) -> dict[str, Any]:
24
+
25
+ params: dict[str, Any] = {}
26
+
27
+ json_area: str = area
28
+ params["area"] = json_area
29
+
30
+ json_period_start_at = period_start_at.isoformat()
31
+ params["period-start-at"] = json_period_start_at
32
+
33
+ json_period_end_at = period_end_at.isoformat()
34
+ params["period-end-at"] = json_period_end_at
35
+
36
+ params["cursor"] = cursor
37
+
38
+ params["limit"] = limit
39
+
40
+ json_updated_since: str | Unset = UNSET
41
+ if not isinstance(updated_since, Unset):
42
+ json_updated_since = updated_since.isoformat()
43
+ params["updated-since"] = json_updated_since
44
+
45
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
46
+
47
+ _kwargs: dict[str, Any] = {
48
+ "method": "get",
49
+ "url": "/imbalance/prices/forecast",
50
+ "params": params,
51
+ }
52
+
53
+ return _kwargs
54
+
55
+
56
+ def _parse_response(
57
+ *, client: AuthenticatedClient | Client, response: httpx.Response
58
+ ) -> ImbalancePriceForecastsResponse | Problem | None:
59
+ if response.status_code == 200:
60
+ response_200 = ImbalancePriceForecastsResponse.from_dict(response.json())
61
+
62
+ return response_200
63
+
64
+ if response.status_code == 400:
65
+ response_400 = Problem.from_dict(response.json())
66
+
67
+ return response_400
68
+
69
+ if response.status_code == 401:
70
+ response_401 = Problem.from_dict(response.json())
71
+
72
+ return response_401
73
+
74
+ if response.status_code == 403:
75
+ response_403 = Problem.from_dict(response.json())
76
+
77
+ return response_403
78
+
79
+ if response.status_code == 404:
80
+ response_404 = Problem.from_dict(response.json())
81
+
82
+ return response_404
83
+
84
+ if response.status_code == 429:
85
+ response_429 = Problem.from_dict(response.json())
86
+
87
+ return response_429
88
+
89
+ if response.status_code == 500:
90
+ response_500 = Problem.from_dict(response.json())
91
+
92
+ return response_500
93
+
94
+ if response.status_code == 501:
95
+ response_501 = Problem.from_dict(response.json())
96
+
97
+ return response_501
98
+
99
+ if client.raise_on_unexpected_status:
100
+ raise errors.UnexpectedStatus(response.status_code, response.content)
101
+ else:
102
+ return None
103
+
104
+
105
+ def _build_response(
106
+ *, client: AuthenticatedClient | Client, response: httpx.Response
107
+ ) -> Response[ImbalancePriceForecastsResponse | Problem]:
108
+ return Response(
109
+ status_code=HTTPStatus(response.status_code),
110
+ content=response.content,
111
+ headers=response.headers,
112
+ parsed=_parse_response(client=client, response=response),
113
+ )
114
+
115
+
116
+ def sync_detailed(
117
+ *,
118
+ client: AuthenticatedClient | Client,
119
+ area: Area,
120
+ period_start_at: datetime.datetime,
121
+ period_end_at: datetime.datetime,
122
+ cursor: str | Unset = UNSET,
123
+ limit: int | Unset = 100,
124
+ updated_since: datetime.datetime | Unset = UNSET,
125
+ ) -> Response[ImbalancePriceForecastsResponse | Problem]:
126
+ """Get imbalance price forecasts for an area
127
+
128
+ **Experimental** - This endpoint is under active development and may change without notice.
129
+
130
+ Returns imbalance price forecasts for the specified area within the given time period. Each
131
+ forecast is a predictive distribution: level/price pairs in `quantiles`, ascending by level.
132
+ An area without forecast coverage returns an empty result rather than an error. Supports
133
+ cursor-based pagination for large result sets.
134
+
135
+ Args:
136
+ area (Area): Area code
137
+ period_start_at (datetime.datetime): Example: 2025-01-01T00:00:00Z.
138
+ period_end_at (datetime.datetime): Example: 2025-01-02T00:00:00Z.
139
+ cursor (str | Unset): Example: v1:AAAAAYwBAgMEBQYHCAkKCw==.
140
+ limit (int | Unset): Default: 100. Example: 100.
141
+ updated_since (datetime.datetime | Unset): Example: 2025-01-02T09:15:00Z.
142
+
143
+ Raises:
144
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
145
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
146
+
147
+ Returns:
148
+ Response[ImbalancePriceForecastsResponse | Problem]
149
+ """
150
+
151
+ kwargs = _get_kwargs(
152
+ area=area,
153
+ period_start_at=period_start_at,
154
+ period_end_at=period_end_at,
155
+ cursor=cursor,
156
+ limit=limit,
157
+ updated_since=updated_since,
158
+ )
159
+
160
+ response = client.get_httpx_client().request(
161
+ **kwargs,
162
+ )
163
+
164
+ return _build_response(client=client, response=response)
165
+
166
+
167
+ def sync(
168
+ *,
169
+ client: AuthenticatedClient | Client,
170
+ area: Area,
171
+ period_start_at: datetime.datetime,
172
+ period_end_at: datetime.datetime,
173
+ cursor: str | Unset = UNSET,
174
+ limit: int | Unset = 100,
175
+ updated_since: datetime.datetime | Unset = UNSET,
176
+ ) -> ImbalancePriceForecastsResponse | Problem | None:
177
+ """Get imbalance price forecasts for an area
178
+
179
+ **Experimental** - This endpoint is under active development and may change without notice.
180
+
181
+ Returns imbalance price forecasts for the specified area within the given time period. Each
182
+ forecast is a predictive distribution: level/price pairs in `quantiles`, ascending by level.
183
+ An area without forecast coverage returns an empty result rather than an error. Supports
184
+ cursor-based pagination for large result sets.
185
+
186
+ Args:
187
+ area (Area): Area code
188
+ period_start_at (datetime.datetime): Example: 2025-01-01T00:00:00Z.
189
+ period_end_at (datetime.datetime): Example: 2025-01-02T00:00:00Z.
190
+ cursor (str | Unset): Example: v1:AAAAAYwBAgMEBQYHCAkKCw==.
191
+ limit (int | Unset): Default: 100. Example: 100.
192
+ updated_since (datetime.datetime | Unset): Example: 2025-01-02T09:15:00Z.
193
+
194
+ Raises:
195
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
196
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
197
+
198
+ Returns:
199
+ ImbalancePriceForecastsResponse | Problem
200
+ """
201
+
202
+ return sync_detailed(
203
+ client=client,
204
+ area=area,
205
+ period_start_at=period_start_at,
206
+ period_end_at=period_end_at,
207
+ cursor=cursor,
208
+ limit=limit,
209
+ updated_since=updated_since,
210
+ ).parsed
211
+
212
+
213
+ async def asyncio_detailed(
214
+ *,
215
+ client: AuthenticatedClient | Client,
216
+ area: Area,
217
+ period_start_at: datetime.datetime,
218
+ period_end_at: datetime.datetime,
219
+ cursor: str | Unset = UNSET,
220
+ limit: int | Unset = 100,
221
+ updated_since: datetime.datetime | Unset = UNSET,
222
+ ) -> Response[ImbalancePriceForecastsResponse | Problem]:
223
+ """Get imbalance price forecasts for an area
224
+
225
+ **Experimental** - This endpoint is under active development and may change without notice.
226
+
227
+ Returns imbalance price forecasts for the specified area within the given time period. Each
228
+ forecast is a predictive distribution: level/price pairs in `quantiles`, ascending by level.
229
+ An area without forecast coverage returns an empty result rather than an error. Supports
230
+ cursor-based pagination for large result sets.
231
+
232
+ Args:
233
+ area (Area): Area code
234
+ period_start_at (datetime.datetime): Example: 2025-01-01T00:00:00Z.
235
+ period_end_at (datetime.datetime): Example: 2025-01-02T00:00:00Z.
236
+ cursor (str | Unset): Example: v1:AAAAAYwBAgMEBQYHCAkKCw==.
237
+ limit (int | Unset): Default: 100. Example: 100.
238
+ updated_since (datetime.datetime | Unset): Example: 2025-01-02T09:15:00Z.
239
+
240
+ Raises:
241
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
242
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
243
+
244
+ Returns:
245
+ Response[ImbalancePriceForecastsResponse | Problem]
246
+ """
247
+
248
+ kwargs = _get_kwargs(
249
+ area=area,
250
+ period_start_at=period_start_at,
251
+ period_end_at=period_end_at,
252
+ cursor=cursor,
253
+ limit=limit,
254
+ updated_since=updated_since,
255
+ )
256
+
257
+ response = await client.get_async_httpx_client().request(**kwargs)
258
+
259
+ return _build_response(client=client, response=response)
260
+
261
+
262
+ async def asyncio(
263
+ *,
264
+ client: AuthenticatedClient | Client,
265
+ area: Area,
266
+ period_start_at: datetime.datetime,
267
+ period_end_at: datetime.datetime,
268
+ cursor: str | Unset = UNSET,
269
+ limit: int | Unset = 100,
270
+ updated_since: datetime.datetime | Unset = UNSET,
271
+ ) -> ImbalancePriceForecastsResponse | Problem | None:
272
+ """Get imbalance price forecasts for an area
273
+
274
+ **Experimental** - This endpoint is under active development and may change without notice.
275
+
276
+ Returns imbalance price forecasts for the specified area within the given time period. Each
277
+ forecast is a predictive distribution: level/price pairs in `quantiles`, ascending by level.
278
+ An area without forecast coverage returns an empty result rather than an error. Supports
279
+ cursor-based pagination for large result sets.
280
+
281
+ Args:
282
+ area (Area): Area code
283
+ period_start_at (datetime.datetime): Example: 2025-01-01T00:00:00Z.
284
+ period_end_at (datetime.datetime): Example: 2025-01-02T00:00:00Z.
285
+ cursor (str | Unset): Example: v1:AAAAAYwBAgMEBQYHCAkKCw==.
286
+ limit (int | Unset): Default: 100. Example: 100.
287
+ updated_since (datetime.datetime | Unset): Example: 2025-01-02T09:15:00Z.
288
+
289
+ Raises:
290
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
291
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
292
+
293
+ Returns:
294
+ ImbalancePriceForecastsResponse | Problem
295
+ """
296
+
297
+ return (
298
+ await asyncio_detailed(
299
+ client=client,
300
+ area=area,
301
+ period_start_at=period_start_at,
302
+ period_end_at=period_end_at,
303
+ cursor=cursor,
304
+ limit=limit,
305
+ updated_since=updated_since,
306
+ )
307
+ ).parsed
@@ -49,6 +49,10 @@ from .eic_code import EicCode
49
49
  from .energy_bid import EnergyBid
50
50
  from .imbalance_direction import ImbalanceDirection
51
51
  from .imbalance_price import ImbalancePrice
52
+ from .imbalance_price_forecast import ImbalancePriceForecast
53
+ from .imbalance_price_forecast_quantile import ImbalancePriceForecastQuantile
54
+ from .imbalance_price_forecasts import ImbalancePriceForecasts
55
+ from .imbalance_price_forecasts_response import ImbalancePriceForecastsResponse
52
56
  from .imbalance_prices import ImbalancePrices
53
57
  from .imbalance_prices_response import ImbalancePricesResponse
54
58
  from .imbalance_total_volumes import ImbalanceTotalVolumes
@@ -106,6 +110,10 @@ __all__ = (
106
110
  "EnergyBid",
107
111
  "ImbalanceDirection",
108
112
  "ImbalancePrice",
113
+ "ImbalancePriceForecast",
114
+ "ImbalancePriceForecastQuantile",
115
+ "ImbalancePriceForecasts",
116
+ "ImbalancePriceForecastsResponse",
109
117
  "ImbalancePrices",
110
118
  "ImbalancePricesResponse",
111
119
  "ImbalanceTotalVolumes",
@@ -0,0 +1,111 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from collections.abc import Mapping
5
+ from typing import TYPE_CHECKING, Any, TypeVar
6
+
7
+ from attrs import define as _attrs_define
8
+ from attrs import field as _attrs_field
9
+
10
+ if TYPE_CHECKING:
11
+ from ..models.imbalance_price_forecast_quantile import (
12
+ ImbalancePriceForecastQuantile,
13
+ )
14
+ from ..models.period import Period
15
+
16
+
17
+ T = TypeVar("T", bound="ImbalancePriceForecast")
18
+
19
+
20
+ @_attrs_define
21
+ class ImbalancePriceForecast:
22
+ """
23
+ Attributes:
24
+ period (Period):
25
+ quantiles (list[ImbalancePriceForecastQuantile]): The predictive distribution of the price, as one level/price
26
+ pair per quantile level, ascending by level. Each forecast states the grid it was made on — read the levels off
27
+ it rather than indexing by a position you hardcoded.
28
+ made_at (datetime.datetime): When this forecast was made (UTC). Example: 2025-01-01T00:05:00Z.
29
+ degraded (bool): True when the forecast was computed from incomplete or stale inputs. It is still served, but is
30
+ less trustworthy — use with care.
31
+ """
32
+
33
+ period: Period
34
+ quantiles: list[ImbalancePriceForecastQuantile]
35
+ made_at: datetime.datetime
36
+ degraded: bool
37
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
38
+
39
+ def to_dict(self) -> dict[str, Any]:
40
+ period = self.period.to_dict()
41
+
42
+ quantiles = []
43
+ for quantiles_item_data in self.quantiles:
44
+ quantiles_item = quantiles_item_data.to_dict()
45
+ quantiles.append(quantiles_item)
46
+
47
+ made_at = self.made_at.isoformat()
48
+
49
+ degraded = self.degraded
50
+
51
+ field_dict: dict[str, Any] = {}
52
+ field_dict.update(self.additional_properties)
53
+ field_dict.update(
54
+ {
55
+ "period": period,
56
+ "quantiles": quantiles,
57
+ "madeAt": made_at,
58
+ "degraded": degraded,
59
+ }
60
+ )
61
+
62
+ return field_dict
63
+
64
+ @classmethod
65
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
66
+ from ..models.imbalance_price_forecast_quantile import (
67
+ ImbalancePriceForecastQuantile,
68
+ )
69
+ from ..models.period import Period
70
+
71
+ d = dict(src_dict)
72
+ period = Period.from_dict(d.pop("period"))
73
+
74
+ quantiles = []
75
+ _quantiles = d.pop("quantiles")
76
+ for quantiles_item_data in _quantiles:
77
+ quantiles_item = ImbalancePriceForecastQuantile.from_dict(
78
+ quantiles_item_data
79
+ )
80
+
81
+ quantiles.append(quantiles_item)
82
+
83
+ made_at = datetime.datetime.fromisoformat(d.pop("madeAt").replace("Z", "+00:00"))
84
+
85
+ degraded = d.pop("degraded")
86
+
87
+ imbalance_price_forecast = cls(
88
+ period=period,
89
+ quantiles=quantiles,
90
+ made_at=made_at,
91
+ degraded=degraded,
92
+ )
93
+
94
+ imbalance_price_forecast.additional_properties = d
95
+ return imbalance_price_forecast
96
+
97
+ @property
98
+ def additional_keys(self) -> list[str]:
99
+ return list(self.additional_properties.keys())
100
+
101
+ def __getitem__(self, key: str) -> Any:
102
+ return self.additional_properties[key]
103
+
104
+ def __setitem__(self, key: str, value: Any) -> None:
105
+ self.additional_properties[key] = value
106
+
107
+ def __delitem__(self, key: str) -> None:
108
+ del self.additional_properties[key]
109
+
110
+ def __contains__(self, key: str) -> bool:
111
+ return key in self.additional_properties
@@ -0,0 +1,70 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ T = TypeVar("T", bound="ImbalancePriceForecastQuantile")
10
+
11
+
12
+ @_attrs_define
13
+ class ImbalancePriceForecastQuantile:
14
+ """
15
+ Attributes:
16
+ level (float): The quantile level, as a decimal strictly between 0 and 1 — 0.5 being the median, and the pair
17
+ 0.1/0.9 bounding the central 80% interval. Example: 0.5.
18
+ price_per_mwh (float): Forecast price per MWh at this level, in the group's currency Example: 45.5.
19
+ """
20
+
21
+ level: float
22
+ price_per_mwh: float
23
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
24
+
25
+ def to_dict(self) -> dict[str, Any]:
26
+ level = self.level
27
+
28
+ price_per_mwh = self.price_per_mwh
29
+
30
+ field_dict: dict[str, Any] = {}
31
+ field_dict.update(self.additional_properties)
32
+ field_dict.update(
33
+ {
34
+ "level": level,
35
+ "pricePerMwh": price_per_mwh,
36
+ }
37
+ )
38
+
39
+ return field_dict
40
+
41
+ @classmethod
42
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
43
+ d = dict(src_dict)
44
+ level = d.pop("level")
45
+
46
+ price_per_mwh = d.pop("pricePerMwh")
47
+
48
+ imbalance_price_forecast_quantile = cls(
49
+ level=level,
50
+ price_per_mwh=price_per_mwh,
51
+ )
52
+
53
+ imbalance_price_forecast_quantile.additional_properties = d
54
+ return imbalance_price_forecast_quantile
55
+
56
+ @property
57
+ def additional_keys(self) -> list[str]:
58
+ return list(self.additional_properties.keys())
59
+
60
+ def __getitem__(self, key: str) -> Any:
61
+ return self.additional_properties[key]
62
+
63
+ def __setitem__(self, key: str, value: Any) -> None:
64
+ self.additional_properties[key] = value
65
+
66
+ def __delitem__(self, key: str) -> None:
67
+ del self.additional_properties[key]
68
+
69
+ def __contains__(self, key: str) -> bool:
70
+ return key in self.additional_properties