Skip to content

v0.7.0

Latest
Compare
Choose a tag to compare
@github-actions github-actions released this 29 Oct 13:30
· 4 commits to v0.x.x since this release
v0.7.0
3d35fe7

Frequenz Client Base Library Release Notes

Summary

This release improves the BaseApiClient interface and introduces HTTP2 keep-alive, among other changes.

Upgrading

  • GrpcStreamBroadcaster now takes a AsyncIterable instead of a AsyncIterator as the stream_method. This is to match the type of streaming methods generated by grpc, so no conversion to an AsyncIterator is needed.

  • GrpcStreamBroadcaster no longer tries to reconnect when a server closes a connection. This behaviour can be overridden by passing retry_on_exhausted_stream=True when constructing GrpcStreamBroadcaster instances.

  • gRPC URLs don't have a default port anymore, unless a default is set via ChannelOptions. If you want to set a default port for URLs, please pass custom ChannelOptions as defaults to parse_grpc_uri or as channel_defaults to BaseApiClient.

  • The ExponentialBackoff and LinearBackoff classes now require keyword arguments for their constructor. This change was made to make the classes easier to use and to avoid confusion with the order of the arguments.
  • HTTP2 keep-alive is now enabled by default, with an interval of 60 seconds between pings, and a 20 second timeout for responses from the service. These values are configurable and may be updated based on specific requirements.
  • The BaseApiClient class is not generic anymore, and doesn't take a function to create the stub. Instead, subclasses should create their own stub right after calling the parent constructor. This enables subclasses to cast the stub to the generated XxxAsyncStub class, which have proper async type hints. To convert you client:

    # Old
    from my_service_pb2_grpc import MyServiceStub
    class MyApiClient(BaseApiClient[MyServiceStub]):
        def __init__(self, server_url: str, *, ...) -> None:
            super().__init__(server_url, MyServiceStub, ...)
            ...
    
    # New
    from __future__ import annotations
    from typing import cast
    import my_service_pb2_grpc
    class MyApiClient(BaseApiClient):
        def __init__(self, server_url: str, *, ...) -> None:
            super().__init__(server_url, connect=connect)
            self._stub = cast(
                my_service_pb2_grpc.MyServiceAsyncStub,
                my_service_pb2_grpc.MyServiceStub(self.channel),
            )
            ...
    
        @property
        def stub(self) -> my_service_pb2_grpc.MyServiceAsyncStub:
            if self.channel is None:
                raise ClientNotConnected(server_url=self.server_url, operation="stub")
            return self._stub

    You probably also need to ignore the no-member check from pylint, as pylint doesn't read *.pyi files, so it won't find the async stub and complain.

    [tool.pylint.messages_control]
    disable = [
      # [..]
      # Checked by mypy
      "no-member",
      # [..]
    ]

    After this, you should be able to remove a lot of casts or type: ignore from the code when calling the stub async methods.

New Features

  • Added support for HTTP2 keep-alive.

What's Changed

  • Clear release notes by @shsms in #83
  • Replace the stream_method return to AsyncIterable by @llucax in #87
  • Don't allow a default port in URLs by default by @llucax in #85
  • Bump the required group with 9 updates by @dependabot in #89
  • Don't retry by default when the stream is exhausted by @shsms in #91
  • Support http2 keep-alive by @shsms in #90
  • Remove generic type from BaseApiClient by @llucax in #92
  • Prepare for v0.7.0 by @shsms in #93

Full Changelog: v0.6.1...v0.7.0