From 4e7d21e21f8facf96d0fcf4b4ca86fafc18047fe Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Wed, 6 Nov 2024 12:03:14 +0100 Subject: [PATCH 1/2] Update BaseClient to support keepalive Signed-off-by: Mathias L. Baumann --- RELEASE_NOTES.md | 4 ++++ pyproject.toml | 4 ++-- src/frequenz/client/dispatch/_client.py | 20 ++++++++++++++++++-- src/frequenz/client/dispatch/test/client.py | 3 +++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6ebf4395..8c48b285 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,9 @@ # Frequenz Dispatch Client Library Release Notes +## New Features + +* Update BaseApiClient to get the http2 keepalive feature. + ## Bug Fixes * Fix crash by adding the missing YEARLY frequency. diff --git a/pyproject.toml b/pyproject.toml index e4a7a5c0..bb8e4649 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,9 +38,9 @@ requires-python = ">= 3.11, < 4" dependencies = [ "typing-extensions >= 4.6.1, < 5", "frequenz-api-dispatch >= 0.15.1, < 0.16", - "frequenz-client-base >= 0.6.0, < 0.7.0", + "frequenz-client-base >= 0.7.0, < 0.8.0", "frequenz-client-common >= 0.1.0, < 0.3.0", - "grpcio >= 1.64.1, < 2", + "grpcio >= 1.66.1, < 2", ] dynamic = ["version"] diff --git a/src/frequenz/client/dispatch/_client.py b/src/frequenz/client/dispatch/_client.py index e2db9499..7126786c 100644 --- a/src/frequenz/client/dispatch/_client.py +++ b/src/frequenz/client/dispatch/_client.py @@ -2,6 +2,8 @@ # Copyright © 2024 Frequenz Energy-as-a-Service GmbH """Dispatch API client for Python.""" +from __future__ import annotations + from datetime import datetime, timedelta from importlib.resources import files from pathlib import Path @@ -33,6 +35,7 @@ from frequenz.client.base.channel import ChannelOptions, SslOptions from frequenz.client.base.client import BaseApiClient from frequenz.client.base.conversion import to_timestamp +from frequenz.client.base.exception import ClientNotConnected from frequenz.client.base.retry import LinearBackoff from frequenz.client.base.streaming import GrpcStreamBroadcaster @@ -49,7 +52,7 @@ DEFAULT_DISPATCH_PORT = 50051 -class Client(BaseApiClient[dispatch_pb2_grpc.MicrogridDispatchServiceStub]): +class Client(BaseApiClient): """Dispatch API client.""" streams: dict[ @@ -73,7 +76,6 @@ def __init__( """ super().__init__( server_url, - dispatch_pb2_grpc.MicrogridDispatchServiceStub, connect=connect, channel_defaults=ChannelOptions( port=DEFAULT_DISPATCH_PORT, @@ -88,6 +90,20 @@ def __init__( ), ) self._metadata = (("key", key),) + self._setup_stub() + + def _setup_stub(self) -> None: + self._stub = cast( + dispatch_pb2_grpc.MicrogridDispatchServiceAsyncStub, + dispatch_pb2_grpc.MicrogridDispatchServiceStub(self.channel), + ) + + @property + def stub(self) -> dispatch_pb2_grpc.MicrogridDispatchServiceAsyncStub: + """The stub for the service.""" + if self._channel is None: + raise ClientNotConnected(server_url=self.server_url, operation="stub") + return self._stub # pylint: disable=too-many-arguments, too-many-locals async def list( diff --git a/src/frequenz/client/dispatch/test/client.py b/src/frequenz/client/dispatch/test/client.py index 8c755aaa..ba12a074 100644 --- a/src/frequenz/client/dispatch/test/client.py +++ b/src/frequenz/client/dispatch/test/client.py @@ -34,6 +34,9 @@ def stub(self) -> FakeService: # type: ignore """ return self._stuba + def _setup_stub(self) -> None: + """Empty body because no setup needed.""" + def dispatches(self, microgrid_id: int) -> list[Dispatch]: """List of dispatches. From c1ba73d2c8c88080eb540fa490347b667f7b5117 Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Wed, 6 Nov 2024 12:24:58 +0100 Subject: [PATCH 2/2] Disable pylint no-member check as it is checked by mypy Signed-off-by: Mathias L. Baumann --- pyproject.toml | 2 ++ src/frequenz/client/dispatch/__main__.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bb8e4649..82f35d7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -151,6 +151,8 @@ disable = [ # pylint's unsubscriptable check is buggy and is not needed because # it is a type-check, for which we already have mypy. "unsubscriptable-object", + # Checked by mypy + "no-member", # Checked by flake8 "redefined-outer-name", "unused-import", diff --git a/src/frequenz/client/dispatch/__main__.py b/src/frequenz/client/dispatch/__main__.py index 92671e65..8b69526c 100644 --- a/src/frequenz/client/dispatch/__main__.py +++ b/src/frequenz/client/dispatch/__main__.py @@ -459,9 +459,9 @@ async def display_help() -> None: # Add recurrence options to the create command -create.params += recurrence_options # pylint: disable=no-member +create.params += recurrence_options # Add recurrence options to the update command -update.params += recurrence_options # pylint: disable=no-member +update.params += recurrence_options def main() -> None: