Skip to content

Commit 067f962

Browse files
committed
Merge branch 'dev/1.36' of https://github.com/weaviate/weaviate-python-client into dev/1.36
2 parents 31d3ce9 + 005fb12 commit 067f962

File tree

10 files changed

+203
-11
lines changed

10 files changed

+203
-11
lines changed

docs/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Changelog
22
=========
33

4+
Version 4.19.3
5+
--------------
6+
This patch version includes:
7+
- Add support for VoyageAI voyage-4 model family (voyage-4, voyage-4-lite, voyage-4-large)
8+
49

510
Version 4.19.2
611
--------------

integration/test_backup_v4.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ def test_create_and_restore_backup_without_waiting(
225225
BackupStatus.TRANSFERRED,
226226
BackupStatus.TRANSFERRING,
227227
BackupStatus.STARTED,
228+
BackupStatus.FINALIZING,
228229
]
229230
if restore_status.status == BackupStatus.SUCCESS:
230231
break

requirements-devel.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
httpx==0.26.0
22
validators==0.34.0
3-
authlib==1.6.5
3+
authlib==1.6.6
44
grpcio==1.75.1
55
grpcio-tools==1.75.1
66
grpcio-health-checking==1.75.1

requirements-test.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
pytest==8.4.2
22
pytest-cov==6.2.1
3-
pytest-asyncio==1.2.0
3+
pytest-asyncio==1.3.0
44
pytest-benchmark==5.1.0
55
pytest-profiling==1.8.1
66
coverage==7.10.7
77
pytest-xdist==3.7.0
8-
werkzeug==3.1.4
8+
werkzeug==3.1.5
99
pytest-httpserver==1.1.3
1010
py-spy==0.4.1
1111

1212
numpy>=1.24.4,<3.0.0
1313
pandas>=2.0.3,<3.0.0
14-
polars>=0.20.26,<1.36.0
14+
polars>=0.20.26,<1.37.0
1515

1616
fastapi>=0.111.0,<1.0.0
1717
flask[async]>=2.0.0,<4.0.0

test/collection/test_config.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import timedelta
12
from typing import List, Union
23

34
import pytest
@@ -11,6 +12,7 @@
1112
Vectorizers,
1213
_CollectionConfigCreate,
1314
_GenerativeProvider,
15+
_ObjectTTLConfig,
1416
_RerankerProvider,
1517
_VectorizerConfigCreate,
1618
)
@@ -2424,6 +2426,83 @@ def test_config_with_named_vectors(
24242426
}
24252427
},
24262428
),
2429+
(
2430+
[
2431+
Configure.Vectors.multi2vec_voyageai(
2432+
name="test",
2433+
model="voyage-multimodal-3.5",
2434+
truncation=True,
2435+
base_url="https://api.voyageai.com",
2436+
),
2437+
],
2438+
{
2439+
"test": {
2440+
"vectorizer": {
2441+
"multi2vec-voyageai": {
2442+
"model": "voyage-multimodal-3.5",
2443+
"truncation": True,
2444+
"baseURL": "https://api.voyageai.com/",
2445+
}
2446+
},
2447+
"vectorIndexType": "hnsw",
2448+
}
2449+
},
2450+
),
2451+
(
2452+
[
2453+
Configure.Vectors.multi2vec_voyageai(
2454+
name="test",
2455+
model="voyage-multimodal-3.5",
2456+
truncation=True,
2457+
text_fields=[Multi2VecField(name="text", weight=0.2)],
2458+
image_fields=[Multi2VecField(name="image", weight=0.3)],
2459+
video_fields=[Multi2VecField(name="video", weight=0.5)],
2460+
)
2461+
],
2462+
{
2463+
"test": {
2464+
"vectorizer": {
2465+
"multi2vec-voyageai": {
2466+
"model": "voyage-multimodal-3.5",
2467+
"truncation": True,
2468+
"textFields": ["text"],
2469+
"imageFields": ["image"],
2470+
"videoFields": ["video"],
2471+
"weights": {
2472+
"textFields": [0.2],
2473+
"imageFields": [0.3],
2474+
"videoFields": [0.5],
2475+
},
2476+
}
2477+
},
2478+
"vectorIndexType": "hnsw",
2479+
},
2480+
},
2481+
),
2482+
(
2483+
[
2484+
Configure.Vectors.multi2vec_voyageai(
2485+
name="test",
2486+
model="voyage-multimodal-3.5",
2487+
dimensions=512,
2488+
text_fields=["text"],
2489+
video_fields=["video"],
2490+
)
2491+
],
2492+
{
2493+
"test": {
2494+
"vectorizer": {
2495+
"multi2vec-voyageai": {
2496+
"model": "voyage-multimodal-3.5",
2497+
"dimensions": 512,
2498+
"textFields": ["text"],
2499+
"videoFields": ["video"],
2500+
}
2501+
},
2502+
"vectorIndexType": "hnsw",
2503+
}
2504+
},
2505+
),
24272506
(
24282507
[
24292508
Configure.Vectors.multi2vec_clip(
@@ -2519,3 +2598,87 @@ def test_config_with_vectors(vector_config: List[_VectorConfigCreate], expected:
25192598
"class": "Test",
25202599
"vectorConfig": expected,
25212600
}
2601+
2602+
2603+
TEST_OBJECT_TTL_CONFIG_TO_DICT_PARAMETERS = [
2604+
# delete_by_creation_time
2605+
(
2606+
_ObjectTTLConfig(
2607+
enabled=True,
2608+
time_to_live=timedelta(hours=24),
2609+
filter_expired_objects=True,
2610+
delete_on="creationTime",
2611+
),
2612+
{
2613+
"enabled": True,
2614+
"timeToLive": 86400,
2615+
"filterExpiredObjects": True,
2616+
"deleteOn": "creationTime",
2617+
},
2618+
),
2619+
# delete_by_update_time
2620+
(
2621+
_ObjectTTLConfig(
2622+
enabled=True,
2623+
time_to_live=timedelta(days=7),
2624+
filter_expired_objects=False,
2625+
delete_on="updateTime",
2626+
),
2627+
{
2628+
"enabled": True,
2629+
"timeToLive": 604800,
2630+
"filterExpiredObjects": False,
2631+
"deleteOn": "updateTime",
2632+
},
2633+
),
2634+
# delete_by_date_property
2635+
(
2636+
_ObjectTTLConfig(
2637+
enabled=True,
2638+
time_to_live=timedelta(hours=1, minutes=30),
2639+
filter_expired_objects=True,
2640+
delete_on="releaseDate",
2641+
),
2642+
{
2643+
"enabled": True,
2644+
"timeToLive": 5400,
2645+
"filterExpiredObjects": True,
2646+
"deleteOn": "releaseDate",
2647+
},
2648+
),
2649+
# None time_to_live
2650+
(
2651+
_ObjectTTLConfig(
2652+
enabled=True,
2653+
time_to_live=None,
2654+
filter_expired_objects=False,
2655+
delete_on="creationTime",
2656+
),
2657+
{
2658+
"enabled": True,
2659+
"filterExpiredObjects": False,
2660+
"deleteOn": "creationTime",
2661+
},
2662+
),
2663+
# negative offset (delete_by_date_property with offset before date)
2664+
(
2665+
_ObjectTTLConfig(
2666+
enabled=True,
2667+
time_to_live=timedelta(seconds=-3600),
2668+
filter_expired_objects=True,
2669+
delete_on="eventDate",
2670+
),
2671+
{
2672+
"enabled": True,
2673+
"timeToLive": -3600,
2674+
"filterExpiredObjects": True,
2675+
"deleteOn": "eventDate",
2676+
},
2677+
),
2678+
]
2679+
2680+
2681+
@pytest.mark.parametrize("ttl_config,expected", TEST_OBJECT_TTL_CONFIG_TO_DICT_PARAMETERS)
2682+
def test_object_ttl_config_to_dict(ttl_config: _ObjectTTLConfig, expected: dict) -> None:
2683+
"""Test that _ObjectTTLConfig.to_dict() properly converts timedelta to seconds."""
2684+
assert ttl_config.to_dict() == expected

weaviate/backup/backup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class BackupStatus(str, Enum):
4141
STARTED = "STARTED"
4242
TRANSFERRING = "TRANSFERRING"
4343
TRANSFERRED = "TRANSFERRED"
44+
CANCELLING = "CANCELLING"
45+
FINALIZING = "FINALIZING"
4446
SUCCESS = "SUCCESS"
4547
FAILED = "FAILED"
4648
CANCELED = "CANCELED"

weaviate/collections/classes/config_base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from abc import abstractmethod
22
from dataclasses import dataclass
3+
from datetime import timedelta
34
from enum import Enum
45
from typing import Any, Dict, cast
56

@@ -59,6 +60,9 @@ def to_dict(self) -> dict:
5960
if isinstance(v, Enum):
6061
out[key] = v.value
6162
continue
63+
if isinstance(v, timedelta):
64+
out[key] = int(v.total_seconds())
65+
continue
6266
if isinstance(v, dict):
6367
out[key] = {
6468
k: v.to_dict() if isinstance(v, _ConfigBase) else v for k, v in v.items()

weaviate/collections/classes/config_named_vectors.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,10 @@ def multi2vec_voyageai(
730730
baseURL=base_url,
731731
model=model,
732732
truncation=truncation,
733+
dimensions=None,
733734
imageFields=_map_multi2vec_fields(image_fields),
734735
textFields=_map_multi2vec_fields(text_fields),
736+
videoFields=None,
735737
),
736738
vector_index_config=vector_index_config,
737739
)

weaviate/collections/classes/config_vectorizers.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
]
4949
JinaMultimodalModel: TypeAlias = Literal["jina-clip-v1", "jina-clip-v2", "jina-embeddings-v4"]
5050
VoyageModel: TypeAlias = Literal[
51+
"voyage-4",
52+
"voyage-4-lite",
53+
"voyage-4-large",
5154
"voyage-3.5",
5255
"voyage-3.5-lite",
5356
"voyage-3-large",
@@ -62,7 +65,10 @@
6265
"voyage-finance-2",
6366
"voyage-multilingual-2",
6467
]
65-
VoyageMultimodalModel: TypeAlias = Literal["voyage-multimodal-3",]
68+
VoyageMultimodalModel: TypeAlias = Literal[
69+
"voyage-multimodal-3",
70+
"voyage-multimodal-3.5",
71+
]
6672
AWSModel: TypeAlias = Literal[
6773
"amazon.titan-embed-text-v1",
6874
"cohere.embed-english-v3",
@@ -566,6 +572,8 @@ class _Multi2VecVoyageaiConfig(_Multi2VecBase):
566572
baseURL: Optional[AnyHttpUrl]
567573
model: Optional[str]
568574
truncation: Optional[bool]
575+
dimensions: Optional[int]
576+
videoFields: Optional[List[Multi2VecField]]
569577

570578
def _to_dict(self) -> Dict[str, Any]:
571579
ret_dict = super()._to_dict()
@@ -897,37 +905,39 @@ def multi2vec_cohere(
897905
@staticmethod
898906
def multi2vec_voyageai(
899907
*,
900-
model: Optional[Union[CohereMultimodalModel, str]] = None,
908+
model: Optional[Union[VoyageMultimodalModel, str]] = None,
901909
truncation: Optional[bool] = None,
902910
output_encoding: Optional[str],
903911
vectorize_collection_name: bool = True,
904912
base_url: Optional[AnyHttpUrl] = None,
905913
image_fields: Optional[Union[List[str], List[Multi2VecField]]] = None,
906914
text_fields: Optional[Union[List[str], List[Multi2VecField]]] = None,
907915
) -> _VectorizerConfigCreate:
908-
"""Create a `_Multi2VecCohereConfig` object for use when vectorizing using the `multi2vec-cohere` model.
916+
"""Create a `_Multi2VecVoyageaiConfig` object for use when vectorizing using the `multi2vec-voyageai` model.
909917
910-
See the [documentation](https://weaviate.io/developers/weaviate/model-providers/cohere/embeddings-multimodal)
918+
See the [documentation](https://weaviate.io/developers/weaviate/model-providers/voyageai/embeddings-multimodal)
911919
for detailed usage.
912920
913921
Args:
914922
model: The model to use. Defaults to `None`, which uses the server-defined default.
915-
truncate: The truncation strategy to use. Defaults to `None`, which uses the server-defined default.
923+
truncation: The truncation strategy to use. Defaults to `None`, which uses the server-defined default.
916924
output_encoding: Deprecated, has no effect.
917925
vectorize_collection_name: Deprecated, has no effect.
918926
base_url: The base URL to use where API requests should go. Defaults to `None`, which uses the server-defined default.
919927
image_fields: The image fields to use in vectorization.
920928
text_fields: The text fields to use in vectorization.
921929
922930
Raises:
923-
pydantic.ValidationError: If `model` is not a valid value from the `CohereMultimodalModel` type or if `truncate` is not a valid value from the `CohereTruncation` type.
931+
pydantic.ValidationError: If `model` is not a valid value from the `VoyageMultimodalModel` type.
924932
"""
925933
return _Multi2VecVoyageaiConfig(
926934
baseURL=base_url,
927935
model=model,
928936
truncation=truncation,
937+
dimensions=None,
929938
imageFields=_map_multi2vec_fields(image_fields),
930939
textFields=_map_multi2vec_fields(text_fields),
940+
videoFields=None,
931941
)
932942

933943
@staticmethod

weaviate/collections/classes/config_vectors.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,8 @@ def multi2vec_voyageai(
11141114
image_fields: Optional[Union[List[str], List[Multi2VecField]]] = None,
11151115
model: Optional[Union[VoyageMultimodalModel, str]] = None,
11161116
text_fields: Optional[Union[List[str], List[Multi2VecField]]] = None,
1117+
video_fields: Optional[Union[List[str], List[Multi2VecField]]] = None,
1118+
dimensions: Optional[int] = None,
11171119
truncation: Optional[bool] = None,
11181120
vector_index_config: Optional[_VectorIndexConfigCreate] = None,
11191121
) -> _VectorConfigCreate:
@@ -1128,8 +1130,9 @@ def multi2vec_voyageai(
11281130
base_url: The base URL to use where API requests should go. Defaults to `None`, which uses the server-defined default.
11291131
image_fields: The image fields to use in vectorization.
11301132
model: The model to use. Defaults to `None`, which uses the server-defined default.
1131-
output_encoding: The output encoding to use. Defaults to `None`, which uses the server-defined default.
11321133
text_fields: The text fields to use in vectorization.
1134+
video_fields: The video fields to use in vectorization.
1135+
dimensions: The number of dimensions for the output embeddings. Defaults to `None`, which uses the model's default.
11331136
truncation: The truncation strategy to use. Defaults to `None`, which uses the server-defined default.
11341137
vector_index_config: The configuration for Weaviate's vector index. Use `wvc.config.Configure.VectorIndex` to create a vector index configuration. None by default
11351138
@@ -1142,8 +1145,10 @@ def multi2vec_voyageai(
11421145
baseURL=base_url,
11431146
model=model,
11441147
truncation=truncation,
1148+
dimensions=dimensions,
11451149
imageFields=_map_multi2vec_fields(image_fields),
11461150
textFields=_map_multi2vec_fields(text_fields),
1151+
videoFields=_map_multi2vec_fields(video_fields),
11471152
),
11481153
vector_index_config=_IndexWrappers.single(vector_index_config, quantizer),
11491154
)

0 commit comments

Comments
 (0)