balancing-services 2.1.0__tar.gz → 2.2.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 (114) hide show
  1. {balancing_services-2.1.0 → balancing_services-2.2.0}/PKG-INFO +2 -2
  2. balancing_services-2.2.0/balancing_services/api/default/get_imbalance_price_history.py +307 -0
  3. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/__init__.py +6 -0
  4. balancing_services-2.2.0/balancing_services/models/imbalance_price_history.py +112 -0
  5. balancing_services-2.2.0/balancing_services/models/imbalance_price_history_response.py +128 -0
  6. balancing_services-2.2.0/balancing_services/models/imbalance_price_revision.py +84 -0
  7. {balancing_services-2.1.0 → balancing_services-2.2.0}/pyproject.toml +1 -1
  8. {balancing_services-2.1.0 → balancing_services-2.2.0}/tests/test_basic.py +23 -0
  9. {balancing_services-2.1.0 → balancing_services-2.2.0}/tests/test_integration.py +164 -0
  10. {balancing_services-2.1.0 → balancing_services-2.2.0}/.env.sample +0 -0
  11. {balancing_services-2.1.0 → balancing_services-2.2.0}/.gitignore +0 -0
  12. {balancing_services-2.1.0 → balancing_services-2.2.0}/LICENSE +0 -0
  13. {balancing_services-2.1.0 → balancing_services-2.2.0}/PUBLISHING.md +0 -0
  14. {balancing_services-2.1.0 → balancing_services-2.2.0}/README.md +0 -0
  15. {balancing_services-2.1.0 → balancing_services-2.2.0}/RELEASE_CHECKLIST.md +0 -0
  16. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/__init__.py +0 -0
  17. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/__init__.py +0 -0
  18. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/__init__.py +0 -0
  19. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_capacity_bids.py +0 -0
  20. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_capacity_demand.py +0 -0
  21. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_capacity_prices.py +0 -0
  22. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_capacity_procured_volumes.py +0 -0
  23. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_energy_activated_volumes.py +0 -0
  24. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_energy_bids.py +0 -0
  25. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_energy_demand.py +0 -0
  26. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_energy_offered_volumes.py +0 -0
  27. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_energy_prices.py +0 -0
  28. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_balancing_energy_satisfied_demand.py +0 -0
  29. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_cross_border_available_capacity.py +0 -0
  30. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_cross_border_energy_volumes.py +0 -0
  31. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_cross_border_marginal_prices.py +0 -0
  32. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_cross_zonal_capacity_allocation.py +0 -0
  33. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_current_imbalance_total_volumes.py +0 -0
  34. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_day_ahead_energy_prices.py +0 -0
  35. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_imbalance_price_forecasts.py +0 -0
  36. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_imbalance_prices.py +0 -0
  37. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/api/default/get_imbalance_total_volumes.py +0 -0
  38. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/client.py +0 -0
  39. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/errors.py +0 -0
  40. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/activation_type.py +0 -0
  41. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/area.py +0 -0
  42. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_bid_period.py +0 -0
  43. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_bids.py +0 -0
  44. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_bids_response.py +0 -0
  45. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_demand.py +0 -0
  46. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_demands.py +0 -0
  47. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_demands_response.py +0 -0
  48. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_price.py +0 -0
  49. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_prices.py +0 -0
  50. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_prices_response.py +0 -0
  51. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_volume.py +0 -0
  52. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_volumes.py +0 -0
  53. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_capacity_volumes_response.py +0 -0
  54. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_bid_period.py +0 -0
  55. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_bids.py +0 -0
  56. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_bids_response.py +0 -0
  57. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_price.py +0 -0
  58. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_prices.py +0 -0
  59. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_prices_response.py +0 -0
  60. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_volume.py +0 -0
  61. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_volumes.py +0 -0
  62. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/balancing_energy_volumes_response.py +0 -0
  63. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/bid_status.py +0 -0
  64. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/capacity_bid.py +0 -0
  65. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_available_capacity.py +0 -0
  66. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_available_capacity_response.py +0 -0
  67. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_available_capacity_value.py +0 -0
  68. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_energy_volumes.py +0 -0
  69. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_energy_volumes_response.py +0 -0
  70. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_marginal_price.py +0 -0
  71. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_marginal_prices.py +0 -0
  72. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_border_marginal_prices_response.py +0 -0
  73. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_zonal_capacity_allocation_response.py +0 -0
  74. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/cross_zonal_volumes.py +0 -0
  75. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/currency.py +0 -0
  76. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/day_ahead_energy_price.py +0 -0
  77. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/day_ahead_energy_prices.py +0 -0
  78. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/day_ahead_energy_prices_response.py +0 -0
  79. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/demand_basis.py +0 -0
  80. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/direction.py +0 -0
  81. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/eic_code.py +0 -0
  82. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/energy_bid.py +0 -0
  83. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_direction.py +0 -0
  84. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_price.py +0 -0
  85. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_price_forecast.py +0 -0
  86. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_price_forecast_quantile.py +0 -0
  87. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_price_forecasts.py +0 -0
  88. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_price_forecasts_response.py +0 -0
  89. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_prices.py +0 -0
  90. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_prices_response.py +0 -0
  91. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_total_volumes.py +0 -0
  92. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/imbalance_total_volumes_response.py +0 -0
  93. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/period.py +0 -0
  94. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/problem.py +0 -0
  95. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/procurement.py +0 -0
  96. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/reserve_type.py +0 -0
  97. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/total_imbalance_direction.py +0 -0
  98. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/models/total_imbalance_volume.py +0 -0
  99. {balancing_services-2.1.0 → balancing_services-2.2.0}/balancing_services/types.py +0 -0
  100. {balancing_services-2.1.0 → balancing_services-2.2.0}/check.sh +0 -0
  101. {balancing_services-2.1.0 → balancing_services-2.2.0}/config.yaml +0 -0
  102. {balancing_services-2.1.0 → balancing_services-2.2.0}/examples/basic_usage.py +0 -0
  103. {balancing_services-2.1.0 → balancing_services-2.2.0}/examples/error_handling.py +0 -0
  104. {balancing_services-2.1.0 → balancing_services-2.2.0}/examples/pagination_example.py +0 -0
  105. {balancing_services-2.1.0 → balancing_services-2.2.0}/fix_enum_validator_casts.py +0 -0
  106. {balancing_services-2.1.0 → balancing_services-2.2.0}/generate-pyproject.sh +0 -0
  107. {balancing_services-2.1.0 → balancing_services-2.2.0}/generate.sh +0 -0
  108. {balancing_services-2.1.0 → balancing_services-2.2.0}/pyproject.toml.draft +0 -0
  109. {balancing_services-2.1.0 → balancing_services-2.2.0}/test-and-publish.sh +0 -0
  110. {balancing_services-2.1.0 → balancing_services-2.2.0}/tests/conftest.py +0 -0
  111. {balancing_services-2.1.0 → balancing_services-2.2.0}/tests/test_async.py +0 -0
  112. {balancing_services-2.1.0 → balancing_services-2.2.0}/tests/test_datetime_compat.py +0 -0
  113. {balancing_services-2.1.0 → balancing_services-2.2.0}/tests/test_procured_at_none_handling.py +0 -0
  114. {balancing_services-2.1.0 → balancing_services-2.2.0}/tests/test_readme_execution.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: balancing-services
3
- Version: 2.1.0
3
+ Version: 2.2.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
@@ -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_history_response import ImbalancePriceHistoryResponse
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/history",
50
+ "params": params,
51
+ }
52
+
53
+ return _kwargs
54
+
55
+
56
+ def _parse_response(
57
+ *, client: AuthenticatedClient | Client, response: httpx.Response
58
+ ) -> ImbalancePriceHistoryResponse | Problem | None:
59
+ if response.status_code == 200:
60
+ response_200 = ImbalancePriceHistoryResponse.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[ImbalancePriceHistoryResponse | 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[ImbalancePriceHistoryResponse | Problem]:
126
+ """Get the revision history of the imbalance prices for an area
127
+
128
+ **Experimental** - This endpoint is under active development and may change without notice.
129
+
130
+ Returns how the imbalance prices on `/imbalance/prices` reached their current values: the
131
+ sequence of values held for a period, each stamped with the `observedAt` it was recorded at.
132
+ The response is the `/imbalance/prices` shape with `observedAt` added to each entry of
133
+ `prices`, which carries the revision entries, ascending by `observedAt`.
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[ImbalancePriceHistoryResponse | 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
+ ) -> ImbalancePriceHistoryResponse | Problem | None:
177
+ """Get the revision history of the imbalance prices for an area
178
+
179
+ **Experimental** - This endpoint is under active development and may change without notice.
180
+
181
+ Returns how the imbalance prices on `/imbalance/prices` reached their current values: the
182
+ sequence of values held for a period, each stamped with the `observedAt` it was recorded at.
183
+ The response is the `/imbalance/prices` shape with `observedAt` added to each entry of
184
+ `prices`, which carries the revision entries, ascending by `observedAt`.
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
+ ImbalancePriceHistoryResponse | 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[ImbalancePriceHistoryResponse | Problem]:
223
+ """Get the revision history of the imbalance prices for an area
224
+
225
+ **Experimental** - This endpoint is under active development and may change without notice.
226
+
227
+ Returns how the imbalance prices on `/imbalance/prices` reached their current values: the
228
+ sequence of values held for a period, each stamped with the `observedAt` it was recorded at.
229
+ The response is the `/imbalance/prices` shape with `observedAt` added to each entry of
230
+ `prices`, which carries the revision entries, ascending by `observedAt`.
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[ImbalancePriceHistoryResponse | 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
+ ) -> ImbalancePriceHistoryResponse | Problem | None:
272
+ """Get the revision history of the imbalance prices for an area
273
+
274
+ **Experimental** - This endpoint is under active development and may change without notice.
275
+
276
+ Returns how the imbalance prices on `/imbalance/prices` reached their current values: the
277
+ sequence of values held for a period, each stamped with the `observedAt` it was recorded at.
278
+ The response is the `/imbalance/prices` shape with `observedAt` added to each entry of
279
+ `prices`, which carries the revision entries, ascending by `observedAt`.
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
+ ImbalancePriceHistoryResponse | 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
@@ -53,6 +53,9 @@ from .imbalance_price_forecast import ImbalancePriceForecast
53
53
  from .imbalance_price_forecast_quantile import ImbalancePriceForecastQuantile
54
54
  from .imbalance_price_forecasts import ImbalancePriceForecasts
55
55
  from .imbalance_price_forecasts_response import ImbalancePriceForecastsResponse
56
+ from .imbalance_price_history import ImbalancePriceHistory
57
+ from .imbalance_price_history_response import ImbalancePriceHistoryResponse
58
+ from .imbalance_price_revision import ImbalancePriceRevision
56
59
  from .imbalance_prices import ImbalancePrices
57
60
  from .imbalance_prices_response import ImbalancePricesResponse
58
61
  from .imbalance_total_volumes import ImbalanceTotalVolumes
@@ -114,6 +117,9 @@ __all__ = (
114
117
  "ImbalancePriceForecastQuantile",
115
118
  "ImbalancePriceForecasts",
116
119
  "ImbalancePriceForecastsResponse",
120
+ "ImbalancePriceHistory",
121
+ "ImbalancePriceHistoryResponse",
122
+ "ImbalancePriceRevision",
117
123
  "ImbalancePrices",
118
124
  "ImbalancePricesResponse",
119
125
  "ImbalanceTotalVolumes",
@@ -0,0 +1,112 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import TYPE_CHECKING, Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ from ..models.area import Area, check_area
10
+ from ..models.currency import Currency, check_currency
11
+ from ..models.eic_code import EicCode, check_eic_code
12
+ from ..models.imbalance_direction import ImbalanceDirection, check_imbalance_direction
13
+
14
+ if TYPE_CHECKING:
15
+ from ..models.imbalance_price_revision import ImbalancePriceRevision
16
+
17
+
18
+ T = TypeVar("T", bound="ImbalancePriceHistory")
19
+
20
+
21
+ @_attrs_define
22
+ class ImbalancePriceHistory:
23
+ """
24
+ Attributes:
25
+ area (Area): Area code
26
+ eic_code (EicCode): Energy Identification Code (EIC)
27
+ currency (Currency): Currency code
28
+ direction (ImbalanceDirection): Imbalance direction
29
+ prices (list[ImbalancePriceRevision]):
30
+ """
31
+
32
+ area: Area
33
+ eic_code: EicCode
34
+ currency: Currency
35
+ direction: ImbalanceDirection
36
+ prices: list[ImbalancePriceRevision]
37
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
38
+
39
+ def to_dict(self) -> dict[str, Any]:
40
+ area: str = self.area
41
+
42
+ eic_code: str = self.eic_code
43
+
44
+ currency: str = self.currency
45
+
46
+ direction: str = self.direction
47
+
48
+ prices = []
49
+ for prices_item_data in self.prices:
50
+ prices_item = prices_item_data.to_dict()
51
+ prices.append(prices_item)
52
+
53
+ field_dict: dict[str, Any] = {}
54
+ field_dict.update(self.additional_properties)
55
+ field_dict.update(
56
+ {
57
+ "area": area,
58
+ "eicCode": eic_code,
59
+ "currency": currency,
60
+ "direction": direction,
61
+ "prices": prices,
62
+ }
63
+ )
64
+
65
+ return field_dict
66
+
67
+ @classmethod
68
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
69
+ from ..models.imbalance_price_revision import ImbalancePriceRevision
70
+
71
+ d = dict(src_dict)
72
+ area = check_area(d.pop("area"))
73
+
74
+ eic_code = check_eic_code(d.pop("eicCode"))
75
+
76
+ currency = check_currency(d.pop("currency"))
77
+
78
+ direction = check_imbalance_direction(d.pop("direction"))
79
+
80
+ prices = []
81
+ _prices = d.pop("prices")
82
+ for prices_item_data in _prices:
83
+ prices_item = ImbalancePriceRevision.from_dict(prices_item_data)
84
+
85
+ prices.append(prices_item)
86
+
87
+ imbalance_price_history = cls(
88
+ area=area,
89
+ eic_code=eic_code,
90
+ currency=currency,
91
+ direction=direction,
92
+ prices=prices,
93
+ )
94
+
95
+ imbalance_price_history.additional_properties = d
96
+ return imbalance_price_history
97
+
98
+ @property
99
+ def additional_keys(self) -> list[str]:
100
+ return list(self.additional_properties.keys())
101
+
102
+ def __getitem__(self, key: str) -> Any:
103
+ return self.additional_properties[key]
104
+
105
+ def __setitem__(self, key: str, value: Any) -> None:
106
+ self.additional_properties[key] = value
107
+
108
+ def __delitem__(self, key: str) -> None:
109
+ del self.additional_properties[key]
110
+
111
+ def __contains__(self, key: str) -> bool:
112
+ return key in self.additional_properties
@@ -0,0 +1,128 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from collections.abc import Mapping
5
+ from typing import TYPE_CHECKING, Any, TypeVar, cast
6
+
7
+ from attrs import define as _attrs_define
8
+ from attrs import field as _attrs_field
9
+
10
+ from ..types import UNSET, Unset
11
+
12
+ if TYPE_CHECKING:
13
+ from ..models.imbalance_price_history import ImbalancePriceHistory
14
+ from ..models.period import Period
15
+
16
+
17
+ T = TypeVar("T", bound="ImbalancePriceHistoryResponse")
18
+
19
+
20
+ @_attrs_define
21
+ class ImbalancePriceHistoryResponse:
22
+ """
23
+ Attributes:
24
+ queried_period (Period):
25
+ data (list[ImbalancePriceHistory]):
26
+ has_more (bool): Indicates whether there are more results available
27
+ next_updated_since (datetime.datetime): The watermark to pass as `updated-since` on the next poll. Every page of
28
+ one drain reports the same value. It deliberately lags real time to cover writes that were still committing, so
29
+ consecutive polls overlap slightly and a record may be delivered more than once — upsert on consume. Example:
30
+ 2025-01-02T09:15:00Z.
31
+ next_cursor (None | str | Unset): Cursor to fetch the next page of results. Null if no more results. Example:
32
+ v1:AAAAAYwBAgMEBQYHCAkKCw==.
33
+ """
34
+
35
+ queried_period: Period
36
+ data: list[ImbalancePriceHistory]
37
+ has_more: bool
38
+ next_updated_since: datetime.datetime
39
+ next_cursor: None | str | Unset = UNSET
40
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
41
+
42
+ def to_dict(self) -> dict[str, Any]:
43
+ queried_period = self.queried_period.to_dict()
44
+
45
+ data = []
46
+ for data_item_data in self.data:
47
+ data_item = data_item_data.to_dict()
48
+ data.append(data_item)
49
+
50
+ has_more = self.has_more
51
+
52
+ next_updated_since = self.next_updated_since.isoformat()
53
+
54
+ next_cursor: None | str | Unset
55
+ if isinstance(self.next_cursor, Unset):
56
+ next_cursor = UNSET
57
+ else:
58
+ next_cursor = self.next_cursor
59
+
60
+ field_dict: dict[str, Any] = {}
61
+ field_dict.update(self.additional_properties)
62
+ field_dict.update(
63
+ {
64
+ "queriedPeriod": queried_period,
65
+ "data": data,
66
+ "hasMore": has_more,
67
+ "nextUpdatedSince": next_updated_since,
68
+ }
69
+ )
70
+ if next_cursor is not UNSET:
71
+ field_dict["nextCursor"] = next_cursor
72
+
73
+ return field_dict
74
+
75
+ @classmethod
76
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
77
+ from ..models.imbalance_price_history import ImbalancePriceHistory
78
+ from ..models.period import Period
79
+
80
+ d = dict(src_dict)
81
+ queried_period = Period.from_dict(d.pop("queriedPeriod"))
82
+
83
+ data = []
84
+ _data = d.pop("data")
85
+ for data_item_data in _data:
86
+ data_item = ImbalancePriceHistory.from_dict(data_item_data)
87
+
88
+ data.append(data_item)
89
+
90
+ has_more = d.pop("hasMore")
91
+
92
+ next_updated_since = datetime.datetime.fromisoformat(d.pop("nextUpdatedSince").replace("Z", "+00:00"))
93
+
94
+ def _parse_next_cursor(data: object) -> None | str | Unset:
95
+ if data is None:
96
+ return data
97
+ if isinstance(data, Unset):
98
+ return data
99
+ return cast(None | str | Unset, data)
100
+
101
+ next_cursor = _parse_next_cursor(d.pop("nextCursor", UNSET))
102
+
103
+ imbalance_price_history_response = cls(
104
+ queried_period=queried_period,
105
+ data=data,
106
+ has_more=has_more,
107
+ next_updated_since=next_updated_since,
108
+ next_cursor=next_cursor,
109
+ )
110
+
111
+ imbalance_price_history_response.additional_properties = d
112
+ return imbalance_price_history_response
113
+
114
+ @property
115
+ def additional_keys(self) -> list[str]:
116
+ return list(self.additional_properties.keys())
117
+
118
+ def __getitem__(self, key: str) -> Any:
119
+ return self.additional_properties[key]
120
+
121
+ def __setitem__(self, key: str, value: Any) -> None:
122
+ self.additional_properties[key] = value
123
+
124
+ def __delitem__(self, key: str) -> None:
125
+ del self.additional_properties[key]
126
+
127
+ def __contains__(self, key: str) -> bool:
128
+ return key in self.additional_properties
@@ -0,0 +1,84 @@
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.period import Period
12
+
13
+
14
+ T = TypeVar("T", bound="ImbalancePriceRevision")
15
+
16
+
17
+ @_attrs_define
18
+ class ImbalancePriceRevision:
19
+ """
20
+ Attributes:
21
+ period (Period):
22
+ price_per_mwh (float): Price per MWh in the specified currency Example: 45.5.
23
+ observed_at (datetime.datetime): When this revision was recorded (UTC) Example: 2026-08-04T10:07:31Z.
24
+ """
25
+
26
+ period: Period
27
+ price_per_mwh: float
28
+ observed_at: datetime.datetime
29
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
30
+
31
+ def to_dict(self) -> dict[str, Any]:
32
+ period = self.period.to_dict()
33
+
34
+ price_per_mwh = self.price_per_mwh
35
+
36
+ observed_at = self.observed_at.isoformat()
37
+
38
+ field_dict: dict[str, Any] = {}
39
+ field_dict.update(self.additional_properties)
40
+ field_dict.update(
41
+ {
42
+ "period": period,
43
+ "pricePerMwh": price_per_mwh,
44
+ "observedAt": observed_at,
45
+ }
46
+ )
47
+
48
+ return field_dict
49
+
50
+ @classmethod
51
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
52
+ from ..models.period import Period
53
+
54
+ d = dict(src_dict)
55
+ period = Period.from_dict(d.pop("period"))
56
+
57
+ price_per_mwh = d.pop("pricePerMwh")
58
+
59
+ observed_at = datetime.datetime.fromisoformat(d.pop("observedAt").replace("Z", "+00:00"))
60
+
61
+ imbalance_price_revision = cls(
62
+ period=period,
63
+ price_per_mwh=price_per_mwh,
64
+ observed_at=observed_at,
65
+ )
66
+
67
+ imbalance_price_revision.additional_properties = d
68
+ return imbalance_price_revision
69
+
70
+ @property
71
+ def additional_keys(self) -> list[str]:
72
+ return list(self.additional_properties.keys())
73
+
74
+ def __getitem__(self, key: str) -> Any:
75
+ return self.additional_properties[key]
76
+
77
+ def __setitem__(self, key: str, value: Any) -> None:
78
+ self.additional_properties[key] = value
79
+
80
+ def __delitem__(self, key: str) -> None:
81
+ del self.additional_properties[key]
82
+
83
+ def __contains__(self, key: str) -> bool:
84
+ return key in self.additional_properties
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "balancing-services"
7
- version = "2.1.0"
7
+ version = "2.2.0"
8
8
  description = "Official Python client for accessing European electricity balancing market data via the Balancing Services REST API"
9
9
  readme = {file = "README.md", content-type = "text/markdown"}
10
10
  requires-python = ">=3.10"