Skip to content

Commit 0d0b363

Browse files
authored
Merge branch 'main' into update_doc_by_func
2 parents c0115fe + 7daf595 commit 0d0b363

15 files changed

+237
-124
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.8.4-buster
1+
FROM python:3.9-buster
22

33
COPY Pipfile .
44
COPY Pipfile.lock .

Pipfile.lock

Lines changed: 93 additions & 100 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

meilisearch/_httprequests.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717

1818

1919
class HttpRequests:
20-
def __init__(self, config: Config) -> None:
20+
def __init__(self, config: Config, custom_headers: Optional[Mapping[str, str]] = None) -> None:
2121
self.config = config
2222
self.headers = {
2323
"Authorization": f"Bearer {self.config.api_key}",
2424
"User-Agent": _build_user_agent(config.client_agents),
2525
}
2626

27+
if custom_headers is not None:
28+
self.headers.update(custom_headers)
29+
2730
def send_request(
2831
self,
2932
http_method: Callable,

meilisearch/client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def __init__(
3434
api_key: Optional[str] = None,
3535
timeout: Optional[int] = None,
3636
client_agents: Optional[Tuple[str, ...]] = None,
37+
custom_headers: Optional[Mapping[str, str]] = None,
3738
) -> None:
3839
"""
3940
Parameters
@@ -48,10 +49,13 @@ def __init__(
4849
client_agents (optional):
4950
Used to send additional client agent information for clients extending the functionality
5051
of this client.
52+
custom_headers (optional):
53+
Custom headers to add when sending data to Meilisearch.
5154
"""
55+
5256
self.config = Config(url, api_key, timeout=timeout, client_agents=client_agents)
5357

54-
self.http = HttpRequests(self.config)
58+
self.http = HttpRequests(self.config, custom_headers)
5559

5660
self.task_handler = TaskHandler(self.config)
5761

meilisearch/index.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
HuggingFaceEmbedder,
3131
IndexStats,
3232
LocalizedAttributes,
33+
OllamaEmbedder,
3334
OpenAiEmbedder,
3435
Pagination,
3536
ProximityPrecision,
37+
RestEmbedder,
3638
TypoTolerance,
3739
UserProvidedEmbedder,
3840
)
@@ -281,12 +283,7 @@ def search(self, query: str, opt_params: Optional[Mapping[str, Any]] = None) ->
281283
String containing the searched word(s)
282284
opt_params (optional):
283285
Dictionary containing optional query parameters.
284-
Note: The vector parameter is only available in Meilisearch >= v1.3.0, and is experimental
285-
Meilisearch v1.3.0. In order to use this feature in Meilisearch v1.3.0 you first need to
286-
enable the feature by sending a PATCH request to /experimental-features with
287-
{ "vectoreStore": true }. Because this feature is experimental it may be removed or
288-
updated causing breaking changes in this library without a major version bump so use
289-
with caution.
286+
Note: The vector parameter is only available in Meilisearch >= v1.13.0
290287
https://www.meilisearch.com/docs/reference/api/search#search-in-an-index
291288
292289
Returns
@@ -958,12 +955,23 @@ def get_settings(self) -> Dict[str, Any]:
958955
)
959956

960957
if settings.get("embedders"):
961-
embedders: dict[str, OpenAiEmbedder | HuggingFaceEmbedder | UserProvidedEmbedder] = {}
958+
embedders: dict[
959+
str,
960+
OpenAiEmbedder
961+
| HuggingFaceEmbedder
962+
| OllamaEmbedder
963+
| RestEmbedder
964+
| UserProvidedEmbedder,
965+
] = {}
962966
for k, v in settings["embedders"].items():
963967
if v.get("source") == "openAi":
964968
embedders[k] = OpenAiEmbedder(**v)
969+
elif v.get("source") == "ollama":
970+
embedders[k] = OllamaEmbedder(**v)
965971
elif v.get("source") == "huggingFace":
966972
embedders[k] = HuggingFaceEmbedder(**v)
973+
elif v.get("source") == "rest":
974+
embedders[k] = RestEmbedder(**v)
967975
else:
968976
embedders[k] = UserProvidedEmbedder(**v)
969977

@@ -1886,12 +1894,23 @@ def get_embedders(self) -> Embedders | None:
18861894
if not response:
18871895
return None
18881896

1889-
embedders: dict[str, OpenAiEmbedder | HuggingFaceEmbedder | UserProvidedEmbedder] = {}
1897+
embedders: dict[
1898+
str,
1899+
OpenAiEmbedder
1900+
| HuggingFaceEmbedder
1901+
| OllamaEmbedder
1902+
| RestEmbedder
1903+
| UserProvidedEmbedder,
1904+
] = {}
18901905
for k, v in response.items():
18911906
if v.get("source") == "openAi":
18921907
embedders[k] = OpenAiEmbedder(**v)
1908+
elif v.get("source") == "ollama":
1909+
embedders[k] = OllamaEmbedder(**v)
18931910
elif v.get("source") == "huggingFace":
18941911
embedders[k] = HuggingFaceEmbedder(**v)
1912+
elif v.get("source") == "rest":
1913+
embedders[k] = RestEmbedder(**v)
18951914
else:
18961915
embedders[k] = UserProvidedEmbedder(**v)
18971916

meilisearch/models/index.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,26 @@ class ProximityPrecision(str, Enum):
5454
BY_ATTRIBUTE = "byAttribute"
5555

5656

57+
class EmbedderDistribution(CamelBase):
58+
mean: float
59+
sigma: float
60+
61+
5762
class LocalizedAttributes(CamelBase):
5863
attribute_patterns: List[str]
5964
locales: List[str]
6065

6166

6267
class OpenAiEmbedder(CamelBase):
6368
source: str = "openAi"
69+
url: Optional[str] = None
6470
model: Optional[str] = None # Defaults to text-embedding-3-small
6571
dimensions: Optional[int] = None # Uses the model default
6672
api_key: Optional[str] = None # Can be provided through a CLI option or environment variable
6773
document_template: Optional[str] = None
6874
document_template_max_bytes: Optional[int] = None # Default to 400
75+
distribution: Optional[EmbedderDistribution] = None
76+
binary_quantized: Optional[bool] = None
6977

7078

7179
class HuggingFaceEmbedder(CamelBase):
@@ -74,12 +82,45 @@ class HuggingFaceEmbedder(CamelBase):
7482
revision: Optional[str] = None
7583
document_template: Optional[str] = None
7684
document_template_max_bytes: Optional[int] = None # Default to 400
85+
distribution: Optional[EmbedderDistribution] = None
86+
binary_quantized: Optional[bool] = None
87+
88+
89+
class OllamaEmbedder(CamelBase):
90+
source: str = "ollama"
91+
url: Optional[str] = None
92+
api_key: Optional[str] = None
93+
model: str
94+
document_template: Optional[str] = None
95+
document_template_max_bytes: Optional[int] = None # Default to 400
96+
distribution: Optional[EmbedderDistribution] = None
97+
binary_quantized: Optional[bool] = None
98+
99+
100+
class RestEmbedder(CamelBase):
101+
source: str = "rest"
102+
url: str
103+
api_key: Optional[str] # required for protected APIs
104+
document_template: Optional[str] = None
105+
document_template_max_bytes: Optional[int] = None # Default to 400
106+
request: Dict[str, Any]
107+
response: Dict[str, Any]
108+
distribution: Optional[EmbedderDistribution] = None
109+
headers: Optional[Dict[str, Any]] = None
110+
binary_quantized: Optional[bool] = None
77111

78112

79113
class UserProvidedEmbedder(CamelBase):
80114
source: str = "userProvided"
81115
dimensions: int
116+
distribution: Optional[EmbedderDistribution] = None
117+
binary_quantized: Optional[bool] = None
82118

83119

84120
class Embedders(CamelBase):
85-
embedders: Dict[str, Union[OpenAiEmbedder, HuggingFaceEmbedder, UserProvidedEmbedder]]
121+
embedders: Dict[
122+
str,
123+
Union[
124+
OpenAiEmbedder, HuggingFaceEmbedder, OllamaEmbedder, RestEmbedder, UserProvidedEmbedder
125+
],
126+
]

meilisearch/models/key.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class _KeyBase(CamelBase):
1111
uid: str
1212
name: Optional[str] = None
13-
description: str
13+
description: Optional[str]
1414
actions: List[str]
1515
indexes: List[str]
1616
expires_at: Optional[datetime] = None

meilisearch/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
__version__ = "0.33.1"
3+
__version__ = "0.34.0"
44

55

66
def qualified_version() -> str:

tests/client/test_client.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# pylint: disable=invalid-name
22

3+
import pytest
4+
35
import meilisearch
46
from tests import BASE_URL, MASTER_KEY
57

@@ -26,3 +28,33 @@ def test_client_timeout_not_set():
2628
response = client.health()
2729
assert client.config.timeout == default_timeout
2830
assert response["status"] == "available"
31+
32+
33+
@pytest.mark.parametrize(
34+
"api_key, custom_headers, expected",
35+
(
36+
("testKey", None, {"Authorization": "Bearer testKey"}),
37+
(
38+
"testKey",
39+
{"header_key_1": "header_value_1", "header_key_2": "header_value_2"},
40+
{
41+
"Authorization": "Bearer testKey",
42+
"header_key_1": "header_value_1",
43+
"header_key_2": "header_value_2",
44+
},
45+
),
46+
(
47+
None,
48+
{"header_key_1": "header_value_1", "header_key_2": "header_value_2"},
49+
{
50+
"header_key_1": "header_value_1",
51+
"header_key_2": "header_value_2",
52+
},
53+
),
54+
(None, None, {}),
55+
),
56+
)
57+
def test_headers(api_key, custom_headers, expected):
58+
client = meilisearch.Client("127.0.0.1:7700", api_key=api_key, custom_headers=custom_headers)
59+
60+
assert client.http.headers.items() >= expected.items()

tests/client/test_client_key_meilisearch.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ def test_create_keys_default(client, test_key_info):
4646
assert key.indexes == test_key_info["indexes"]
4747

4848

49+
def test_create_keys_without_desc(client, test_nondescript_key_info):
50+
"""Tests the creation of a key with no optional argument."""
51+
key = client.create_key(test_nondescript_key_info)
52+
print(key)
53+
54+
assert key.name == "keyWithoutDescription"
55+
assert key.description is None
56+
57+
4958
def test_create_keys_with_options(client, test_key_info):
5059
"""Tests the creation of a key with arguments."""
5160
key = client.create_key(

tests/conftest.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import json
33
from typing import Optional
44

5-
import requests
65
from pytest import fixture
76

87
import meilisearch
@@ -206,6 +205,27 @@ def test_key_info(client):
206205
pass
207206

208207

208+
@fixture(scope="function")
209+
def test_nondescript_key_info(client):
210+
key_info = {
211+
"name": "keyWithoutDescription",
212+
"actions": ["search"],
213+
"indexes": [common.INDEX_UID],
214+
"expiresAt": None,
215+
}
216+
217+
yield key_info
218+
219+
try:
220+
keys = client.get_keys().results
221+
key = next(x for x in keys if x.name == key_info["name"])
222+
client.delete_key(key.key)
223+
except MeilisearchApiError:
224+
pass
225+
except StopIteration:
226+
pass
227+
228+
209229
@fixture(scope="function")
210230
def get_private_key(client):
211231
keys = client.get_keys().results

tests/index/test_index_document_meilisearch.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ def test_get_documents_filter_with_fields(index_with_documents):
265265
assert next(iter(genres)) == "action"
266266

267267

268-
@pytest.mark.usefixtures("enable_vector_search")
269268
def test_get_similar_documents(empty_index):
270269
index = empty_index()
271270
index.update_embedders({"manual": {"source": "userProvided", "dimensions": 3}})

tests/index/test_index_search_meilisearch.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,6 @@ def test_show_ranking_score(index_with_documents):
502502
assert response["hits"][0]["_rankingScore"] >= 0.9
503503

504504

505-
@pytest.mark.usefixtures("enable_vector_search")
506505
def test_vector_search(index_with_documents_and_vectors):
507506
response = index_with_documents_and_vectors().search(
508507
"",

tests/settings/test_settings.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ def test_get_settings_default(empty_index):
4141
assert response["synonyms"] == {}
4242

4343

44-
@pytest.mark.usefixtures("enable_vector_search")
4544
def test_update_settings(new_settings, empty_index):
4645
"""Tests updating some settings."""
4746
index = empty_index()
@@ -61,7 +60,6 @@ def test_update_settings(new_settings, empty_index):
6160
assert isinstance(response["embedders"]["open_ai"], OpenAiEmbedder)
6261

6362

64-
@pytest.mark.usefixtures("enable_vector_search")
6563
def test_reset_settings(new_settings, empty_index):
6664
"""Tests resetting all the settings to their default value."""
6765
index = empty_index()
@@ -94,4 +92,4 @@ def test_reset_settings(new_settings, empty_index):
9492
assert response["searchableAttributes"] == ["*"]
9593
assert response["stopWords"] == []
9694
assert response["synonyms"] == {}
97-
assert response.get("embedders") is None
95+
assert response["embedders"] == {}

tests/settings/test_settings_embedders.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
# pylint: disable=redefined-outer-name
2-
import pytest
32

43
from meilisearch.models.index import OpenAiEmbedder, UserProvidedEmbedder
54

65

7-
@pytest.mark.usefixtures("enable_vector_search")
86
def test_get_default_embedders(empty_index):
97
"""Tests getting default embedders."""
108
response = empty_index().get_embedders()
119

1210
assert response is None
1311

1412

15-
@pytest.mark.usefixtures("enable_vector_search")
1613
def test_update_embedders_with_user_provided_source(new_embedders, empty_index):
1714
"""Tests updating embedders."""
1815
index = empty_index()
@@ -24,7 +21,6 @@ def test_update_embedders_with_user_provided_source(new_embedders, empty_index):
2421
assert isinstance(response_get.embedders["open_ai"], OpenAiEmbedder)
2522

2623

27-
@pytest.mark.usefixtures("enable_vector_search")
2824
def test_reset_embedders(new_embedders, empty_index):
2925
"""Tests resetting the typo_tolerance setting to its default value."""
3026
index = empty_index()

0 commit comments

Comments
 (0)