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:
python
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
import my_service_pb2_grpc
class MyApiClient(BaseApiClient):
def __init__(self, server_url: str, *, ...) -> None:
super().__init__(server_url, connect=connect)
stub = my_service_pb2_grpc.MyServiceStub(self.channel)
We need the type: ignore here because the generated async stub only lives in
the .pyi file (the interpreter doesn't know anything about it) so we can't use
a proper `cast()`, we can only use the async stub as a type hint.
self._stub: my_service_pb2_grpc.MyServiceAsyncStub = stub type: ignore
...
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.
toml
[tool.pylint.messages_control]
disable = [
[..]
Checked by mypy
"no-member",
[..]
]
After this, you should be able to remove a lot of `cast`s 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 https://github.com/frequenz-floss/frequenz-client-base-python/pull/83
* Replace the `stream_method` return to `AsyncIterable` by llucax in https://github.com/frequenz-floss/frequenz-client-base-python/pull/87
* Don't allow a default port in URLs by default by llucax in https://github.com/frequenz-floss/frequenz-client-base-python/pull/85
* Bump the required group with 9 updates by dependabot in https://github.com/frequenz-floss/frequenz-client-base-python/pull/89
* Don't retry by default when the stream is exhausted by shsms in https://github.com/frequenz-floss/frequenz-client-base-python/pull/91
* Support http2 keep-alive by shsms in https://github.com/frequenz-floss/frequenz-client-base-python/pull/90
* Remove generic type from `BaseApiClient` by llucax in https://github.com/frequenz-floss/frequenz-client-base-python/pull/92
* Prepare for v0.7.0 by shsms in https://github.com/frequenz-floss/frequenz-client-base-python/pull/93
**Full Changelog**: https://github.com/frequenz-floss/frequenz-client-base-python/compare/v0.6.1...v0.7.0