Skip to content

Commit 21a75dd

Browse files
Initial client
Signed-off-by: Flora <[email protected]>
1 parent 0c14015 commit 21a75dd

File tree

5 files changed

+177
-3
lines changed

5 files changed

+177
-3
lines changed

RELEASE_NOTES.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22

33
## Summary
44

5-
<!-- Here goes a general summary of what this release is about -->
5+
This release introduces the initial version of the Assets API client, enabling retrieval of asset-related data.
66

77
## Upgrading
88

99
<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->
1010

1111
## New Features
1212

13-
<!-- Here goes the main new features and examples or instructions on how to use them -->
13+
Introducing the initial version of the Assets API client, designed to streamline access to asset-related data.
14+
15+
* Supports querying asset components and retrieving their metrics efficiently.
16+
* Provides a structured data representation while retaining raw protobuf responses.
17+
* Currently focused on retrieving asset data for individual components.
18+
* Examples are provided to guide users through the basic usage of the client.
1419

1520
## Bug Fixes
1621

examples/client.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# License: MIT
2+
# Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3+
4+
"""Examples usage of PlatformAssets API."""
5+
6+
import argparse
7+
import asyncio
8+
from pprint import pprint
9+
10+
from frequenz.client.assets import AssetsApiClient
11+
12+
13+
async def main(microgrid_id: int) -> None:
14+
"""Test the AssetsApiClient.
15+
16+
Args:
17+
microgrid_id: The ID of the microgrid to query.
18+
"""
19+
server_url = "localhost:50052"
20+
client = AssetsApiClient(server_url)
21+
22+
print("########################################################")
23+
print("Fetching microgrid details")
24+
25+
microgrid_details = await client.get_microgrid(microgrid_id)
26+
pprint(microgrid_details)
27+
28+
print("########################################################")
29+
print("Listing microgrid components")
30+
31+
components = await client.list_microgrid_components(microgrid_id)
32+
pprint(components)
33+
34+
print("########################################################")
35+
print("Listing microgrid component connections")
36+
37+
connections = await client.list_microgrid_component_connections(microgrid_id)
38+
pprint(connections)
39+
40+
41+
if __name__ == "__main__":
42+
parser = argparse.ArgumentParser()
43+
parser.add_argument("microgrid_id", type=int, help="Microgrid ID")
44+
45+
args = parser.parse_args()
46+
asyncio.run(main(args.microgrid_id))

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ classifiers = [
2727
requires-python = ">= 3.11, < 4"
2828
dependencies = [
2929
"typing-extensions >= 4.12.2, < 5",
30+
"frequenz-api-assets >= 0.0.1, < 1",
31+
"frequenz-client-common >= 0.3.0, < 1",
32+
"frequenz-client-base >= 0.9.0, < 1",
3033
]
3134
dynamic = ["version"]
3235

@@ -82,6 +85,10 @@ dev = [
8285
"frequenz-client-assets[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
8386
]
8487

88+
examples = [
89+
"grpcio >= 1.51.1, < 2",
90+
]
91+
8592
[project.urls]
8693
Documentation = "https://frequenz-floss.github.io/frequenz-client-assets-python/"
8794
Changelog = "https://github.com/frequenz-floss/frequenz-client-assets-python/releases"

src/frequenz/client/assets/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ def delete_me(*, blow_up: bool = False) -> bool:
1313
1414
Returns:
1515
True if no exception was raised.
16-
1716
Raises:
1817
RuntimeError: if blow_up is True.
1918
"""
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# License: MIT
2+
# Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3+
4+
"""Client for requests to the PlatformAssets API."""
5+
6+
from typing import Iterable, Optional
7+
8+
# pylint: disable=no-name-in-module
9+
from frequenz.api.assets.v1.assets_pb2 import (
10+
GetMicrogridRequest as PBGetMicrogridRequest,
11+
)
12+
from frequenz.api.assets.v1.assets_pb2 import (
13+
GetMicrogridResponse as PBGetMicrogridResponse,
14+
)
15+
from frequenz.api.assets.v1.assets_pb2 import (
16+
ListMicrogridComponentConnectionsRequest as PBListMicrogridComponentConnectionsRequest,
17+
)
18+
from frequenz.api.assets.v1.assets_pb2 import (
19+
ListMicrogridComponentConnectionsResponse as PBListMicrogridComponentConnectionsResponse,
20+
)
21+
from frequenz.api.assets.v1.assets_pb2 import (
22+
ListMicrogridComponentsRequest as PBListMicrogridComponentsRequest,
23+
)
24+
from frequenz.api.assets.v1.assets_pb2 import (
25+
ListMicrogridComponentsResponse as PBListMicrogridComponentsResponse,
26+
)
27+
from frequenz.api.assets.v1.assets_pb2_grpc import PlatformAssetsStub
28+
from frequenz.api.common.v1.microgrid.components.components_pb2 import (
29+
ComponentCategory as PBComponentCategory,
30+
)
31+
from frequenz.client.base.client import BaseApiClient, call_stub_method
32+
from frequenz.client.base.exception import ClientNotConnected
33+
34+
# pylint: enable=no-name-in-module
35+
36+
37+
class AssetsApiClient(BaseApiClient[PlatformAssetsStub]):
38+
"""A client for the Frequenz PlatformAssets service."""
39+
40+
def __init__(self, server_url: str, *, connect: bool = True) -> None:
41+
"""Initialize the client.
42+
43+
Args:
44+
server_url: The URL of the PlatformAssets service.
45+
connect: Whether to establish a connection immediately.
46+
"""
47+
super().__init__(server_url, PlatformAssetsStub, connect=connect)
48+
49+
@property
50+
def stub(self) -> PlatformAssetsStub:
51+
"""Return the gRPC stub for the PlatformAssets service."""
52+
if self.channel is None or self._stub is None:
53+
raise ClientNotConnected(server_url=self.server_url, operation="stub")
54+
return self._stub
55+
56+
async def get_microgrid(self, microgrid_id: int) -> PBGetMicrogridResponse:
57+
"""Fetch details of a specific microgrid.
58+
59+
Args:
60+
microgrid_id: The ID of the microgrid to fetch.
61+
62+
Returns:
63+
The response containing the microgrid details.
64+
"""
65+
request = PBGetMicrogridRequest(microgrid_id=microgrid_id)
66+
return await call_stub_method(self, lambda: self.stub.GetMicrogrid(request))
67+
68+
async def list_microgrid_components(
69+
self,
70+
microgrid_id: int,
71+
component_ids: Optional[list[int]] | None,
72+
categories: Optional[Iterable[PBComponentCategory]] | None,
73+
) -> PBListMicrogridComponentsResponse:
74+
"""List electrical components of a microgrid.
75+
76+
Args:
77+
microgrid_id: The ID of the microgrid to fetch components for.
78+
component_ids: The IDs of the components to fetch.
79+
categories: The categories of the components to fetch.
80+
81+
Returns:
82+
The response containing the microgrid components.
83+
"""
84+
request = PBListMicrogridComponentsRequest(
85+
microgrid_id=microgrid_id,
86+
component_ids=component_ids,
87+
categories=categories,
88+
)
89+
return await call_stub_method(
90+
self, lambda: self.stub.ListMicrogridComponents(request)
91+
)
92+
93+
async def list_microgrid_component_connections(
94+
self,
95+
microgrid_id: int,
96+
source_component_ids: Optional[list[int]] | None,
97+
destination_component_ids: Optional[list[int]] | None,
98+
) -> PBListMicrogridComponentConnectionsResponse:
99+
"""List electrical connections between components in a microgrid.
100+
101+
Args:
102+
microgrid_id: The ID of the microgrid to fetch component connections for.
103+
source_component_ids: The IDs of the source components to fetch connections for.
104+
destination_component_ids: The IDs of the destination components to fetch
105+
connections for.
106+
107+
Returns:
108+
The response containing the component connections.
109+
"""
110+
request = PBListMicrogridComponentConnectionsRequest(
111+
microgrid_id=microgrid_id,
112+
source_component_ids=source_component_ids,
113+
destination_component_ids=destination_component_ids,
114+
)
115+
return await call_stub_method(
116+
self, lambda: self.stub.ListMicrogridComponentConnections(request)
117+
)

0 commit comments

Comments
 (0)