Skip to content

Commit 18eaabd

Browse files
committed
docs: update release notes for v0.4.0 API features
Signed-off-by: Mathias L. Baumann <[email protected]>
1 parent b802d77 commit 18eaabd

File tree

4 files changed

+33
-31
lines changed

4 files changed

+33
-31
lines changed

RELEASE_NOTES.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ Initial release of the Frequenz Market Metering API client for Python.
77
## New Features
88

99
- `MarketMeteringApiClient`: Main client class for connecting to the Market Metering service
10-
- `stream_samples()`: Async iterator for streaming metering samples from Market Locations
10+
- `upsert_samples()`: Bidirectional streaming for upserting metering samples.
11+
- `create_market_location()`: Create a new Market Location.
12+
- `update_market_location()`: Update an existing Market Location.
13+
- `activate_market_location()`: Activate a Market Location.
14+
- `deactivate_market_location()`: Deactivate a Market Location.
15+
- `list_market_locations()`: List Market Locations with filtering and pagination.
1116
- `stream()`: Channel-based receiver for streaming with automatic reconnection
1217
- CLI tool (`marketmetering-cli`) for quick access to metering data
1318
- Support for multiple market identifier types:

mkdocs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ plugins:
102102
- mkdocstrings:
103103
default_handler: python
104104
handlers:
105-
paths: ["src"]
106105
python:
107106
options:
107+
paths: ["src"]
108108
docstring_section_style: spacy
109109
inherited_members: true
110110
merge_init_into_class: false
@@ -116,7 +116,7 @@ plugins:
116116
show_source: true
117117
show_symbol_type_toc: true
118118
signature_crossrefs: true
119-
inventories:
119+
import:
120120
# TODO(cookiecutter): You might want to add other external references here
121121
# See https://mkdocstrings.github.io/python/usage/#import for details
122122
- https://docs.python.org/3/objects.inv

src/frequenz/client/marketmetering/_client.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@
2929
MarketLocationsFilter,
3030
MarketLocationUpdate,
3131
MetricType,
32-
MetricUnit,
3332
PaginationParams,
3433
ResamplingOptions,
3534
RevisionSelection,
3635
UpsertResult,
37-
MarketLocationSample,
3836
)
3937

4038
DEFAULT_PORT = 443
@@ -159,16 +157,12 @@ def stream_timeout(self) -> timedelta:
159157
@property
160158
def stub(self) -> marketmetering_pb2_grpc.MarketMeteringServiceStub:
161159
"""The stub for the service."""
162-
# If we have an injected mock stub (for testing), return it directly
163-
if self._stub is not None:
164-
return self._stub # type: ignore
165-
166-
if self._channel is None:
160+
if self._channel is None or self._stub is None:
167161
raise ClientNotConnected(server_url=self.server_url, operation="stub")
168162
# This type: ignore is needed because we need to cast the sync stub to
169163
# the async stub, but we can't use cast because the async stub doesn't
170164
# actually exist to the eyes of the interpreter.
171-
return self._stub # type: ignore
165+
return self._stub # type: ignore[return-value]
172166

173167
async def create_market_location(
174168
self,
@@ -186,7 +180,7 @@ async def create_market_location(
186180
market_location_ref=market_location_ref.to_protobuf(),
187181
market_location=market_location.to_protobuf(),
188182
)
189-
await self.stub.CreateMarketLocation(
183+
await self.stub.CreateMarketLocation( # type: ignore[misc]
190184
request,
191185
timeout=self._call_timeout_seconds,
192186
)
@@ -209,7 +203,7 @@ async def update_market_location(
209203
update_fields=update_pb,
210204
update_mask=update_mask_pb,
211205
)
212-
await self.stub.UpdateMarketLocation(
206+
await self.stub.UpdateMarketLocation( # type: ignore[misc]
213207
request,
214208
timeout=self._call_timeout_seconds,
215209
)
@@ -227,7 +221,7 @@ async def activate_market_location(
227221
request = pb.ActivateMarketLocationRequest(
228222
market_location_refs=[market_location_ref.to_protobuf()],
229223
)
230-
await self.stub.ActivateMarketLocation(
224+
await self.stub.ActivateMarketLocation( # type: ignore[misc]
231225
request,
232226
timeout=self._call_timeout_seconds,
233227
)
@@ -245,7 +239,7 @@ async def deactivate_market_location(
245239
request = pb.DeactivateMarketLocationRequest(
246240
market_location_refs=[market_location_ref.to_protobuf()],
247241
)
248-
await self.stub.DeactivateMarketLocation(
242+
await self.stub.DeactivateMarketLocation( # type: ignore[misc]
249243
request,
250244
timeout=self._call_timeout_seconds,
251245
)
@@ -280,7 +274,7 @@ async def list_market_locations(
280274
pagination_params.to_protobuf() if pagination_params else None
281275
),
282276
)
283-
response = await self.stub.ListMarketLocations(
277+
response = await self.stub.ListMarketLocations( # type: ignore[misc]
284278
request,
285279
timeout=self._call_timeout_seconds,
286280
)
@@ -311,9 +305,9 @@ async def upsert_samples(
311305
UpsertResult objects indicating success or failure for each sample.
312306
"""
313307

314-
async def request_generator() -> AsyncIterator[
315-
pb.UpsertMarketLocationSamplesStreamRequest
316-
]:
308+
async def request_generator() -> (
309+
AsyncIterator[pb.UpsertMarketLocationSamplesStreamRequest]
310+
):
317311
async for ml_ref, series in samples_stream:
318312
for sample in series.samples:
319313
yield pb.UpsertMarketLocationSamplesStreamRequest(
@@ -326,7 +320,7 @@ async def request_generator() -> AsyncIterator[
326320

327321
response_stream = cast(
328322
AsyncIterator[pb.UpsertMarketLocationSamplesStreamResponse],
329-
self.stub.UpsertMarketLocationSamplesStream(
323+
self.stub.UpsertMarketLocationSamplesStream( # type: ignore[arg-type]
330324
request_generator(),
331325
timeout=self._stream_timeout_seconds,
332326
),

src/frequenz/client/marketmetering/types.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
pagination_params_pb2 as pagination_params_pb,
1313
)
1414
from frequenz.api.marketmetering.v1alpha1 import marketmetering_pb2 as pb
15-
from google.protobuf import struct_pb2
16-
from google.protobuf import field_mask_pb2
15+
from google.protobuf import field_mask_pb2, struct_pb2
1716
from google.protobuf.timestamp_pb2 import Timestamp
1817

1918

@@ -265,11 +264,11 @@ class DataQuality(Enum):
265264
MISSING = pb.DATA_QUALITY_MISSING
266265
"""No valid value is available for this interval."""
267266

268-
def to_protobuf(self) -> pb.DataQuality:
267+
def to_protobuf(self) -> int:
269268
"""Convert to protobuf message.
270269
271270
Returns:
272-
The protobuf representation.
271+
The protobuf representation (integer enum value).
273272
"""
274273
return self.value
275274

@@ -691,11 +690,13 @@ def from_protobuf(
691690
# Here we assume it's always present or defaults to 0.
692691
revision=pb_obj.revision,
693692
update_time=update_time,
694-
resampling_method=ResamplingMethod(pb_obj.resampling_method)
695-
if isinstance(pb_obj, pb.MarketLocationSampleDetail)
696-
# Fallback to UNSPECIFIED if it's a simple MarketLocationSample
697-
# which does not have this field.
698-
else ResamplingMethod.UNSPECIFIED,
693+
resampling_method=(
694+
ResamplingMethod(pb_obj.resampling_method)
695+
if isinstance(pb_obj, pb.MarketLocationSampleDetail)
696+
# Fallback to UNSPECIFIED if it's a simple MarketLocationSample
697+
# which does not have this field.
698+
else ResamplingMethod.UNSPECIFIED
699+
),
699700
)
700701

701702
def to_protobuf(self) -> pb.MarketLocationSample:
@@ -704,12 +705,14 @@ def to_protobuf(self) -> pb.MarketLocationSample:
704705
Returns:
705706
The protobuf representation.
706707
"""
707-
return pb.MarketLocationSample(
708+
sample = pb.MarketLocationSample(
708709
sample_time=_datetime_to_timestamp(self.sample_time),
709710
value=self.value,
710711
quality=self.quality.value,
711-
revision=self.revision,
712712
)
713+
if self.revision is not None:
714+
sample.revision = self.revision
715+
return sample
713716

714717

715718
@dataclass(frozen=True)

0 commit comments

Comments
 (0)