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
9 changes: 7 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@

## Upgrading

<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->
- `ApiClient`:

* The class was renamed to `MicrogridApiClient`.
* The `api` attribute was renamed to `stub`.
* The constructor parameter `channel_options` was renamed to `channels_defaults` to match the name used in `BaseApiClient`.
* The constructor now accepts a `connect` parameter, which is `True` by default. If set to `False`, the client will not connect to the server upon instantiation. You can connect later by calling the `connect()` method.

## New Features

<!-- Here goes the main new features and examples or instructions on how to use them -->
- The client now inherits from `frequenz.client.base.BaseApiClient`, so it provides a few new features, like `disconnect()`ing or using it as a context manager. Please refer to the [`BaseApiClient` documentation](https://frequenz-floss.github.io/frequenz-client-base-python/latest/reference/frequenz/client/base/client/#frequenz.client.base.client.BaseApiClient) for more information on these features.

## Bug Fixes

Expand Down
4 changes: 2 additions & 2 deletions src/frequenz/client/microgrid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"""


from ._client import ApiClient
from ._client import MicrogridApiClient
from ._component import (
Component,
ComponentCategory,
Expand Down Expand Up @@ -65,7 +65,7 @@
from ._metadata import Location, Metadata

__all__ = [
"ApiClient",
"MicrogridApiClient",
"ApiClientError",
"BatteryComponentState",
"BatteryData",
Expand Down
42 changes: 20 additions & 22 deletions src/frequenz/client/microgrid/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from frequenz.api.common import components_pb2, metrics_pb2
from frequenz.api.microgrid import microgrid_pb2, microgrid_pb2_grpc
from frequenz.channels import Receiver
from frequenz.client.base import channel, retry, streaming
from frequenz.client.base import channel, client, retry, streaming
from google.protobuf.empty_pb2 import Empty
from google.protobuf.timestamp_pb2 import Timestamp

Expand Down Expand Up @@ -55,14 +55,15 @@
"""


class ApiClient:
class MicrogridApiClient(client.BaseApiClient[microgrid_pb2_grpc.MicrogridStub]):
"""A microgrid API client."""

def __init__(
self,
server_url: str,
*,
channel_options: channel.ChannelOptions = DEFAULT_CHANNEL_OPTIONS,
channel_defaults: channel.ChannelOptions = DEFAULT_CHANNEL_OPTIONS,
connect: bool = True,
retry_strategy: retry.Strategy | None = None,
) -> None:
"""Initialize the class instance.
Expand All @@ -74,28 +75,25 @@ def __init__(
where the `port` should be an int between 0 and 65535 (defaulting to
9090) and `ssl` should be a boolean (defaulting to `false`).
For example: `grpc://localhost:1090?ssl=true`.
channel_options: The default options use to create the channel when not
channel_defaults: The default options use to create the channel when not
specified in the URL.
connect: Whether to connect to the server as soon as a client instance is
created. If `False`, the client will not connect to the server until
[connect()][frequenz.client.base.client.BaseApiClient.connect] is
called.
retry_strategy: The retry strategy to use to reconnect when the connection
to the streaming method is lost. By default a linear backoff strategy
is used.
"""
self._server_url = server_url
"""The location of the microgrid API server as a URL."""

self.api = microgrid_pb2_grpc.MicrogridStub(
channel.parse_grpc_uri(server_url, defaults=channel_options)
super().__init__(
server_url,
microgrid_pb2_grpc.MicrogridStub,
connect=connect,
channel_defaults=channel_defaults,
)
"""The gRPC stub for the microgrid API."""

self._broadcasters: dict[int, streaming.GrpcStreamBroadcaster[Any, Any]] = {}
self._retry_strategy = retry_strategy

@property
def server_url(self) -> str:
"""The server location in URL format."""
return self._server_url

async def components(self) -> Iterable[Component]:
"""Fetch all the components present in the microgrid.

Expand All @@ -112,7 +110,7 @@ async def components(self) -> Iterable[Component]:
# but it is
component_list = await cast(
Awaitable[microgrid_pb2.ComponentList],
self.api.ListComponents(
self.stub.ListComponents(
microgrid_pb2.ComponentFilter(),
timeout=int(DEFAULT_GRPC_CALL_TIMEOUT),
),
Expand Down Expand Up @@ -154,7 +152,7 @@ async def metadata(self) -> Metadata:
try:
microgrid_metadata = await cast(
Awaitable[microgrid_pb2.MicrogridMetadata],
self.api.GetMicrogridMetadata(
self.stub.GetMicrogridMetadata(
Empty(),
timeout=int(DEFAULT_GRPC_CALL_TIMEOUT),
),
Expand Down Expand Up @@ -203,7 +201,7 @@ async def connections(
# awaitable, but it is
cast(
Awaitable[microgrid_pb2.ConnectionList],
self.api.ListConnections(
self.stub.ListConnections(
connection_filter,
timeout=int(DEFAULT_GRPC_CALL_TIMEOUT),
),
Expand Down Expand Up @@ -269,7 +267,7 @@ async def _new_component_data_receiver(
# microgrid_pb2.ComponentData], which it is.
lambda: cast(
AsyncIterator[microgrid_pb2.ComponentData],
self.api.StreamComponentData(
self.stub.StreamComponentData(
microgrid_pb2.ComponentIdParam(id=component_id)
),
),
Expand Down Expand Up @@ -427,7 +425,7 @@ async def set_power(self, component_id: int, power_w: float) -> None:
try:
await cast(
Awaitable[Empty],
self.api.SetPowerActive(
self.stub.SetPowerActive(
microgrid_pb2.SetPowerActiveParam(
component_id=component_id, power=power_w
),
Expand Down Expand Up @@ -472,7 +470,7 @@ async def set_bounds(
try:
await cast(
Awaitable[Timestamp],
self.api.AddInclusionBounds(
self.stub.AddInclusionBounds(
microgrid_pb2.SetBoundsParam(
component_id=component_id,
target_metric=target_metric,
Expand Down
6 changes: 3 additions & 3 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from frequenz.client.base import retry

from frequenz.client.microgrid import (
ApiClient,
ApiClientError,
BatteryData,
Component,
Expand All @@ -28,11 +27,12 @@
InverterData,
InverterType,
MeterData,
MicrogridApiClient,
)
from frequenz.client.microgrid._connection import Connection


class _TestClient(ApiClient):
class _TestClient(MicrogridApiClient):
def __init__(self, *, retry_strategy: retry.Strategy | None = None) -> None:
# Here we sadly can't use spec=MicrogridStub because the generated stub typing
# is a mess, and for some reason inspection of gRPC methods doesn't work.
Expand All @@ -46,7 +46,7 @@ def __init__(self, *, retry_strategy: retry.Strategy | None = None) -> None:
mock_stub.StreamComponentData = mock.Mock("StreamComponentData")
super().__init__("grpc://mock_host:1234", retry_strategy=retry_strategy)
self.mock_stub = mock_stub
self.api = mock_stub
self._stub = mock_stub # pylint: disable=protected-access


async def test_components() -> None:
Expand Down