Releases: frequenz-floss/frequenz-client-base-python
v0.11.1
Frequenz Client Base Library Release Notes
Warning
This version has a bug in the streaming module that makes any stream using GrpcStreamBroadcaster not receive any data. The version was yanked from PyPI and should not be used.
Upgrading
- There is very minor breaking change in this release,
GrpcStreamBroadcasternow requires agrpc.aio.UnaryStreamCallinstead of aAsyncIterablefor thestream_methodargument. In practice all users should be passing agrpc.aio.UnaryStreamCallalready, so this should not affect anyone unless they are doing something very strange.
Bug Fixes
-
GrpcStreamBroadcaster: Fix potential long delays on retries, and giving up early if the number of retries is limited.The retry strategy was not reset after a successful start of the stream, so the back-off delays would accumulate over multiple retries and eventually give up if the number of retries were limited, even if there was a successful start of the stream in between. Now we properly reset the retry strategy after a successful start of the stream (successfully receiving the first item from the stream).
-
GrpcStreamBroadcaster: FixStreamStartedevent firing too soon.The
StreamStartedevent was being fired as soon as the streamming method was called, but that doesn't mean that a streamming connection was established with the server at all, which can give a false impression that the stream is active and working. Now we wait until we receive the initial metadata from the server before firing theStreamStartedevent. That should give users a better indication that the stream is actually active and working without having to wait for the first item to be received, which can take a long time for some low-frequency streams.
What's Changed
- Improve the README by @llucax in #157
- Bump pytest-asyncio from 0.26.0 to 1.0.0 by @dependabot[bot] in #159
- Bump the patch group with 6 updates by @dependabot[bot] in #160
- Bump pytest-asyncio from 1.0.0 to 1.1.0 by @dependabot[bot] in #166
- Bump the compatible group with 2 updates by @dependabot[bot] in #163
- Bump async-solipsism from 0.7 to 0.8 by @dependabot[bot] in #165
- Bump mkdocstrings[python] from 0.29.1 to 0.30.0 in the mkdocstrings group by @dependabot[bot] in #164
- Bump pydoclint from 0.6.6 to 0.6.11 by @dependabot[bot] in #170
- Bump actions/checkout from 4 to 5 by @dependabot[bot] in #171
- Bump actions/download-artifact from 4 to 5 in the artifacts group by @dependabot[bot] in #168
- Bump mkdocstrings-python from 1.16.12 to 1.18.2 in the mkdocstrings group by @dependabot[bot] in #169
- Add missing retry strategy reset in streaming by @llucax in #148
Full Changelog: v0.11.0...v0.11.1
v0.11.0
Frequenz Client Base Library Release Notes
Summary
Upgrading
-
Updated interface and behavior for HMAC
This introduces a new positional argument to
parse_grpc_uri.
If calling this function manually and passingChannelOptions, it is recommended
to switch to passingChannelOptionsvia keyword argument. -
All parameters of the Streamers
new_receivermethod are now keyword-only arguments. This means that you must specify them by name when calling the method, e.g.:recv = streamer.new_receiver(max_size=50, warn_on_overflow=True)
New Features
-
The streaming client, when using
new_receiver(include_events=True), will now return a receiver that yields stream notification events, such asStreamStarted,StreamRetrying, andStreamFatalError. This allows you to monitor the state of the stream:recv = streamer.new_receiver(include_events=True) for msg in recv: match msg: case StreamStarted(): print("Stream started") case StreamRetrying(delay, error): print(f"Stream stopped and will retry in {delay}: {error or 'closed'}") case StreamFatalError(error): print(f"Stream will stop because of a fatal error: {error}") case int() as output: print(f"Received message: {output}")
Bug Fixes
What's Changed
- Reset release notes by @florian-wagner-frequenz in #144
- Streamer: Write out events on the channels as well by @Marenz in #146
- Update release notes formatting by @Marenz in #147
- Improve streamer events by @llucax in #149
- Bump the patch group with 6 updates by @dependabot in #150
- Bump the minor group with 3 updates by @dependabot in #151
- Bump types-protobuf from 5.29.1.20250403 to 6.30.2.20250516 by @dependabot in #152
- Streaming: Make events optional by @Marenz in #154
- Change interface for HMAC by @florian-wagner-frequenz in #145
- Make parameters named of new_receiver by @Marenz in #155
Full Changelog: v0.10.0...v0.11.0
v0.10.0
Frequenz Client Base Library Release Notes
Features
- Added support for HMAC signing of
UnaryUnaryclient messages - Added support for HMAC signing of
UnaryStreamclient messages
Upgrading
- Updated
protobufdependency range: changed from>=4.21.6, <6to>=5.29.2, <7 - The minimum dependency for
typing-extensionsis now4.6.0to be compatible with Python 3.12 - The minimum dependency for
grpciois now1.59to be compatible with Python 3.12
Bug Fixes
-
Fixed keys of signature to match what fuse-rs expects
-
GrpcStreamBroadcasterwill now correctly try to restart on unexpected errors.Before if an unexpected exception was raised by the stream method, the
internal task would silently finish and never start again.
What's Changed
- Bump types-protobuf from 5.29.1.20241207 to 5.29.1.20250208 by @dependabot in #115
- Bump nox from 2024.10.9 to 2025.2.9 by @dependabot in #116
- Log when stopping
GrpcStreamBroadcasterinstances by @shsms in #118 - Upgrade
protobufdependency range from>=4.21.6, <6to>=5.29.2, <7by @camille-bouvy-frequenz in #119 - Prepare release notes for release v0.10.0 by @camille-bouvy-frequenz in #120
- Implement HMAC for metadata by @florian-wagner-frequenz in #121
- Update to repo-config v0.13.2 by @llucax in #125
- Bump the minimum dependency of
grpcioby @llucax in #132 - Bump the patch group with 5 updates by @dependabot in #126
- Bump the minor group with 6 updates by @dependabot in #127
- Bump pytest-asyncio from 0.25.3 to 0.26.0 by @dependabot in #130
- Bump pydoclint from 0.6.0 to 0.6.5 by @dependabot in #131
- Bump types-protobuf from 5.29.1.20250208 to 5.29.1.20250403 by @dependabot in #128
- Bump setuptools from 75.8.0 to 78.1.0 by @dependabot in #129
- Bump setuptools from 78.1.0 to 80.1.0 by @dependabot in #137
- Bump pydoclint from 0.6.5 to 0.6.6 by @dependabot in #135
- Bump grpc-stubs from 1.53.0.5 to 1.53.0.6 by @dependabot in #136
- Bump the patch group with 4 updates by @dependabot in #133
- Bump the minor group across 1 directory with 3 updates by @dependabot in #138
- Bring the metadata keys in line with the server by @florian-wagner-frequenz in #140
- Add interceptors for stream requests by @florian-wagner-frequenz in #142
- Fix handling of unexpected exceptions in
GrpcStreamBroadcasterby @llucax in #143
New Contributors
- @florian-wagner-frequenz made their first contribution in #121
Full Changelog: v0.9.0...v0.10.0
v0.9.0
Frequenz Client Base Library Release Notes
Upgrading
- The minimum required version of
frequenz-channelsis nowv1.6.1.
New Features
- Add the
warn_on_overflowoption to the streaming receivers to allow ignoring overflow warnings
What's Changed
- Bump the required group with 6 updates by @dependabot in #100
- Bump setuptools from 68.1.0 to 75.6.0 by @dependabot in #102
- Bump setuptools-scm[toml] from 7.1.0 to 8.1.0 by @dependabot in #101
- Apply new repo-config 0.11 templates by @llucax in #103
- Bump the required group with 2 updates by @dependabot in #104
- Bump types-markdown from 3.7.0.20240822 to 3.7.0.20241204 by @dependabot in #106
- Bump types-protobuf from 5.28.3.20241030 to 5.28.3.20241203 by @dependabot in #105
- Bump the required group with 8 updates by @dependabot in #107
- Bump the required group with 6 updates by @dependabot in #109
- Bump black from 24.10.0 to 25.1.0 by @dependabot in #110
- Bump isort from 5.13.2 to 6.0.0 by @dependabot in #111
- Add the
warn_on_overflowoption on the streaming receivers by @camille-bouvy-frequenz in #112 - Prepare release notes for release v0.9.0 by @camille-bouvy-frequenz in #113
New Contributors
- @camille-bouvy-frequenz made their first contribution in #112
Full Changelog: v0.8.1...v0.9.0
v0.8.1
Frequenz Client Base Library Release Notes
Summary
This release adds some arguments that were missing in the parse_grpc_uri() function's documentation.
What's Changed
- Clear release notes by @llucax in #97
- Remove unnecessary --platform flag in Dockerfile by @llucax in #98
- Update
parse_grpc_uridocs with keep-alive params by @shsms in #99
Full Changelog: v0.8.0...v0.8.1
v0.8.0
Frequenz Client Base Library Release Notes
Upgrading
The BaseApiClient class is generic again. There was too many issues with the new approach, so it was rolled back.
-
If you are upgrading from v0.7.x, you should be able to roll back your changes with the upgrade and just keep the new
stubproperty.# Old from __future__ import annotations import my_service_pb2_grpc class MyApiClient(BaseApiClient): def __init__(self, server_url: str, *, ...) -> None: super().__init__(server_url, ...) stub = my_service_pb2_grpc.MyServiceStub(self.channel) 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 # New from __future__ import annotations import my_service_pb2_grpc from my_service_pb2_grpc import MyServiceStub class MyApiClient(BaseApiClient[MyServiceStub]): def __init__(self, server_url: str, *, ...) -> None: super().__init__(server_url, MyServiceStub, ...) ... @property def stub(self) -> my_service_pb2_grpc.MyServiceAsyncStub: """The gRPC stub for the API.""" if self.channel is None or self._stub is None: raise ClientNotConnected(server_url=self.server_url, operation="stub") # This type: ignore is needed because we need to cast the sync stub to # the async stub, but we can't use cast because the async stub doesn't # actually exists to the eyes of the interpreter, it only exists for the # type-checker, so it can only be used for type hints. return self._stub # type: ignore
-
If you are upgrading from v0.6.x, you should only need to add the
stubproperty to your client class and then use that property instead of_stubin your code.@property def stub(self) -> my_service_pb2_grpc.MyServiceAsyncStub: """The gRPC stub for the API.""" if self.channel is None or self._stub is None: raise ClientNotConnected(server_url=self.server_url, operation="stub") # This type: ignore is needed because we need to cast the sync stub to # the async stub, but we can't use cast because the async stub doesn't # actually exists to the eyes of the interpreter, it only exists for the # type-checker, so it can only be used for type hints. return self._stub # type: ignore
What's Changed
- Clear release notes by @shsms in #94
- Bump the required group with 9 updates by @dependabot in #95
- Revert "Remove generic type from
BaseApiClient" by @llucax in #96
Full Changelog: v0.7.0...v0.8.0
v0.7.0
Frequenz Client Base Library Release Notes
Summary
This release improves the BaseApiClient interface and introduces HTTP2 keep-alive, among other changes.
Upgrading
-
GrpcStreamBroadcasternow takes aAsyncIterableinstead of aAsyncIteratoras thestream_method. This is to match the type of streaming methods generated bygrpc, so no conversion to anAsyncIteratoris needed. -
GrpcStreamBroadcasterno longer tries to reconnect when a server closes a connection. This behaviour can be overridden by passingretry_on_exhausted_stream=Truewhen constructingGrpcStreamBroadcasterinstances. -
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 customChannelOptionsasdefaultstoparse_grpc_urior aschannel_defaultstoBaseApiClient.
- The
ExponentialBackoffandLinearBackoffclasses 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
BaseApiClientclass 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 generatedXxxAsyncStubclass, which have properasynctype 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 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-membercheck frompylint, aspylintdoesn't read*.pyifiles, so it won't find theasyncstub and complain.[tool.pylint.messages_control] disable = [ # [..] # Checked by mypy "no-member", # [..] ]
After this, you should be able to remove a lot of
casts ortype: ignorefrom the code when calling the stubasyncmethods.
New Features
- Added support for HTTP2 keep-alive.
What's Changed
- Clear release notes by @shsms in #83
- Replace the
stream_methodreturn toAsyncIterableby @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
BaseApiClientby @llucax in #92 - Prepare for v0.7.0 by @shsms in #93
Full Changelog: v0.6.1...v0.7.0
v0.6.1
Frequenz Client Base Library Release Notes
Bug Fixes
- Fixes a bug in creating grpc channels from ipv6 URIs.
What's Changed
- Clear release notes by @llucax in #76
- Bump the required group with 9 updates by @dependabot in #78
- Use
netlocfromurlparseto specify the host by @shsms in #79 - Prepare release notes for v0.6.1 by @shsms in #82
Full Changelog: v0.6.0...v0.6.1
v0.6.0
Frequenz Client Base Library Release Notes
Summary
This version removes grpclib support and adds new SSL options to the connection URI.
Upgrading
-
grpclibwas removed, if you usedgrpclibyou should switch togrpcioinstead.You should also update your dependency to
frequenz-client-base(without any[grpclib]or[grpcio]suffix). Also, now there is no need to pass around the channel type to theBaseApiClientor theparse_grpc_urifunction. -
The
parse_grpc_urifunction (andBaseApiClientconstructor) now enables SSL by default (ssl=falseshould be passed to disable it). -
The
parse_grpc_uriandBaseApiClientfunction now accepts a set of defaults to use when the URI does not specify a value for a given option.
New Features
-
The connection URI can now have a few new SSL options:
ssl_root_certificates_pathto specify the path to the root certificates file.ssl_private_key_pathto specify the path to the private key file.ssl_certificate_chain_pathto specify the path to the certificate chain file.
What's Changed
- Clear release notes by @llucax in #64
- Use SSL by default by @llucax in #67
- Remove support for grpclib by @llucax in #71
- Bump the required group across 1 directory with 13 updates by @dependabot in #72
- Allow passing SSL options via server URL by @llucax in #73
- Prepare release notes for v0.6.0 by @llucax in #75
Full Changelog: v0.5.0...v0.6.0
v0.5.0
Frequenz Client Base Library Release Notes
Summary
The main features of this release is the new base class for API clients, gRPC exception wrappers and a new utility function to call stub methods.
Upgrading
channel.parse_grpc_uri()takes an extra argument, the channel type (which can be eithergrpclib.client.Channelorgrpcio.aio.Channel).
New Features
- Add a
exceptionmodule to provide client exceptions, including gRPC errors with one subclass per gRPC error status code. channel.parse_grpc_uri()can now be used withgrpciotoo.- A new
BaseApiClientclass is introduced to provide a base class for API clients. It is strongly recommended to use this class as a base class for all API clients. - A new
call_stub_method()function to simplify calling stub methods, converting gRPC errors toApiClientErrors, checking if the client is connected and optionally wrapping the response.
What's Changed
- Clear the release notes by @llucax in #53
- Add client exceptions by @llucax in #55
- Bump the required group with 7 updates by @dependabot in #57
- Add
grpciosupport toparse_grpc_uri()by @llucax in #54 - Add a
BaseApiClientclass by @llucax in #56 - Improve type-checking for
_grpchacksby @llucax in #59 - Add a function to call gRPC stubs and wrap errors by @llucax in #58
- Bump docker/build-push-action from 5 to 6 by @dependabot in #61
- Bump the required group with 9 updates by @dependabot in #60
- Bump brettcannon/check-for-changed-files from 1.2.0 to 1.2.1 by @dependabot in #62
- Prepare release notes for the 0.5 release by @llucax in #63
Full Changelog: v0.4.0...v0.5.0