-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add data set management methods (#54)
- Loading branch information
Showing
11 changed files
with
350 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
2.0.2 | ||
2.1.0 |
37 changes: 37 additions & 0 deletions
37
exabel_data_sdk/client/api/api_client/data_set_api_client.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from abc import ABC, abstractmethod | ||
|
||
from exabel_data_sdk.stubs.exabel.api.data.v1.all_pb2 import ( | ||
CreateDataSetRequest, | ||
DataSet, | ||
DeleteDataSetRequest, | ||
GetDataSetRequest, | ||
ListDataSetsRequest, | ||
ListDataSetsResponse, | ||
UpdateDataSetRequest, | ||
) | ||
|
||
|
||
class DataSetApiClient(ABC): | ||
""" | ||
Superclass for clients that send data set requests to the Exabel Data API. | ||
""" | ||
|
||
@abstractmethod | ||
def list_data_sets(self, request: ListDataSetsRequest) -> ListDataSetsResponse: | ||
"""List all data sets.""" | ||
|
||
@abstractmethod | ||
def get_data_set(self, request: GetDataSetRequest) -> DataSet: | ||
"""Get a data set.""" | ||
|
||
@abstractmethod | ||
def create_data_set(self, request: CreateDataSetRequest) -> DataSet: | ||
"""Create a data set.""" | ||
|
||
@abstractmethod | ||
def update_data_set(self, request: UpdateDataSetRequest) -> DataSet: | ||
"""Update a data set.""" | ||
|
||
@abstractmethod | ||
def delete_data_set(self, request: DeleteDataSetRequest) -> None: | ||
"""Delete a data set.""" |
44 changes: 44 additions & 0 deletions
44
exabel_data_sdk/client/api/api_client/grpc/data_set_grpc_client.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from exabel_data_sdk.client.api.api_client.data_set_api_client import DataSetApiClient | ||
from exabel_data_sdk.client.api.api_client.grpc.base_grpc_client import BaseGrpcClient | ||
from exabel_data_sdk.client.api.error_handler import handle_grpc_error | ||
from exabel_data_sdk.client.client_config import ClientConfig | ||
from exabel_data_sdk.stubs.exabel.api.data.v1.all_pb2 import ( | ||
CreateDataSetRequest, | ||
DataSet, | ||
DeleteDataSetRequest, | ||
GetDataSetRequest, | ||
ListDataSetsRequest, | ||
ListDataSetsResponse, | ||
UpdateDataSetRequest, | ||
) | ||
from exabel_data_sdk.stubs.exabel.api.data.v1.all_pb2_grpc import DataSetServiceStub | ||
|
||
|
||
class DataSetGrpcClient(DataSetApiClient, BaseGrpcClient): | ||
""" | ||
Client which sends data set requests to the Exabel Data API with gRPC. | ||
""" | ||
|
||
def __init__(self, config: ClientConfig): | ||
super().__init__(config) | ||
self.stub = DataSetServiceStub(self.channel) | ||
|
||
@handle_grpc_error | ||
def list_data_sets(self, request: ListDataSetsRequest) -> ListDataSetsResponse: | ||
return self.stub.ListDataSets(request, metadata=self.metadata, timeout=self.config.timeout) | ||
|
||
@handle_grpc_error | ||
def get_data_set(self, request: GetDataSetRequest) -> DataSet: | ||
return self.stub.GetDataSet(request, metadata=self.metadata, timeout=self.config.timeout) | ||
|
||
@handle_grpc_error | ||
def create_data_set(self, request: CreateDataSetRequest) -> DataSet: | ||
return self.stub.CreateDataSet(request, metadata=self.metadata, timeout=self.config.timeout) | ||
|
||
@handle_grpc_error | ||
def update_data_set(self, request: UpdateDataSetRequest) -> DataSet: | ||
return self.stub.UpdateDataSet(request, metadata=self.metadata, timeout=self.config.timeout) | ||
|
||
@handle_grpc_error | ||
def delete_data_set(self, request: DeleteDataSetRequest) -> None: | ||
return self.stub.DeleteDataSet(request, metadata=self.metadata, timeout=self.config.timeout) |
32 changes: 32 additions & 0 deletions
32
exabel_data_sdk/client/api/api_client/http/data_set_http_client.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from exabel_data_sdk.client.api.api_client.data_set_api_client import DataSetApiClient | ||
from exabel_data_sdk.client.api.api_client.http.base_http_client import BaseHttpClient | ||
from exabel_data_sdk.stubs.exabel.api.data.v1.all_pb2 import ( | ||
CreateDataSetRequest, | ||
DataSet, | ||
DeleteDataSetRequest, | ||
GetDataSetRequest, | ||
ListDataSetsRequest, | ||
ListDataSetsResponse, | ||
UpdateDataSetRequest, | ||
) | ||
|
||
|
||
class DataSetHttpClient(DataSetApiClient, BaseHttpClient): | ||
""" | ||
Client which sends data set requests to the Exabel Data API with JSON over gRPC. | ||
""" | ||
|
||
def list_data_sets(self, request: ListDataSetsRequest) -> ListDataSetsResponse: | ||
return self._request("GET", "dataSets", ListDataSetsResponse()) | ||
|
||
def get_data_set(self, request: GetDataSetRequest) -> DataSet: | ||
return self._request("GET", request.name, DataSet()) | ||
|
||
def create_data_set(self, request: CreateDataSetRequest) -> DataSet: | ||
return self._request("POST", "dataSets", DataSet(), body=request.data_set) | ||
|
||
def update_data_set(self, request: UpdateDataSetRequest) -> DataSet: | ||
return self._request("PATCH", "dataSets", DataSet(), body=request.data_set) | ||
|
||
def delete_data_set(self, request: DeleteDataSetRequest) -> None: | ||
return self._request("DELETE", request.name, None) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from typing import Sequence | ||
|
||
from exabel_data_sdk.stubs.exabel.api.data.v1.all_pb2 import DataSet as ProtoDataSet | ||
|
||
|
||
class DataSet: | ||
""" | ||
A data set resource in the Data API. | ||
Attributes: | ||
name (str): The resource name of the data set, for example "dataSets/ns.mydata". | ||
display_name (str): The display name of the data set. | ||
description (str): One or more paragraphs of text description. | ||
signals ([str]): Resource names of signals this data set contains. | ||
read_only (bool): Whether this resource is read only. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
name: str, | ||
display_name: str, | ||
description: str = "", | ||
signals: Sequence[str] = None, | ||
read_only: bool = False, | ||
): | ||
""" | ||
Create a data set resource in the Data API. | ||
Args: | ||
name (str): The resource name of the data set, for example "dataSets/ns.mydata". | ||
display_name: The display name of the data set. | ||
description: One or more paragraphs of text description. | ||
signals: Resource names of signals this data set contains. | ||
read_only: Whether this resource is read only. | ||
""" | ||
self.name = name | ||
self.display_name = display_name | ||
self.description = description | ||
self.read_only = read_only | ||
self.signals = signals or [] | ||
|
||
@staticmethod | ||
def from_proto(data_set: ProtoDataSet) -> "DataSet": | ||
"""Create an DataSet from the given protobuf DataSet.""" | ||
return DataSet( | ||
name=data_set.name, | ||
display_name=data_set.display_name, | ||
description=data_set.description, | ||
signals=list(data_set.signals), | ||
read_only=data_set.read_only, | ||
) | ||
|
||
def to_proto(self) -> ProtoDataSet: | ||
"""Create a protobuf DataSet from this DataSet.""" | ||
return ProtoDataSet( | ||
name=self.name, | ||
display_name=self.display_name, | ||
description=self.description, | ||
signals=self.signals if self.signals else None, | ||
) | ||
|
||
def __eq__(self, other: object) -> bool: | ||
if not isinstance(other, DataSet): | ||
return False | ||
return ( | ||
self.name == other.name | ||
and self.display_name == other.display_name | ||
and self.description == other.description | ||
and self.read_only == other.read_only | ||
and sorted(self.signals) == sorted(other.signals) | ||
) | ||
|
||
def __repr__(self) -> str: | ||
return ( | ||
f"DataSet(name='{self.name}', display_name='{self.display_name}', " | ||
f"description='{self.description}', signals={self.signals}, " | ||
f"read_only={self.read_only})" | ||
) | ||
|
||
def __lt__(self, other: object) -> bool: | ||
if not isinstance(other, DataSet): | ||
raise ValueError(f"Cannot compare DataSet to non-DataSet: {other}") | ||
return self.name < other.name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from typing import Optional, Sequence | ||
|
||
from google.protobuf.field_mask_pb2 import FieldMask | ||
|
||
from exabel_data_sdk.client.api.api_client.grpc.data_set_grpc_client import DataSetGrpcClient | ||
from exabel_data_sdk.client.api.api_client.http.data_set_http_client import DataSetHttpClient | ||
from exabel_data_sdk.client.api.data_classes.data_set import DataSet | ||
from exabel_data_sdk.client.api.data_classes.request_error import ErrorType, RequestError | ||
from exabel_data_sdk.client.client_config import ClientConfig | ||
from exabel_data_sdk.stubs.exabel.api.data.v1.data_set_service_pb2 import ( | ||
CreateDataSetRequest, | ||
DeleteDataSetRequest, | ||
GetDataSetRequest, | ||
ListDataSetsRequest, | ||
UpdateDataSetRequest, | ||
) | ||
|
||
|
||
class DataSetApi: | ||
""" | ||
API class for data set CRUD operations. | ||
""" | ||
|
||
def __init__(self, config: ClientConfig, use_json: bool = False): | ||
self.client = (DataSetHttpClient if use_json else DataSetGrpcClient)(config) | ||
|
||
def list_data_sets(self) -> Sequence[DataSet]: | ||
""" | ||
List all data sets. | ||
""" | ||
response = self.client.list_data_sets(ListDataSetsRequest()) | ||
return [DataSet.from_proto(d) for d in response.data_sets] | ||
|
||
def get_data_set(self, name: str) -> Optional[DataSet]: | ||
""" | ||
Get one data set. | ||
Return None if the data set does not exist. | ||
Args: | ||
name: The resource name of the requested data set, for example | ||
"dataSet/123". | ||
""" | ||
try: | ||
response = self.client.get_data_set(GetDataSetRequest(name=name)) | ||
except RequestError as error: | ||
if error.error_type == ErrorType.NOT_FOUND: | ||
return None | ||
raise | ||
return DataSet.from_proto(response) | ||
|
||
def create_data_set(self, data_set: DataSet) -> DataSet: | ||
""" | ||
Create a data set. | ||
Args: | ||
data_set: The data set to create. | ||
""" | ||
response = self.client.create_data_set(CreateDataSetRequest(data_set=data_set.to_proto())) | ||
return DataSet.from_proto(response) | ||
|
||
def update_data_set(self, data_set: DataSet, update_mask: FieldMask = None) -> DataSet: | ||
""" | ||
Update a data set. | ||
Args: | ||
data_set: The data set to update. | ||
update_mask: The fields to update. If not specified, the update behaves as a | ||
full update, overwriting all existing fields and properties. | ||
""" | ||
response = self.client.update_data_set( | ||
UpdateDataSetRequest(data_set=data_set.to_proto(), update_mask=update_mask) | ||
) | ||
return DataSet.from_proto(response) | ||
|
||
def delete_data_set(self, data_set: str) -> None: | ||
""" | ||
Delete a data set. | ||
Args: | ||
data_set: The data set to delete. | ||
""" | ||
self.client.delete_data_set(DeleteDataSetRequest(name=data_set)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 10 additions & 2 deletions
12
exabel_data_sdk/stubs/exabel/api/data/v1/data_set_messages_pb2.py
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.