Skip to content

Commit 5e7179c

Browse files
committed
feat: add runtime property reindex API for Weaviate >= 1.39 (#2097)
Adds collection.config methods for the GA runtime property reindex API: - update_property_index: declarative create-or-migrate upsert (PUT /schema/{class}/properties/{prop}/index/{indexType}) with optional wait_for_completion polling of the index status endpoint - rebuild_property_index: rebuild an existing index from scratch, with tenant selection and optional wait_for_completion - cancel_property_index_task: idempotent cancellation of a live task - get_property_indexes: parse GET /schema/{class}/indexes into new CollectionPropertyIndexes/PropertyIndexStatus read-side types All methods raise WeaviateUnsupportedFeatureError below server 1.39.0.
1 parent 904ea78 commit 5e7179c

7 files changed

Lines changed: 622 additions & 2 deletions

File tree

weaviate/collections/classes/config.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,6 +2207,83 @@ class _ShardStatus:
22072207
ShardStatus = _ShardStatus
22082208

22092209

2210+
class PropertyIndexTaskStatus(str, BaseEnum):
2211+
"""The status of a runtime property index task submission.
2212+
2213+
Attributes:
2214+
STARTED: A reindexing task was submitted and started.
2215+
CANCELLED: A live reindexing task was cancelled.
2216+
NO_OP: No work was necessary, e.g. the index configuration already matched the request
2217+
or there was no live task to cancel.
2218+
"""
2219+
2220+
STARTED = "STARTED"
2221+
CANCELLED = "CANCELLED"
2222+
NO_OP = "NO_OP"
2223+
2224+
2225+
class PropertyIndexState(str, BaseEnum):
2226+
"""The state of a property index as reported by the index status endpoint.
2227+
2228+
Attributes:
2229+
READY: The index is ready to serve queries.
2230+
PENDING: A reindexing task for the index is queued but has not started yet.
2231+
INDEXING: A reindexing task for the index is in progress.
2232+
FAILED: The reindexing task for the index failed.
2233+
CANCELLED: The reindexing task for the index was cancelled.
2234+
"""
2235+
2236+
READY = "ready"
2237+
PENDING = "pending"
2238+
INDEXING = "indexing"
2239+
FAILED = "failed"
2240+
CANCELLED = "cancelled"
2241+
2242+
2243+
@dataclass
2244+
class _PropertyIndexTask(_ConfigBase):
2245+
task_id: Optional[str]
2246+
status: PropertyIndexTaskStatus
2247+
2248+
2249+
PropertyIndexTask = _PropertyIndexTask
2250+
2251+
2252+
@dataclass
2253+
class _PropertyIndexStatus(_ConfigBase):
2254+
type: IndexName # noqa: A003
2255+
status: PropertyIndexState
2256+
progress: Optional[float]
2257+
task_id: Optional[str]
2258+
tokenization: Optional[Tokenization]
2259+
target_tokenization: Optional[Tokenization]
2260+
algorithm: Optional[str]
2261+
target_algorithm: Optional[str]
2262+
2263+
2264+
PropertyIndexStatus = _PropertyIndexStatus
2265+
2266+
2267+
@dataclass
2268+
class _PropertyIndexes(_ConfigBase):
2269+
name: str
2270+
data_type: str
2271+
description: Optional[str]
2272+
indexes: List[PropertyIndexStatus]
2273+
2274+
2275+
PropertyIndexes = _PropertyIndexes
2276+
2277+
2278+
@dataclass
2279+
class _CollectionPropertyIndexes(_ConfigBase):
2280+
collection: str
2281+
properties: List[PropertyIndexes]
2282+
2283+
2284+
CollectionPropertyIndexes = _CollectionPropertyIndexes
2285+
2286+
22102287
class _TextAnalyzerConfigCreate(_ConfigCreateModel):
22112288
"""Text analysis options for a property.
22122289

weaviate/collections/classes/config_methods.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
from weaviate.collections.classes.config import (
55
DataType,
66
GenerativeSearches,
7+
IndexName,
78
PQEncoderDistribution,
89
PQEncoderType,
10+
PropertyIndexState,
11+
PropertyIndexTaskStatus,
912
ReplicationDeletionStrategy,
1013
Rerankers,
1114
StopwordsPreset,
@@ -19,6 +22,7 @@
1922
_BQConfig,
2023
_CollectionConfig,
2124
_CollectionConfigSimple,
25+
_CollectionPropertyIndexes,
2226
_GenerativeConfig,
2327
_InvertedIndexConfig,
2428
_MultiTenancyConfig,
@@ -31,6 +35,9 @@
3135
_PQConfig,
3236
_PQEncoderConfig,
3337
_Property,
38+
_PropertyIndexes,
39+
_PropertyIndexStatus,
40+
_PropertyIndexTask,
3441
_PropertyVectorizerConfig,
3542
_ReferenceProperty,
3643
_ReplicationConfig,
@@ -558,3 +565,49 @@ def _references_from_config(schema: Dict[str, Any]) -> List[_ReferenceProperty]:
558565
for prop in schema["properties"]
559566
if not _is_primitive(prop["dataType"])
560567
]
568+
569+
570+
def _property_index_task_from_json(response: Dict[str, Any]) -> _PropertyIndexTask:
571+
return _PropertyIndexTask(
572+
task_id=response.get("taskId"),
573+
status=PropertyIndexTaskStatus(response["status"]),
574+
)
575+
576+
577+
def _property_index_status_from_json(index: Dict[str, Any]) -> _PropertyIndexStatus:
578+
tokenization = index.get("tokenization")
579+
target_tokenization = index.get("targetTokenization")
580+
return _PropertyIndexStatus(
581+
type=cast(IndexName, index["type"]),
582+
status=PropertyIndexState(index["status"]),
583+
progress=index.get("progress"),
584+
task_id=index.get("taskId"),
585+
tokenization=Tokenization(tokenization) if tokenization is not None else None,
586+
target_tokenization=(
587+
Tokenization(target_tokenization) if target_tokenization is not None else None
588+
),
589+
algorithm=index.get("algorithm"),
590+
target_algorithm=index.get("targetAlgorithm"),
591+
)
592+
593+
594+
def _collection_property_indexes_from_json(response: Dict[str, Any]) -> _CollectionPropertyIndexes:
595+
properties: List[_PropertyIndexes] = []
596+
for prop in response.get("properties") or []:
597+
data_type = prop.get("dataType")
598+
if isinstance(data_type, list):
599+
data_type = data_type[0] if len(data_type) > 0 else ""
600+
properties.append(
601+
_PropertyIndexes(
602+
name=prop["name"],
603+
data_type=cast(str, data_type),
604+
description=prop.get("description"),
605+
indexes=[
606+
_property_index_status_from_json(index) for index in prop.get("indexes") or []
607+
],
608+
)
609+
)
610+
return _CollectionPropertyIndexes(
611+
collection=response["collection"],
612+
properties=properties,
613+
)

weaviate/collections/config/async_.pyi

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
from typing import Dict, List, Literal, Optional, Union, overload
1+
from typing import Dict, List, Literal, Optional, Sequence, Union, overload
22

33
from typing_extensions import deprecated
44

55
from weaviate.collections.classes.config import (
66
CollectionConfig,
77
CollectionConfigSimple,
8+
CollectionPropertyIndexes,
89
IndexName,
910
Property,
11+
PropertyIndexStatus,
12+
PropertyIndexTask,
1013
ReferenceProperty,
1114
ShardStatus,
1215
ShardTypes,
16+
Tokenization,
1317
_GenerativeProvider,
1418
_InvertedIndexConfigUpdate,
1519
_MultiTenancyConfigUpdate,
@@ -90,3 +94,47 @@ class _ConfigCollectionAsync(_ConfigCollectionExecutor[ConnectionAsync]):
9094
self, *, vector_config: Union[_VectorConfigCreate, List[_VectorConfigCreate]]
9195
) -> None: ...
9296
async def delete_property_index(self, property_name: str, index_name: IndexName) -> bool: ...
97+
@overload
98+
async def update_property_index(
99+
self,
100+
property_name: str,
101+
index_name: IndexName,
102+
*,
103+
tokenization: Optional[Tokenization] = None,
104+
algorithm: Optional[Literal["blockmax"]] = None,
105+
tenants: Optional[Sequence[str]] = None,
106+
wait_for_completion: Literal[True],
107+
) -> PropertyIndexStatus: ...
108+
@overload
109+
async def update_property_index(
110+
self,
111+
property_name: str,
112+
index_name: IndexName,
113+
*,
114+
tokenization: Optional[Tokenization] = None,
115+
algorithm: Optional[Literal["blockmax"]] = None,
116+
tenants: Optional[Sequence[str]] = None,
117+
wait_for_completion: Literal[False] = False,
118+
) -> PropertyIndexTask: ...
119+
@overload
120+
async def rebuild_property_index(
121+
self,
122+
property_name: str,
123+
index_name: IndexName,
124+
*,
125+
tenants: Optional[Sequence[str]] = None,
126+
wait_for_completion: Literal[True],
127+
) -> PropertyIndexStatus: ...
128+
@overload
129+
async def rebuild_property_index(
130+
self,
131+
property_name: str,
132+
index_name: IndexName,
133+
*,
134+
tenants: Optional[Sequence[str]] = None,
135+
wait_for_completion: Literal[False] = False,
136+
) -> PropertyIndexTask: ...
137+
async def cancel_property_index_task(
138+
self, property_name: str, index_name: IndexName
139+
) -> PropertyIndexTask: ...
140+
async def get_property_indexes(self) -> CollectionPropertyIndexes: ...

0 commit comments

Comments
 (0)