Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `tilebox-datasets`: Added `delete_collection` method to `DatasetClient` to delete a collection by name.

## [0.37.1] - 2025-06-10

### Fixed
Expand Down
12 changes: 11 additions & 1 deletion tilebox-datasets/tests/test_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import xarray as xr
from attr import dataclass
from hypothesis import assume, given, settings
from hypothesis.stateful import Bundle, RuleBasedStateMachine, invariant, rule
from hypothesis.stateful import Bundle, RuleBasedStateMachine, consumes, invariant, rule
from hypothesis.strategies import lists
from promise import Promise

Expand All @@ -28,6 +28,7 @@
from tilebox.datasets.data.uuid import uuid_message_to_uuid, uuid_to_uuid_message
from tilebox.datasets.datasetsv1.collections_pb2 import (
CreateCollectionRequest,
DeleteCollectionByNameRequest,
GetCollectionByNameRequest,
ListCollectionsRequest,
)
Expand Down Expand Up @@ -291,6 +292,9 @@ def GetCollectionByName(self, req: GetCollectionByNameRequest) -> CollectionInfo
return self.collections[req.collection_name]
raise NotFoundError(f"Collection {req.collection_name} not found")

def DeleteCollectionByName(self, req: DeleteCollectionByNameRequest) -> None: # noqa: N802
del self.collections[req.collection_name]

def ListCollections(self, req: ListCollectionsRequest) -> CollectionInfosMessage: # noqa: N802
_ = req
return CollectionInfosMessage(data=list(self.collections.values()))
Expand Down Expand Up @@ -346,6 +350,12 @@ def get_collection(self, collection: CollectionClient) -> None:
got = self.dataset_client.collection(collection.name)
assert got.info() == collection.info()

@rule(collection=consumes(inserted_collections)) # consumes -> remove from bundle afterwards
def delete_collection(self, collection: CollectionClient) -> None:
self.count_collections -= 1
assert self.count_collections >= 0
self.dataset_client.delete_collection(collection.name)

@invariant()
def list_collections(self) -> None:
collections = self.dataset_client.collections()
Expand Down
8 changes: 8 additions & 0 deletions tilebox-datasets/tilebox/datasets/aio/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ async def collection(self, name: str) -> "CollectionClient":

return CollectionClient(self, info)

async def delete_collection(self, name: str) -> None:
"""Delete a collection by its name.

Args:
name: The name of the collection to delete.
"""
await self._service.delete_collection_by_name(self._dataset.id, name)

def __repr__(self) -> str:
return f"{self.name} [Timeseries Dataset]: {self._dataset.summary}"

Expand Down
14 changes: 9 additions & 5 deletions tilebox-datasets/tilebox/datasets/datasetsv1/collections_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions tilebox-datasets/tilebox/datasets/datasetsv1/collections_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ class GetCollectionByNameRequest(_message.Message):
dataset_id: _core_pb2.ID
def __init__(self, collection_name: _Optional[str] = ..., with_availability: bool = ..., with_count: bool = ..., dataset_id: _Optional[_Union[_core_pb2.ID, _Mapping]] = ...) -> None: ...

class DeleteCollectionByNameRequest(_message.Message):
__slots__ = ("collection_name", "dataset_id")
COLLECTION_NAME_FIELD_NUMBER: _ClassVar[int]
DATASET_ID_FIELD_NUMBER: _ClassVar[int]
collection_name: str
dataset_id: _core_pb2.ID
def __init__(self, collection_name: _Optional[str] = ..., dataset_id: _Optional[_Union[_core_pb2.ID, _Mapping]] = ...) -> None: ...

class DeleteCollectionByNameResponse(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...

class ListCollectionsRequest(_message.Message):
__slots__ = ("dataset_id", "with_availability", "with_count")
DATASET_ID_FIELD_NUMBER: _ClassVar[int]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ def __init__(self, channel):
request_serializer=datasets_dot_v1_dot_collections__pb2.GetCollectionByNameRequest.SerializeToString,
response_deserializer=datasets_dot_v1_dot_core__pb2.CollectionInfo.FromString,
_registered_method=True)
self.DeleteCollectionByName = channel.unary_unary(
'/datasets.v1.CollectionService/DeleteCollectionByName',
request_serializer=datasets_dot_v1_dot_collections__pb2.DeleteCollectionByNameRequest.SerializeToString,
response_deserializer=datasets_dot_v1_dot_collections__pb2.DeleteCollectionByNameResponse.FromString,
_registered_method=True)
self.ListCollections = channel.unary_unary(
'/datasets.v1.CollectionService/ListCollections',
request_serializer=datasets_dot_v1_dot_collections__pb2.ListCollectionsRequest.SerializeToString,
Expand All @@ -49,6 +54,12 @@ def GetCollectionByName(self, request, context):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def DeleteCollectionByName(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def ListCollections(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
Expand All @@ -68,6 +79,11 @@ def add_CollectionServiceServicer_to_server(servicer, server):
request_deserializer=datasets_dot_v1_dot_collections__pb2.GetCollectionByNameRequest.FromString,
response_serializer=datasets_dot_v1_dot_core__pb2.CollectionInfo.SerializeToString,
),
'DeleteCollectionByName': grpc.unary_unary_rpc_method_handler(
servicer.DeleteCollectionByName,
request_deserializer=datasets_dot_v1_dot_collections__pb2.DeleteCollectionByNameRequest.FromString,
response_serializer=datasets_dot_v1_dot_collections__pb2.DeleteCollectionByNameResponse.SerializeToString,
),
'ListCollections': grpc.unary_unary_rpc_method_handler(
servicer.ListCollections,
request_deserializer=datasets_dot_v1_dot_collections__pb2.ListCollectionsRequest.FromString,
Expand Down Expand Up @@ -139,6 +155,33 @@ def GetCollectionByName(request,
metadata,
_registered_method=True)

@staticmethod
def DeleteCollectionByName(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/datasets.v1.CollectionService/DeleteCollectionByName',
datasets_dot_v1_dot_collections__pb2.DeleteCollectionByNameRequest.SerializeToString,
datasets_dot_v1_dot_collections__pb2.DeleteCollectionByNameResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)

@staticmethod
def ListCollections(request,
target,
Expand Down
Loading
Loading