Skip to content

Commit dd929bf

Browse files
committed
Merge branch 'main' of https://github.com/weaviate/weaviate-python-client into dev/1.32
2 parents a6a4254 + bb6d90d commit dd929bf

6 files changed

Lines changed: 153 additions & 29 deletions

File tree

integration/test_tenants.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,3 +504,24 @@ def test_tenants_auto_tenant_creation(
504504
collection=collection.name, properties={"name": "some name"}, tenant=f"tenant-{i}"
505505
)
506506
assert len(client.batch.failed_objects) == 0
507+
508+
509+
def test_tenants_deactivate_then_activate(collection_factory: CollectionFactory) -> None:
510+
collection = collection_factory(
511+
properties=[Property(name="name", data_type=DataType.TEXT)],
512+
vectorizer_config=Configure.Vectorizer.none(),
513+
multi_tenancy_config=Configure.multi_tenancy(enabled=True),
514+
)
515+
516+
t = Tenant(name="tenant1")
517+
collection.tenants.create([t])
518+
tenant1 = collection.with_tenant(t)
519+
520+
tenant1.data.insert(properties={"name": "some name"})
521+
assert tenant1.query.fetch_objects().objects[0].properties["name"] == "some name"
522+
523+
collection.tenants.deactivate(t)
524+
assert collection.tenants.get()["tenant1"].activity_status == TenantActivityStatus.INACTIVE
525+
526+
collection.tenants.activate(t)
527+
assert tenant1.query.fetch_objects().objects[0].properties["name"] == "some name"

requirements-devel.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ importlib_metadata==8.7.0
2020
tomli==2.2.1
2121
types-protobuf==6.30.2.20250703
2222
types-urllib3==1.26.25.14
23-
typing_extensions==4.14.0
23+
typing_extensions==4.14.1
2424

2525
pre-commit
2626
flake8
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Dict, Optional, Sequence, Union
22

3-
from weaviate.collections.classes.tenants import Tenant
43
from weaviate.collections.tenants.types import (
54
TenantCreateInputType,
5+
TenantInputType,
66
TenantOutputType,
77
TenantUpdateInputType,
88
)
@@ -14,13 +14,18 @@ class _TenantsAsync(_TenantsExecutor[ConnectionAsync]):
1414
async def create(
1515
self, tenants: Union[TenantCreateInputType, Sequence[TenantCreateInputType]]
1616
) -> None: ...
17-
async def remove(self, tenants: Union[str, Tenant, Sequence[Union[str, Tenant]]]) -> None: ...
17+
async def remove(self, tenants: Union[TenantInputType, Sequence[TenantInputType]]) -> None: ...
1818
async def get(self) -> Dict[str, TenantOutputType]: ...
1919
async def get_by_names(
20-
self, tenants: Sequence[Union[str, Tenant]]
20+
self, tenants: Sequence[TenantInputType]
2121
) -> Dict[str, TenantOutputType]: ...
22-
async def get_by_name(self, tenant: Union[str, Tenant]) -> Optional[TenantOutputType]: ...
22+
async def get_by_name(self, tenant: TenantInputType) -> Optional[TenantOutputType]: ...
2323
async def update(
2424
self, tenants: Union[TenantUpdateInputType, Sequence[TenantUpdateInputType]]
2525
) -> None: ...
26-
async def exists(self, tenant: Union[str, Tenant]) -> bool: ...
26+
async def exists(self, tenant: TenantInputType) -> bool: ...
27+
async def activate(self, tenant: Union[TenantInputType, Sequence[TenantInputType]]) -> None: ...
28+
async def deactivate(
29+
self, tenant: Union[TenantInputType, Sequence[TenantInputType]]
30+
) -> None: ...
31+
async def offload(self, tenant: Union[TenantInputType, Sequence[TenantInputType]]) -> None: ...

weaviate/collections/tenants/executor.py

Lines changed: 112 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from weaviate.collections.grpc.tenants import _TenantsGRPC
1717
from weaviate.collections.tenants.types import (
1818
TenantCreateInputType,
19+
TenantInputType,
1920
TenantOutputType,
2021
TenantUpdateInputType,
2122
)
@@ -47,7 +48,7 @@ def create(
4748
self,
4849
tenants: Union[TenantCreateInputType, Sequence[TenantCreateInputType]],
4950
) -> executor.Result[None]:
50-
"""Create the specified tenants for a collection in Weaviate.
51+
"""Create the specified tenants for this collection in Weaviate.
5152
5253
The collection must have been created with multi-tenancy enabled.
5354
@@ -94,9 +95,9 @@ def resp(res: Response) -> None:
9495

9596
def remove(
9697
self,
97-
tenants: Union[str, Tenant, Sequence[Union[str, Tenant]]],
98+
tenants: Union[TenantInputType, Sequence[TenantInputType]],
9899
) -> executor.Result[None]:
99-
"""Remove the specified tenants from a collection in Weaviate.
100+
"""Remove the specified tenants from this collection in Weaviate.
100101
101102
The collection must have been created with multi-tenancy enabled.
102103
@@ -170,7 +171,7 @@ def resp(res: Response) -> Dict[str, TenantOutputType]:
170171
)
171172

172173
def __get_with_grpc(
173-
self, *, tenants: Optional[Sequence[Union[str, Tenant]]] = None
174+
self, *, tenants: Optional[Sequence[TenantInputType]] = None
174175
) -> executor.Result[Dict[str, TenantOutputType]]:
175176
names = (
176177
[tenant.name if isinstance(tenant, Tenant) else tenant for tenant in tenants]
@@ -228,7 +229,7 @@ def __map_update_tenant(self, tenant: TenantUpdateInputType) -> TenantUpdate:
228229

229230
def __map_create_tenants(
230231
self,
231-
tenants: Union[str, Tenant, TenantCreate, Sequence[Union[str, Tenant, TenantCreate]]],
232+
tenants: Union[TenantCreateInputType, Sequence[TenantCreateInputType]],
232233
) -> List[dict]:
233234
if (
234235
isinstance(tenants, str)
@@ -260,7 +261,7 @@ def __map_update_tenants(
260261
]
261262

262263
def get(self) -> executor.Result[Dict[str, TenantOutputType]]:
263-
"""Return all tenants currently associated with a collection in Weaviate.
264+
"""Return all tenants currently associated with this collection in Weaviate.
264265
265266
The collection must have been created with multi-tenancy enabled.
266267
@@ -282,9 +283,9 @@ def resp(res: Dict[str, TenantOutputType]) -> Dict[str, TenantOutputType]:
282283
)
283284

284285
def get_by_names(
285-
self, tenants: Sequence[Union[str, Tenant]]
286+
self, tenants: Sequence[TenantInputType]
286287
) -> executor.Result[Dict[str, TenantOutputType]]:
287-
"""Return named tenants currently associated with a collection in Weaviate.
288+
"""Return named tenants currently associated with this collection in Weaviate.
288289
289290
If the tenant does not exist, it will not be included in the response.
290291
If no names are provided, all tenants will be returned.
@@ -308,10 +309,8 @@ def get_by_names(
308309
)
309310
return self.__get_with_grpc(tenants=tenants)
310311

311-
def get_by_name(
312-
self, tenant: Union[str, Tenant]
313-
) -> executor.Result[Optional[TenantOutputType]]:
314-
"""Return a specific tenant associated with a collection in Weaviate.
312+
def get_by_name(self, tenant: TenantInputType) -> executor.Result[Optional[TenantOutputType]]:
313+
"""Return a specific tenant associated with this collection in Weaviate.
315314
316315
If the tenant does not exist, `None` will be returned.
317316
@@ -405,7 +404,7 @@ def update(
405404
self,
406405
tenants: Union[TenantUpdateInputType, Sequence[TenantUpdateInputType]],
407406
) -> executor.Result[None]:
408-
"""Update the specified tenants for a collection in Weaviate.
407+
"""Update the specified tenants for this collection in Weaviate.
409408
410409
The collection must have been created with multi-tenancy enabled.
411410
@@ -432,8 +431,8 @@ def update(
432431
)
433432
return self.__update(tenants=tenants)
434433

435-
def exists(self, tenant: Union[str, Tenant]) -> executor.Result[bool]:
436-
"""Check if a tenant exists for a collection in Weaviate.
434+
def exists(self, tenant: TenantInputType) -> executor.Result[bool]:
435+
"""Check if a tenant exists for this collection in Weaviate.
437436
438437
The collection must have been created with multi-tenancy enabled.
439438
@@ -451,7 +450,7 @@ def exists(self, tenant: Union[str, Tenant]) -> executor.Result[bool]:
451450
if self._validate_arguments:
452451
_validate_input(
453452
_ValidateArgument(
454-
expected=[str, Tenant, Sequence[Union[str, Tenant]]],
453+
expected=[str, Tenant],
455454
name="tenant",
456455
value=tenant,
457456
)
@@ -471,3 +470,100 @@ def resp(res: Response) -> bool:
471470
ok_in=[200, 404], error=f"Check if tenant exists for {self._name}"
472471
), # allow 404 to perform bool check on response code
473472
)
473+
474+
def __update_tenant_activity_status(
475+
self,
476+
tenant: Union[TenantInputType, Sequence[TenantInputType]],
477+
activity_status: TenantUpdateActivityStatus,
478+
) -> executor.Result[None]:
479+
if self._validate_arguments:
480+
_validate_input(
481+
_ValidateArgument(
482+
expected=[
483+
str,
484+
Tenant,
485+
Sequence[Union[str, Tenant]],
486+
],
487+
name="tenant",
488+
value=tenant,
489+
)
490+
)
491+
if isinstance(tenant, str) or isinstance(tenant, Tenant):
492+
tenants = [
493+
TenantUpdate(
494+
name=tenant.name if isinstance(tenant, Tenant) else tenant,
495+
activity_status=activity_status,
496+
)
497+
]
498+
else:
499+
tenants = [
500+
TenantUpdate(
501+
name=t.name if isinstance(t, Tenant) else t,
502+
activity_status=activity_status,
503+
)
504+
for t in tenant
505+
]
506+
return self.__update(tenants=tenants)
507+
508+
def activate(
509+
self, tenant: Union[TenantInputType, Sequence[TenantInputType]]
510+
) -> executor.Result[None]:
511+
"""Activate the specified tenants for this collection in Weaviate.
512+
513+
The collection must have been created with multi-tenancy enabled.
514+
515+
Args:
516+
tenant: A tenant name, `wvc.config.tenants.Tenant` object, or a list of tenants names
517+
and/or `wvc.config.tenants.Tenant` objects to activate for the given collection.
518+
519+
Raises:
520+
weaviate.exceptions.WeaviateConnectionError: If the network connection to Weaviate fails.
521+
weaviate.exceptions.UnexpectedStatusCodeError: If Weaviate reports a non-OK status.
522+
weaviate.exceptions.WeaviateInvalidInputError: If `tenant` is not a list of `wvc.Tenant` objects.
523+
"""
524+
self.__update_tenant_activity_status(
525+
tenant=tenant,
526+
activity_status=TenantUpdateActivityStatus.ACTIVE,
527+
)
528+
529+
def deactivate(
530+
self, tenant: Union[TenantInputType, Sequence[TenantInputType]]
531+
) -> executor.Result[None]:
532+
"""Deactivate the specified tenants for this collection in Weaviate.
533+
534+
The collection must have been created with multi-tenancy enabled.
535+
536+
Args:
537+
tenant: A tenant name, `wvc.config.tenants.Tenant` object, or a list of tenants names
538+
and/or `wvc.config.tenants.Tenant` objects to deactivate for the given collection.
539+
540+
Raises:
541+
weaviate.exceptions.WeaviateConnectionError: If the network connection to Weaviate fails.
542+
weaviate.exceptions.UnexpectedStatusCodeError: If Weaviate reports a non-OK status.
543+
weaviate.exceptions.WeaviateInvalidInputError: If `tenant` is not a list of `wvc.Tenant` objects.
544+
"""
545+
self.__update_tenant_activity_status(
546+
tenant=tenant,
547+
activity_status=TenantUpdateActivityStatus.INACTIVE,
548+
)
549+
550+
def offload(
551+
self, tenant: Union[TenantInputType, Sequence[TenantInputType]]
552+
) -> executor.Result[None]:
553+
"""Offload the specified tenants for this collection in Weaviate.
554+
555+
The collection must have been created with multi-tenancy enabled.
556+
557+
Args:
558+
tenant: A tenant name, `wvc.config.tenants.Tenant` object, or a list of tenants names
559+
and/or `wvc.config.tenants.Tenant` objects to offload for the given collection.
560+
561+
Raises:
562+
weaviate.exceptions.WeaviateConnectionError: If the network connection to Weaviate fails.
563+
weaviate.exceptions.UnexpectedStatusCodeError: If Weaviate reports a non-OK status.
564+
weaviate.exceptions.WeaviateInvalidInputError: If `tenant` is not a list of `wvc.Tenant` objects.
565+
"""
566+
self.__update_tenant_activity_status(
567+
tenant=tenant,
568+
activity_status=TenantUpdateActivityStatus.OFFLOADED,
569+
)
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Dict, Optional, Sequence, Union
22

3-
from weaviate.collections.classes.tenants import Tenant
43
from weaviate.collections.tenants.types import (
54
TenantCreateInputType,
5+
TenantInputType,
66
TenantOutputType,
77
TenantUpdateInputType,
88
)
@@ -14,13 +14,14 @@ class _Tenants(_TenantsExecutor[ConnectionSync]):
1414
def create(
1515
self, tenants: Union[TenantCreateInputType, Sequence[TenantCreateInputType]]
1616
) -> None: ...
17-
def remove(self, tenants: Union[str, Tenant, Sequence[Union[str, Tenant]]]) -> None: ...
17+
def remove(self, tenants: Union[TenantInputType, Sequence[TenantInputType]]) -> None: ...
1818
def get(self) -> Dict[str, TenantOutputType]: ...
19-
def get_by_names(
20-
self, tenants: Sequence[Union[str, Tenant]]
21-
) -> Dict[str, TenantOutputType]: ...
22-
def get_by_name(self, tenant: Union[str, Tenant]) -> Optional[TenantOutputType]: ...
19+
def get_by_names(self, tenants: Sequence[TenantInputType]) -> Dict[str, TenantOutputType]: ...
20+
def get_by_name(self, tenant: TenantInputType) -> Optional[TenantOutputType]: ...
2321
def update(
2422
self, tenants: Union[TenantUpdateInputType, Sequence[TenantUpdateInputType]]
2523
) -> None: ...
26-
def exists(self, tenant: Union[str, Tenant]) -> bool: ...
24+
def exists(self, tenant: TenantInputType) -> bool: ...
25+
def activate(self, tenant: Union[TenantInputType, Sequence[TenantInputType]]) -> None: ...
26+
def deactivate(self, tenant: Union[TenantInputType, Sequence[TenantInputType]]) -> None: ...
27+
def offload(self, tenant: Union[TenantInputType, Sequence[TenantInputType]]) -> None: ...

weaviate/collections/tenants/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from weaviate.collections.classes.tenants import Tenant, TenantCreate, TenantUpdate
44

5+
TenantInputType = Union[str, Tenant]
56
TenantCreateInputType = Union[str, Tenant, TenantCreate]
67
TenantUpdateInputType = Union[Tenant, TenantUpdate]
78
TenantOutputType = Tenant

0 commit comments

Comments
 (0)