Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@

## Summary

<!-- Here goes a general summary of what this release is about -->
This release adds enhanced filtering capabilities for gridpool orders and trades, with support for tag-based filtering and more flexible time-based queries.

## Upgrading
## New Features

<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->
* **Tag filtering for gridpool trades**: The `gridpool_trades()` method now accepts a `tag` parameter to filter trades by tag. The `GridpoolTradeFilter` dataclass has been updated accordingly.

## New Features
* **Flexible time filtering with `DeliveryTimeFilter`**: Replaced the restrictive `delivery_period` parameter with a more flexible `delivery_time_filter` across gridpool orders and trades methods. The new `DeliveryTimeFilter` supports:
- Time interval filtering with optional start/end times
- Multiple delivery duration filters
- More granular control over time-based queries

* **New types for time filtering**: Added `Interval` and `DeliveryTimeFilter` types to support the enhanced filtering API.

* Support tags in CLI create-order command.

## Bug Fixes
## Breaking Changes

* The `delivery_period` parameter has been replaced with `delivery_time_filter` in the following methods:
- `list_gridpool_orders()`
- `stream_gridpool_orders()`
- `gridpool_trades()`

Note: The `create_gridpool_order()` method maintains backward compatibility by keeping both parameters.

<!-- Here goes notable bug fixes that are worth a special mention or explanation -->
* Updated API imports from v1 to v1alpha8 for common types.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ dependencies = [
"click >= 8.1.8, < 9",
# Stick to a version without a polluting `tests` package: https://github.com/EnergieID/entsoe-py/pull/447
"entsoe-py >= 0.6.16, < 0.7.1",
"frequenz-api-common >= 0.6.5, < 0.9.0",
"frequenz-api-common >= 0.8.1, < 0.9.0",
"grpcio >= 1.72.1, < 2",
"frequenz-channels >= 1.6.1, < 2",
"frequenz-client-base >= 0.11.0, < 0.12.0",
"frequenz-client-common >= 0.1.0, < 0.4.0",
"frequenz-api-electricity-trading >= 0.8.0, < 0.9.0",
"frequenz-api-electricity-trading >= 0.9.0, < 0.10.0",
"protobuf >= 6.31.1, < 8", # Do not widen beyond 8!
]
dynamic = ["version"]
Expand Down
60 changes: 42 additions & 18 deletions src/frequenz/client/electricity_trading/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
from zoneinfo import ZoneInfo

import grpc
from frequenz.api.common.v1.pagination.pagination_params_pb2 import PaginationParams
from frequenz.api.common.v1alpha8.pagination.pagination_params_pb2 import (
PaginationParams,
)

# pylint: disable=no-member
from frequenz.api.electricity_trading.v1 import (
Expand All @@ -28,13 +30,13 @@
from frequenz.client.base.client import BaseApiClient
from frequenz.client.base.exception import ClientNotConnected
from frequenz.client.base.streaming import GrpcStreamBroadcaster
from frequenz.client.common.pagination import Params
from google.protobuf import field_mask_pb2, struct_pb2
from google.protobuf.timestamp_pb2 import Timestamp

from ._types import (
DeliveryArea,
DeliveryPeriod,
DeliveryTimeFilter,
GridpoolOrderFilter,
GridpoolTradeFilter,
MarketSide,
Expand Down Expand Up @@ -277,7 +279,7 @@ def gridpool_orders_stream(
order_states: list[OrderState] | None = None,
market_side: MarketSide | None = None,
delivery_area: DeliveryArea | None = None,
delivery_period: DeliveryPeriod | None = None,
delivery_time_filter: DeliveryTimeFilter | None = None,
tag: str | None = None,
) -> GrpcStreamBroadcaster[
electricity_trading_pb2.ReceiveGridpoolOrdersStreamResponse, OrderDetail
Expand All @@ -290,7 +292,7 @@ def gridpool_orders_stream(
order_states: List of order states to filter for.
market_side: Market side to filter for.
delivery_area: Delivery area to filter for.
delivery_period: Delivery period to filter for.
delivery_time_filter: Delivery time to filter for.
tag: Tag to filter for.

Returns:
Expand All @@ -299,13 +301,13 @@ def gridpool_orders_stream(
Raises:
grpc.RpcError: If an error occurs while streaming the orders.
"""
self.validate_params(delivery_period=delivery_period)
self.validate_params(delivery_time_filter=delivery_time_filter)

gridpool_order_filter = GridpoolOrderFilter(
order_states=order_states,
side=market_side,
delivery_area=delivery_area,
delivery_period=delivery_period,
delivery_time_filter=delivery_time_filter,
tag=tag,
)

Expand Down Expand Up @@ -341,8 +343,9 @@ def gridpool_trades_stream(
trade_states: list[TradeState] | None = None,
trade_ids: list[int] | None = None,
market_side: MarketSide | None = None,
delivery_period: DeliveryPeriod | None = None,
delivery_time_filter: DeliveryTimeFilter | None = None,
delivery_area: DeliveryArea | None = None,
tag: str | None = None,
) -> GrpcStreamBroadcaster[
electricity_trading_pb2.ReceiveGridpoolTradesStreamResponse, Trade
]:
Expand All @@ -354,23 +357,25 @@ def gridpool_trades_stream(
trade_states: List of trade states to filter for.
trade_ids: List of trade IDs to filter for.
market_side: The market side to filter for.
delivery_period: The delivery period to filter for.
delivery_time_filter: The delivery time filter of the trade.
delivery_area: The delivery area to filter for.
tag: The tag to filter for.

Returns:
The gridpool trades streamer.

Raises:
grpc.RpcError: If an error occurs while streaming gridpool trades.
"""
self.validate_params(delivery_period=delivery_period)
self.validate_params(delivery_time_filter=delivery_time_filter)

gridpool_trade_filter = GridpoolTradeFilter(
trade_states=trade_states,
trade_ids=trade_ids,
side=market_side,
delivery_period=delivery_period,
delivery_time_filter=delivery_time_filter,
delivery_area=delivery_area,
tag=tag,
)

stream_key = (gridpool_id, gridpool_trade_filter)
Expand Down Expand Up @@ -407,6 +412,7 @@ def validate_params(
peak_price_delta: Price | None | _NoValue = NO_VALUE,
display_quantity: Power | None | _NoValue = NO_VALUE,
delivery_period: DeliveryPeriod | None = None,
delivery_time_filter: DeliveryTimeFilter | None = None,
valid_until: datetime | None | _NoValue = NO_VALUE,
execution_option: OrderExecutionOption | None | _NoValue = NO_VALUE,
order_type: OrderType | None = None,
Expand All @@ -425,6 +431,7 @@ def validate_params(
peak_price_delta: The peak price delta of the order.
display_quantity: The display quantity of the order.
delivery_period: The delivery period of the order.
delivery_time_filter: The delivery time filter of the order.
valid_until: The valid until of the order.
execution_option: The execution option of the order.
order_type: The order type.
Expand Down Expand Up @@ -458,6 +465,23 @@ def validate_params(
if delivery_period is not None:
if delivery_period.start < datetime.now(timezone.utc):
raise ValueError("delivery_period must be in the future")
if (
delivery_time_filter is not None
and delivery_time_filter.time_interval is not None
and delivery_time_filter.time_interval.start_time is not None
):
if delivery_time_filter.time_interval.start_time < datetime.now(
timezone.utc
):
raise ValueError("delivery_time_filter must be in the future")
if (
Comment thread
florian-wagner-frequenz marked this conversation as resolved.
delivery_time_filter.time_interval.end_time is not None
and delivery_time_filter.time_interval.end_time
< delivery_time_filter.time_interval.start_time
):
raise ValueError(
"delivery_time_filter end time must be after start time"
)
if not isinstance(valid_until, _NoValue) and valid_until is not None:
if (
not isinstance(execution_option, _NoValue)
Expand Down Expand Up @@ -804,7 +828,7 @@ async def list_gridpool_orders(
*,
order_states: list[OrderState] | None = None,
side: MarketSide | None = None,
delivery_period: DeliveryPeriod | None = None,
delivery_time_filter: DeliveryTimeFilter | None = None,
delivery_area: DeliveryArea | None = None,
tag: str | None = None,
page_size: int | None = None,
Expand All @@ -817,7 +841,7 @@ async def list_gridpool_orders(
gridpool_id: The Gridpool to retrieve the orders for.
order_states: List of order states to filter by.
side: The side of the market to filter by.
delivery_period: The delivery period to filter by.
delivery_time_filter: The delivery time filter of the order.
delivery_area: The delivery area to filter by.
tag: The tag to filter by.
page_size: The number of orders to return per page.
Expand All @@ -832,7 +856,7 @@ async def list_gridpool_orders(
gridpool_order_filter = GridpoolOrderFilter(
order_states=order_states,
side=side,
delivery_period=delivery_period,
delivery_time_filter=delivery_time_filter,
delivery_area=delivery_area,
tag=tag,
)
Expand All @@ -841,7 +865,7 @@ async def list_gridpool_orders(
gridpool_id=gridpool_id,
filter=gridpool_order_filter.to_pb(),
pagination_params=(
Params(page_size=page_size, page_token="").to_proto()
PaginationParams(page_size=page_size, page_token="")
if page_size
else None
),
Expand Down Expand Up @@ -881,7 +905,7 @@ async def list_gridpool_trades(
trade_states: list[TradeState] | None = None,
trade_ids: list[int] | None = None,
market_side: MarketSide | None = None,
delivery_period: DeliveryPeriod | None = None,
delivery_time_filter: DeliveryTimeFilter | None = None,
delivery_area: DeliveryArea | None = None,
page_size: int | None = None,
timeout: timedelta | None = None,
Expand All @@ -894,7 +918,7 @@ async def list_gridpool_trades(
trade_states: List of trade states to filter by.
trade_ids: List of trade IDs to filter by.
market_side: The side of the market to filter by.
delivery_period: The delivery period to filter by.
delivery_time_filter: The delivery time filter of the order.
delivery_area: The delivery area to filter by.
page_size: The number of trades to return per page.
timeout: Timeout duration, defaults to None.
Expand All @@ -909,15 +933,15 @@ async def list_gridpool_trades(
trade_states=trade_states,
trade_ids=trade_ids,
side=market_side,
delivery_period=delivery_period,
delivery_time_filter=delivery_time_filter,
delivery_area=delivery_area,
)

request = electricity_trading_pb2.ListGridpoolTradesRequest(
gridpool_id=gridpool_id,
filter=gridpool_trade_filter.to_pb(),
pagination_params=(
Params(page_size=page_size, page_token="").to_proto()
PaginationParams(page_size=page_size, page_token="")
if page_size
else None
),
Expand Down
Loading