meilisearch-python-sdk 5.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meilisearch_python_sdk/__init__.py +8 -0
- meilisearch_python_sdk/_batch.py +166 -0
- meilisearch_python_sdk/_client.py +2468 -0
- meilisearch_python_sdk/_http_requests.py +197 -0
- meilisearch_python_sdk/_task.py +368 -0
- meilisearch_python_sdk/_utils.py +58 -0
- meilisearch_python_sdk/_version.py +1 -0
- meilisearch_python_sdk/decorators.py +242 -0
- meilisearch_python_sdk/errors.py +75 -0
- meilisearch_python_sdk/index/__init__.py +4 -0
- meilisearch_python_sdk/index/_common.py +296 -0
- meilisearch_python_sdk/index/async_index.py +4891 -0
- meilisearch_python_sdk/index/index.py +3839 -0
- meilisearch_python_sdk/json_handler.py +74 -0
- meilisearch_python_sdk/models/__init__.py +0 -0
- meilisearch_python_sdk/models/batch.py +58 -0
- meilisearch_python_sdk/models/client.py +97 -0
- meilisearch_python_sdk/models/documents.py +12 -0
- meilisearch_python_sdk/models/health.py +5 -0
- meilisearch_python_sdk/models/index.py +46 -0
- meilisearch_python_sdk/models/search.py +126 -0
- meilisearch_python_sdk/models/settings.py +197 -0
- meilisearch_python_sdk/models/task.py +77 -0
- meilisearch_python_sdk/models/version.py +9 -0
- meilisearch_python_sdk/models/webhook.py +24 -0
- meilisearch_python_sdk/plugins.py +124 -0
- meilisearch_python_sdk/py.typed +0 -0
- meilisearch_python_sdk/types.py +8 -0
- meilisearch_python_sdk-5.5.0.dist-info/METADATA +279 -0
- meilisearch_python_sdk-5.5.0.dist-info/RECORD +32 -0
- meilisearch_python_sdk-5.5.0.dist-info/WHEEL +4 -0
- meilisearch_python_sdk-5.5.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,2468 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from ssl import SSLContext
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
import jwt
|
|
8
|
+
from camel_converter import dict_to_camel
|
|
9
|
+
from httpx import AsyncClient as HttpxAsyncClient
|
|
10
|
+
from httpx import Client as HttpxClient
|
|
11
|
+
|
|
12
|
+
from meilisearch_python_sdk import _task
|
|
13
|
+
from meilisearch_python_sdk._batch import async_get_batch, async_get_batches
|
|
14
|
+
from meilisearch_python_sdk._batch import get_batch as _get_batch
|
|
15
|
+
from meilisearch_python_sdk._batch import get_batches as _get_batches
|
|
16
|
+
from meilisearch_python_sdk._http_requests import AsyncHttpRequests, HttpRequests
|
|
17
|
+
from meilisearch_python_sdk.errors import InvalidRestriction, MeilisearchApiError
|
|
18
|
+
from meilisearch_python_sdk.index import AsyncIndex, Index
|
|
19
|
+
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
|
|
20
|
+
from meilisearch_python_sdk.models.client import (
|
|
21
|
+
ClientStats,
|
|
22
|
+
Key,
|
|
23
|
+
KeyCreate,
|
|
24
|
+
KeySearch,
|
|
25
|
+
KeyUpdate,
|
|
26
|
+
Network,
|
|
27
|
+
)
|
|
28
|
+
from meilisearch_python_sdk.models.health import Health
|
|
29
|
+
from meilisearch_python_sdk.models.index import IndexInfo
|
|
30
|
+
from meilisearch_python_sdk.models.search import (
|
|
31
|
+
Federation,
|
|
32
|
+
FederationMerged,
|
|
33
|
+
SearchParams,
|
|
34
|
+
SearchResultsFederated,
|
|
35
|
+
SearchResultsWithUID,
|
|
36
|
+
)
|
|
37
|
+
from meilisearch_python_sdk.models.settings import MeilisearchSettings
|
|
38
|
+
from meilisearch_python_sdk.models.task import TaskInfo, TaskResult, TaskStatus
|
|
39
|
+
from meilisearch_python_sdk.models.version import Version
|
|
40
|
+
from meilisearch_python_sdk.models.webhook import Webhook, WebhookCreate, Webhooks, WebhookUpdate
|
|
41
|
+
from meilisearch_python_sdk.plugins import AsyncIndexPlugins, IndexPlugins
|
|
42
|
+
from meilisearch_python_sdk.types import JsonDict
|
|
43
|
+
|
|
44
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
45
|
+
import sys
|
|
46
|
+
from types import TracebackType
|
|
47
|
+
|
|
48
|
+
from meilisearch_python_sdk.models.batch import BatchResult, BatchStatus
|
|
49
|
+
from meilisearch_python_sdk.types import JsonMapping
|
|
50
|
+
|
|
51
|
+
if sys.version_info >= (3, 11):
|
|
52
|
+
from typing import Self
|
|
53
|
+
else:
|
|
54
|
+
from typing_extensions import Self
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class BaseClient:
|
|
58
|
+
def __init__(
|
|
59
|
+
self,
|
|
60
|
+
api_key: str | None = None,
|
|
61
|
+
custom_headers: dict[str, str] | None = None,
|
|
62
|
+
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
|
|
63
|
+
) -> None:
|
|
64
|
+
self.json_handler = json_handler if json_handler else BuiltinHandler()
|
|
65
|
+
self._headers: dict[str, str] | None = None
|
|
66
|
+
if api_key:
|
|
67
|
+
self._headers = {"Authorization": f"Bearer {api_key}"}
|
|
68
|
+
|
|
69
|
+
if custom_headers:
|
|
70
|
+
if self._headers:
|
|
71
|
+
self._headers.update(custom_headers)
|
|
72
|
+
else:
|
|
73
|
+
self._headers = custom_headers
|
|
74
|
+
|
|
75
|
+
def generate_tenant_token(
|
|
76
|
+
self,
|
|
77
|
+
search_rules: JsonMapping | list[str],
|
|
78
|
+
*,
|
|
79
|
+
api_key: Key,
|
|
80
|
+
expires_at: datetime | None = None,
|
|
81
|
+
) -> str:
|
|
82
|
+
"""Generates a JWT token to use for searching.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
search_rules: Contains restrictions to use for the token. The default rules used for
|
|
86
|
+
the API key used for signing can be used by setting searchRules to ["*"]. If "indexes"
|
|
87
|
+
is included it must be equal to or more restrictive than the key used to generate the
|
|
88
|
+
token.
|
|
89
|
+
api_key: The API key to use to generate the token.
|
|
90
|
+
expires_at: The timepoint at which the token should expire. If value is provided it
|
|
91
|
+
should be a UTC time in the future. Default = None.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
A JWT token
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
InvalidRestriction: If the restrictions are less strict than the permissions allowed
|
|
98
|
+
in the API key.
|
|
99
|
+
KeyNotFoundError: If no API search key is found.
|
|
100
|
+
|
|
101
|
+
Examples:
|
|
102
|
+
Async:
|
|
103
|
+
|
|
104
|
+
>>> from datetime import datetime, timedelta, timezone
|
|
105
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
106
|
+
>>>
|
|
107
|
+
>>> expires_at = datetime.now(tz=timezone.utc) + timedelta(days=7)
|
|
108
|
+
>>>
|
|
109
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
110
|
+
>>> token = client.generate_tenant_token(
|
|
111
|
+
>>> search_rules = ["*"], api_key=api_key, expires_at=expires_at
|
|
112
|
+
>>> )
|
|
113
|
+
|
|
114
|
+
Sync:
|
|
115
|
+
|
|
116
|
+
>>> from datetime import datetime, timedelta, timezone
|
|
117
|
+
>>> from meilisearch_python_sdk import Client
|
|
118
|
+
>>>
|
|
119
|
+
>>> expires_at = datetime.now(tz=timezone.utc) + timedelta(days=7)
|
|
120
|
+
>>>
|
|
121
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
122
|
+
>>> token = client.generate_tenant_token(
|
|
123
|
+
>>> search_rules = ["*"], api_key=api_key, expires_at=expires_at
|
|
124
|
+
>>> )
|
|
125
|
+
"""
|
|
126
|
+
if isinstance(search_rules, dict) and search_rules.get("indexes"):
|
|
127
|
+
for index in search_rules["indexes"]:
|
|
128
|
+
if api_key.indexes != ["*"] and index not in api_key.indexes:
|
|
129
|
+
raise InvalidRestriction(
|
|
130
|
+
"Invalid index. The token cannot be less restrictive than the API key"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
payload: JsonDict = {"searchRules": search_rules}
|
|
134
|
+
|
|
135
|
+
payload["apiKeyUid"] = api_key.uid
|
|
136
|
+
if expires_at:
|
|
137
|
+
if expires_at <= datetime.now(tz=timezone.utc):
|
|
138
|
+
raise ValueError("expires_at must be a time in the future")
|
|
139
|
+
|
|
140
|
+
payload["exp"] = int(datetime.timestamp(expires_at))
|
|
141
|
+
|
|
142
|
+
return jwt.encode(payload, api_key.key, algorithm="HS256")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class AsyncClient(BaseClient):
|
|
146
|
+
"""Async client to connect to the Meilisearch API."""
|
|
147
|
+
|
|
148
|
+
def __init__(
|
|
149
|
+
self,
|
|
150
|
+
url: str,
|
|
151
|
+
api_key: str | None = None,
|
|
152
|
+
*,
|
|
153
|
+
timeout: int | None = None,
|
|
154
|
+
verify: bool | SSLContext = True,
|
|
155
|
+
custom_headers: dict[str, str] | None = None,
|
|
156
|
+
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
|
|
157
|
+
http2: bool = False,
|
|
158
|
+
) -> None:
|
|
159
|
+
"""Class initializer.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
url: The url to the Meilisearch API (ex: http://localhost:7700)
|
|
163
|
+
api_key: The optional API key for Meilisearch. Defaults to None.
|
|
164
|
+
timeout: The amount of time in seconds that the client will wait for a response before
|
|
165
|
+
timing out. Defaults to None.
|
|
166
|
+
verify: SSL certificates (a.k.a CA bundle) used to
|
|
167
|
+
verify the identity of requested hosts. Either `True` (default CA bundle),
|
|
168
|
+
a path to an SSL certificate file, or `False` (disable verification)
|
|
169
|
+
custom_headers: Custom headers to add when sending data to Meilisearch. Defaults to
|
|
170
|
+
None.
|
|
171
|
+
json_handler: The module to use for json operations. The options are BuiltinHandler
|
|
172
|
+
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
|
|
173
|
+
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
|
|
174
|
+
extra needs to be included. Default: BuiltinHandler.
|
|
175
|
+
http2: Whether or not to use HTTP/2. Defaults to False.
|
|
176
|
+
"""
|
|
177
|
+
super().__init__(api_key, custom_headers, json_handler)
|
|
178
|
+
|
|
179
|
+
self.http_client = HttpxAsyncClient(
|
|
180
|
+
base_url=url, timeout=timeout, headers=self._headers, verify=verify, http2=http2
|
|
181
|
+
)
|
|
182
|
+
self._http_requests = AsyncHttpRequests(self.http_client, json_handler=self.json_handler)
|
|
183
|
+
|
|
184
|
+
async def __aenter__(self) -> Self:
|
|
185
|
+
return self
|
|
186
|
+
|
|
187
|
+
async def __aexit__(
|
|
188
|
+
self,
|
|
189
|
+
et: type[BaseException] | None,
|
|
190
|
+
ev: type[BaseException] | None,
|
|
191
|
+
traceback: TracebackType | None,
|
|
192
|
+
) -> None:
|
|
193
|
+
await self.aclose()
|
|
194
|
+
|
|
195
|
+
async def aclose(self) -> None:
|
|
196
|
+
"""Closes the client.
|
|
197
|
+
|
|
198
|
+
This only needs to be used if the client was not created with a context manager.
|
|
199
|
+
"""
|
|
200
|
+
await self.http_client.aclose()
|
|
201
|
+
|
|
202
|
+
async def add_or_update_networks(self, *, network: Network) -> Network:
|
|
203
|
+
"""Set or update remote networks.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
network: Information to use for the networks.
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
An instance of Network containing the network information.
|
|
210
|
+
|
|
211
|
+
Raises:
|
|
212
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
213
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
214
|
+
|
|
215
|
+
Examples:
|
|
216
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
217
|
+
>>> from meilisearch_python_sdk.models.client import Network, Remote
|
|
218
|
+
>>>
|
|
219
|
+
>>>
|
|
220
|
+
>>> network = Network(
|
|
221
|
+
>>> self_="remote_1",
|
|
222
|
+
>>> remotes={
|
|
223
|
+
>>> "remote_1": {"url": "http://localhost:7700", "searchApiKey": "xxxx"},
|
|
224
|
+
>>> "remote_2": {"url": "http://localhost:7720", "searchApiKey": "xxxx"},
|
|
225
|
+
>>> },
|
|
226
|
+
>>> )
|
|
227
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
228
|
+
>>> response = await client.add_or_update_networks(network=network)
|
|
229
|
+
"""
|
|
230
|
+
response = await self._http_requests.patch(
|
|
231
|
+
"network", network.model_dump(by_alias=True, exclude_none=True)
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
return Network(**response.json())
|
|
235
|
+
|
|
236
|
+
async def get_networks(self) -> Network:
|
|
237
|
+
"""Fetches the remote-networks
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
An instance of Network containing information about each remote.
|
|
241
|
+
|
|
242
|
+
Raises:
|
|
243
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
244
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
245
|
+
|
|
246
|
+
Examples:
|
|
247
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
248
|
+
>>>
|
|
249
|
+
>>>
|
|
250
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
251
|
+
>>> response = await client.get_networks()
|
|
252
|
+
"""
|
|
253
|
+
response = await self._http_requests.get("network")
|
|
254
|
+
|
|
255
|
+
return Network(**response.json())
|
|
256
|
+
|
|
257
|
+
async def get_webhooks(self) -> Webhooks:
|
|
258
|
+
"""Get all webhooks.
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
An instance of Webhooks containing all configured webhooks.
|
|
262
|
+
|
|
263
|
+
Raises:
|
|
264
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
265
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
266
|
+
|
|
267
|
+
Examples:
|
|
268
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
269
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
270
|
+
>>> webhooks = await client.get_webhooks()
|
|
271
|
+
"""
|
|
272
|
+
response = await self._http_requests.get("webhooks")
|
|
273
|
+
|
|
274
|
+
return Webhooks(**response.json())
|
|
275
|
+
|
|
276
|
+
async def get_webhook(self, uuid: str) -> Webhook:
|
|
277
|
+
"""Get a specific webhook by UUID.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
uuid: The webhook's unique identifier.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
An instance of Webhook containing the webhook information.
|
|
284
|
+
|
|
285
|
+
Raises:
|
|
286
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
287
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
288
|
+
|
|
289
|
+
Examples:
|
|
290
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
291
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
292
|
+
>>> webhook = await client.get_webhook("abc-123")
|
|
293
|
+
"""
|
|
294
|
+
response = await self._http_requests.get(f"webhooks/{uuid}")
|
|
295
|
+
|
|
296
|
+
return Webhook(**response.json())
|
|
297
|
+
|
|
298
|
+
async def create_webhook(self, webhook: WebhookCreate) -> Webhook:
|
|
299
|
+
"""Create a new webhook.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
webhook: The webhook configuration to create.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
The created webhook.
|
|
306
|
+
|
|
307
|
+
Raises:
|
|
308
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
309
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
310
|
+
|
|
311
|
+
Examples:
|
|
312
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
313
|
+
>>> from meilisearch_python_sdk.models.webhook import WebhookCreate
|
|
314
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
315
|
+
>>> webhook_config = WebhookCreate(
|
|
316
|
+
>>> url="https://example.com/webhook",
|
|
317
|
+
>>> headers={"Authorization": "Bearer token"}
|
|
318
|
+
>>> )
|
|
319
|
+
>>> webhook = await client.create_webhook(webhook_config)
|
|
320
|
+
"""
|
|
321
|
+
response = await self._http_requests.post(
|
|
322
|
+
"webhooks", webhook.model_dump(by_alias=True, exclude_none=True)
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
return Webhook(**response.json())
|
|
326
|
+
|
|
327
|
+
async def update_webhook(self, *, uuid: str, webhook: WebhookUpdate) -> Webhook:
|
|
328
|
+
"""Update an existing webhook.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
uuid: The webhook's unique identifier.
|
|
332
|
+
webhook: The webhook configuration updates.
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
The updated webhook.
|
|
336
|
+
|
|
337
|
+
Raises:
|
|
338
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
339
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
340
|
+
|
|
341
|
+
Examples:
|
|
342
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
343
|
+
>>> from meilisearch_python_sdk.models.webhook import WebhookUpdate
|
|
344
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
345
|
+
>>> webhook_update = WebhookUpdate(url="https://example.com/new-webhook")
|
|
346
|
+
>>> webhook = await client.update_webhook("abc-123", webhook_update)
|
|
347
|
+
"""
|
|
348
|
+
response = await self._http_requests.patch(
|
|
349
|
+
f"webhooks/{uuid}", webhook.model_dump(by_alias=True, exclude_none=True)
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
return Webhook(**response.json())
|
|
353
|
+
|
|
354
|
+
async def delete_webhook(self, uuid: str) -> int:
|
|
355
|
+
"""Delete a webhook.
|
|
356
|
+
|
|
357
|
+
Args:
|
|
358
|
+
uuid: The webhook's unique identifier.
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
The Response status code. 204 signifies a successful delete.
|
|
362
|
+
|
|
363
|
+
Raises:
|
|
364
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
365
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
366
|
+
|
|
367
|
+
Examples:
|
|
368
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
369
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
370
|
+
>>> await client.delete_webhook("abc-123")
|
|
371
|
+
"""
|
|
372
|
+
response = await self._http_requests.delete(f"webhooks/{uuid}")
|
|
373
|
+
return response.status_code
|
|
374
|
+
|
|
375
|
+
async def create_dump(self) -> TaskInfo:
|
|
376
|
+
"""Trigger the creation of a Meilisearch dump.
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
The details of the task.
|
|
380
|
+
Raises:
|
|
381
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
382
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
383
|
+
|
|
384
|
+
Examples:
|
|
385
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
386
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
387
|
+
>>> await client.create_dump()
|
|
388
|
+
"""
|
|
389
|
+
response = await self._http_requests.post("dumps")
|
|
390
|
+
|
|
391
|
+
return TaskInfo(**response.json())
|
|
392
|
+
|
|
393
|
+
async def create_index(
|
|
394
|
+
self,
|
|
395
|
+
uid: str,
|
|
396
|
+
primary_key: str | None = None,
|
|
397
|
+
*,
|
|
398
|
+
settings: MeilisearchSettings | None = None,
|
|
399
|
+
wait: bool = True,
|
|
400
|
+
timeout_in_ms: int | None = None,
|
|
401
|
+
plugins: AsyncIndexPlugins | None = None,
|
|
402
|
+
hits_type: Any = JsonDict,
|
|
403
|
+
) -> AsyncIndex:
|
|
404
|
+
"""Creates a new index.
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
uid: The index's unique identifier.
|
|
408
|
+
primary_key: The primary key of the documents. Defaults to None.
|
|
409
|
+
settings: Settings for the index. The settings can also be updated independently of
|
|
410
|
+
creating the index. The advantage to updating them here is updating the settings after
|
|
411
|
+
adding documents will cause the documents to be re-indexed. Because of this it will be
|
|
412
|
+
faster to update them before adding documents. Defaults to None (i.e. default
|
|
413
|
+
Meilisearch index settings).
|
|
414
|
+
wait: If set to True and settings are being updated, the index will be returned after
|
|
415
|
+
the settings update has completed. If False it will not wait for settings to complete.
|
|
416
|
+
Default: True
|
|
417
|
+
timeout_in_ms: Amount of time in milliseconds to wait before raising a
|
|
418
|
+
MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
|
|
419
|
+
if the `None` option is used the wait time could be very long. Defaults to None.
|
|
420
|
+
plugins: Optional plugins can be provided to extend functionality.
|
|
421
|
+
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
|
|
422
|
+
JsonDict
|
|
423
|
+
|
|
424
|
+
Returns:
|
|
425
|
+
An instance of AsyncIndex containing the information of the newly created index.
|
|
426
|
+
|
|
427
|
+
Raises:
|
|
428
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
429
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
430
|
+
|
|
431
|
+
Examples:
|
|
432
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
433
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
434
|
+
>>> index = await client.create_index("movies")
|
|
435
|
+
"""
|
|
436
|
+
return await AsyncIndex.create(
|
|
437
|
+
self.http_client,
|
|
438
|
+
uid,
|
|
439
|
+
primary_key,
|
|
440
|
+
settings=settings,
|
|
441
|
+
wait=wait,
|
|
442
|
+
timeout_in_ms=timeout_in_ms,
|
|
443
|
+
plugins=plugins,
|
|
444
|
+
json_handler=self.json_handler,
|
|
445
|
+
hits_type=hits_type,
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
async def create_snapshot(self) -> TaskInfo:
|
|
449
|
+
"""Trigger the creation of a Meilisearch snapshot.
|
|
450
|
+
|
|
451
|
+
Returns:
|
|
452
|
+
The details of the task.
|
|
453
|
+
|
|
454
|
+
Raises:
|
|
455
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
456
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
457
|
+
|
|
458
|
+
Examples:
|
|
459
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
460
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
461
|
+
>>> await client.create_snapshot()
|
|
462
|
+
"""
|
|
463
|
+
response = await self._http_requests.post("snapshots")
|
|
464
|
+
|
|
465
|
+
return TaskInfo(**response.json())
|
|
466
|
+
|
|
467
|
+
async def delete_index_if_exists(self, uid: str) -> bool:
|
|
468
|
+
"""Deletes an index if it already exists.
|
|
469
|
+
|
|
470
|
+
Args:
|
|
471
|
+
uid: The index's unique identifier.
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
True if an index was deleted for False if not.
|
|
475
|
+
|
|
476
|
+
Raises:
|
|
477
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
478
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
479
|
+
|
|
480
|
+
Examples:
|
|
481
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
482
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
483
|
+
>>> await client.delete_index_if_exists()
|
|
484
|
+
"""
|
|
485
|
+
response = await self._http_requests.delete(f"indexes/{uid}")
|
|
486
|
+
status = await self.wait_for_task(response.json()["taskUid"], timeout_in_ms=100000)
|
|
487
|
+
if status.status == "succeeded":
|
|
488
|
+
return True
|
|
489
|
+
return False
|
|
490
|
+
|
|
491
|
+
async def get_indexes(
|
|
492
|
+
self, *, offset: int | None = None, limit: int | None = None
|
|
493
|
+
) -> list[AsyncIndex] | None:
|
|
494
|
+
"""Get all indexes.
|
|
495
|
+
|
|
496
|
+
Args:
|
|
497
|
+
offset: Number of indexes to skip. The default of None will use the Meilisearch
|
|
498
|
+
default.
|
|
499
|
+
limit: Number of indexes to return. The default of None will use the Meilisearch
|
|
500
|
+
default.
|
|
501
|
+
|
|
502
|
+
Returns:
|
|
503
|
+
A list of all indexes.
|
|
504
|
+
|
|
505
|
+
Raises:
|
|
506
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
507
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
508
|
+
|
|
509
|
+
Examples:
|
|
510
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
511
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
512
|
+
>>> indexes = await client.get_indexes()
|
|
513
|
+
"""
|
|
514
|
+
url = _build_offset_limit_url("indexes", offset, limit)
|
|
515
|
+
response = await self._http_requests.get(url)
|
|
516
|
+
|
|
517
|
+
if not response.json()["results"]:
|
|
518
|
+
return None
|
|
519
|
+
|
|
520
|
+
return [
|
|
521
|
+
AsyncIndex(
|
|
522
|
+
http_client=self.http_client,
|
|
523
|
+
uid=x["uid"],
|
|
524
|
+
primary_key=x["primaryKey"],
|
|
525
|
+
created_at=x["createdAt"],
|
|
526
|
+
updated_at=x["updatedAt"],
|
|
527
|
+
json_handler=self.json_handler,
|
|
528
|
+
)
|
|
529
|
+
for x in response.json()["results"]
|
|
530
|
+
]
|
|
531
|
+
|
|
532
|
+
async def get_index(self, uid: str) -> AsyncIndex:
|
|
533
|
+
"""Gets a single index based on the uid of the index.
|
|
534
|
+
|
|
535
|
+
Args:
|
|
536
|
+
uid: The index's unique identifier.
|
|
537
|
+
|
|
538
|
+
Returns:
|
|
539
|
+
An AsyncIndex instance containing the information of the fetched index.
|
|
540
|
+
|
|
541
|
+
Raises:
|
|
542
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
543
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
544
|
+
|
|
545
|
+
Examples:
|
|
546
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
547
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
548
|
+
>>> index = await client.get_index()
|
|
549
|
+
"""
|
|
550
|
+
return await AsyncIndex(self.http_client, uid, json_handler=self.json_handler).fetch_info()
|
|
551
|
+
|
|
552
|
+
def index(self, uid: str, *, plugins: AsyncIndexPlugins | None = None) -> AsyncIndex:
|
|
553
|
+
"""Create a local reference to an index identified by UID, without making an HTTP call.
|
|
554
|
+
|
|
555
|
+
Because no network call is made this method is not awaitable.
|
|
556
|
+
|
|
557
|
+
Args:
|
|
558
|
+
uid: The index's unique identifier.
|
|
559
|
+
plugins: Optional plugins can be provided to extend functionality.
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
An AsyncIndex instance.
|
|
563
|
+
|
|
564
|
+
Raises:
|
|
565
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
566
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
567
|
+
|
|
568
|
+
Examples:
|
|
569
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
570
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
571
|
+
>>> index = client.index("movies")
|
|
572
|
+
"""
|
|
573
|
+
return AsyncIndex(
|
|
574
|
+
self.http_client, uid=uid, plugins=plugins, json_handler=self.json_handler
|
|
575
|
+
)
|
|
576
|
+
|
|
577
|
+
async def get_all_stats(self) -> ClientStats:
|
|
578
|
+
"""Get stats for all indexes.
|
|
579
|
+
|
|
580
|
+
Returns:
|
|
581
|
+
Information about database size and all indexes.
|
|
582
|
+
https://docs.meilisearch.com/reference/api/stats.html
|
|
583
|
+
|
|
584
|
+
Raises:
|
|
585
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
586
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
587
|
+
|
|
588
|
+
Examples
|
|
589
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
590
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
591
|
+
>>> stats = await client.get_all_stats()
|
|
592
|
+
"""
|
|
593
|
+
response = await self._http_requests.get("stats")
|
|
594
|
+
|
|
595
|
+
return ClientStats(**response.json())
|
|
596
|
+
|
|
597
|
+
async def get_or_create_index(
|
|
598
|
+
self,
|
|
599
|
+
uid: str,
|
|
600
|
+
primary_key: str | None = None,
|
|
601
|
+
*,
|
|
602
|
+
plugins: AsyncIndexPlugins | None = None,
|
|
603
|
+
hits_type: Any = JsonDict,
|
|
604
|
+
) -> AsyncIndex:
|
|
605
|
+
"""Get an index, or create it if it doesn't exist.
|
|
606
|
+
|
|
607
|
+
Args:
|
|
608
|
+
uid: The index's unique identifier.
|
|
609
|
+
primary_key: The primary key of the documents. Defaults to None.
|
|
610
|
+
plugins: Optional plugins can be provided to extend functionality.
|
|
611
|
+
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
|
|
612
|
+
JsonDict
|
|
613
|
+
|
|
614
|
+
Returns:
|
|
615
|
+
An instance of AsyncIndex containing the information of the retrieved or newly created index.
|
|
616
|
+
|
|
617
|
+
Raises:
|
|
618
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
619
|
+
MeilisearchApiError: If the Meilisearch API returned an error.MeilisearchTimeoutError: If the connection times out.
|
|
620
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
621
|
+
|
|
622
|
+
Examples
|
|
623
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
624
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
625
|
+
>>> index = await client.get_or_create_index("movies")
|
|
626
|
+
"""
|
|
627
|
+
try:
|
|
628
|
+
index_instance = await self.get_index(uid)
|
|
629
|
+
except MeilisearchApiError as err:
|
|
630
|
+
if "index_not_found" not in err.code:
|
|
631
|
+
raise
|
|
632
|
+
index_instance = await self.create_index(
|
|
633
|
+
uid, primary_key, plugins=plugins, hits_type=hits_type
|
|
634
|
+
)
|
|
635
|
+
return index_instance
|
|
636
|
+
|
|
637
|
+
async def create_key(self, key: KeyCreate) -> Key:
|
|
638
|
+
"""Creates a new API key.
|
|
639
|
+
|
|
640
|
+
Args:
|
|
641
|
+
key: The information to use in creating the key. Note that if an expires_at value
|
|
642
|
+
is included it should be in UTC time.
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
The new API key.
|
|
646
|
+
|
|
647
|
+
Raises:
|
|
648
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
649
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
650
|
+
|
|
651
|
+
Examples
|
|
652
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
653
|
+
>>> from meilissearch_async_client.models.client import KeyCreate
|
|
654
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
655
|
+
>>> key_info = KeyCreate(
|
|
656
|
+
>>> description="My new key",
|
|
657
|
+
>>> actions=["search"],
|
|
658
|
+
>>> indexes=["movies"],
|
|
659
|
+
>>> )
|
|
660
|
+
>>> keys = await client.create_key(key_info)
|
|
661
|
+
"""
|
|
662
|
+
response = await self._http_requests.post(
|
|
663
|
+
"keys", self.json_handler.loads(key.model_dump_json(by_alias=True))
|
|
664
|
+
) # type: ignore[attr-defined]
|
|
665
|
+
|
|
666
|
+
return Key(**response.json())
|
|
667
|
+
|
|
668
|
+
async def delete_key(self, key: str) -> int:
|
|
669
|
+
"""Deletes an API key.
|
|
670
|
+
|
|
671
|
+
Args:
|
|
672
|
+
key: The key or uid to delete.
|
|
673
|
+
|
|
674
|
+
Returns:
|
|
675
|
+
The Response status code. 204 signifies a successful delete.
|
|
676
|
+
|
|
677
|
+
Raises:
|
|
678
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
679
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
680
|
+
|
|
681
|
+
Examples
|
|
682
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
683
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
684
|
+
>>> await client.delete_key("abc123")
|
|
685
|
+
"""
|
|
686
|
+
response = await self._http_requests.delete(f"keys/{key}")
|
|
687
|
+
return response.status_code
|
|
688
|
+
|
|
689
|
+
async def get_keys(self, *, offset: int | None = None, limit: int | None = None) -> KeySearch:
|
|
690
|
+
"""Gets the Meilisearch API keys.
|
|
691
|
+
|
|
692
|
+
Args:
|
|
693
|
+
offset: Number of indexes to skip. The default of None will use the Meilisearch
|
|
694
|
+
default.
|
|
695
|
+
limit: Number of indexes to return. The default of None will use the Meilisearch
|
|
696
|
+
default.
|
|
697
|
+
|
|
698
|
+
Returns:
|
|
699
|
+
API keys.
|
|
700
|
+
|
|
701
|
+
Raises:
|
|
702
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
703
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
704
|
+
|
|
705
|
+
Examples
|
|
706
|
+
from meilisearch_python_sdk import AsyncClient
|
|
707
|
+
async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
708
|
+
keys = await client.get_keys()
|
|
709
|
+
"""
|
|
710
|
+
url = _build_offset_limit_url("keys", offset, limit)
|
|
711
|
+
response = await self._http_requests.get(url)
|
|
712
|
+
|
|
713
|
+
return KeySearch(**response.json())
|
|
714
|
+
|
|
715
|
+
async def get_key(self, key: str) -> Key:
|
|
716
|
+
"""Gets information about a specific API key.
|
|
717
|
+
|
|
718
|
+
Args:
|
|
719
|
+
key: The key for which to retrieve the information.
|
|
720
|
+
|
|
721
|
+
Returns:
|
|
722
|
+
The API key, or `None` if the key is not found.
|
|
723
|
+
|
|
724
|
+
Raises:
|
|
725
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
726
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
727
|
+
|
|
728
|
+
Examples
|
|
729
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
730
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
731
|
+
>>> keys = await client.get_key("abc123")
|
|
732
|
+
"""
|
|
733
|
+
response = await self._http_requests.get(f"keys/{key}")
|
|
734
|
+
|
|
735
|
+
return Key(**response.json())
|
|
736
|
+
|
|
737
|
+
async def update_key(self, key: KeyUpdate) -> Key:
|
|
738
|
+
"""Update an API key.
|
|
739
|
+
|
|
740
|
+
Args:
|
|
741
|
+
key: The information to use in updating the key. Note that if an expires_at value
|
|
742
|
+
is included it should be in UTC time.
|
|
743
|
+
|
|
744
|
+
Returns:
|
|
745
|
+
The updated API key.
|
|
746
|
+
|
|
747
|
+
Raises:
|
|
748
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
749
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
750
|
+
|
|
751
|
+
Examples
|
|
752
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
753
|
+
>>> from meilissearch_async_client.models.client import KeyUpdate
|
|
754
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
755
|
+
>>> key_info = KeyUpdate(
|
|
756
|
+
key="abc123",
|
|
757
|
+
>>> indexes=["*"],
|
|
758
|
+
>>> )
|
|
759
|
+
>>> keys = await client.update_key(key_info)
|
|
760
|
+
"""
|
|
761
|
+
payload = _build_update_key_payload(key, self.json_handler)
|
|
762
|
+
response = await self._http_requests.patch(f"keys/{key.key}", payload)
|
|
763
|
+
|
|
764
|
+
return Key(**response.json())
|
|
765
|
+
|
|
766
|
+
async def multi_search(
|
|
767
|
+
self,
|
|
768
|
+
queries: list[SearchParams],
|
|
769
|
+
*,
|
|
770
|
+
federation: Federation | FederationMerged | None = None,
|
|
771
|
+
hits_type: Any = JsonDict,
|
|
772
|
+
) -> list[SearchResultsWithUID] | SearchResultsFederated:
|
|
773
|
+
"""Multi-index search.
|
|
774
|
+
|
|
775
|
+
Args:
|
|
776
|
+
queries: List of SearchParameters
|
|
777
|
+
federation: If included a single search result with hits built from all queries will
|
|
778
|
+
be returned. This parameter can only be used with Meilisearch >= v1.10.0. Defaults
|
|
779
|
+
to None.
|
|
780
|
+
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
|
|
781
|
+
JsonDict
|
|
782
|
+
|
|
783
|
+
Returns:
|
|
784
|
+
Results of the search
|
|
785
|
+
|
|
786
|
+
Raises:
|
|
787
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
788
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
789
|
+
|
|
790
|
+
Examples
|
|
791
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
792
|
+
>>> from meilisearch_python_sdk.models.search import SearchParams
|
|
793
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
794
|
+
>>> queries = [
|
|
795
|
+
>>> SearchParams(index_uid="my_first_index", query"Some search"),
|
|
796
|
+
>>> SearchParams(index_uid="my_second_index", query="Another search")
|
|
797
|
+
>>> ]
|
|
798
|
+
>>> search_results = await client.search(queries)
|
|
799
|
+
"""
|
|
800
|
+
url = "multi-search"
|
|
801
|
+
processed_queries = []
|
|
802
|
+
for query in queries:
|
|
803
|
+
q = query.model_dump(by_alias=True)
|
|
804
|
+
|
|
805
|
+
if query.retrieve_vectors is None:
|
|
806
|
+
del q["retrieveVectors"]
|
|
807
|
+
|
|
808
|
+
if federation:
|
|
809
|
+
del q["limit"]
|
|
810
|
+
del q["offset"]
|
|
811
|
+
|
|
812
|
+
if query.media is None:
|
|
813
|
+
del q["media"]
|
|
814
|
+
|
|
815
|
+
processed_queries.append(q)
|
|
816
|
+
|
|
817
|
+
if federation:
|
|
818
|
+
federation_payload = federation.model_dump(by_alias=True)
|
|
819
|
+
if federation.facets_by_index is None:
|
|
820
|
+
del federation_payload["facetsByIndex"]
|
|
821
|
+
|
|
822
|
+
else:
|
|
823
|
+
federation_payload = None
|
|
824
|
+
|
|
825
|
+
response = await self._http_requests.post(
|
|
826
|
+
url,
|
|
827
|
+
body={
|
|
828
|
+
"federation": federation_payload,
|
|
829
|
+
"queries": processed_queries,
|
|
830
|
+
},
|
|
831
|
+
)
|
|
832
|
+
|
|
833
|
+
if federation:
|
|
834
|
+
results = response.json()
|
|
835
|
+
return SearchResultsFederated[hits_type](**results)
|
|
836
|
+
|
|
837
|
+
return [SearchResultsWithUID[hits_type](**x) for x in response.json()["results"]]
|
|
838
|
+
|
|
839
|
+
async def get_raw_index(self, uid: str) -> IndexInfo | None:
|
|
840
|
+
"""Gets the index and returns all the index information rather than an AsyncIndex instance.
|
|
841
|
+
|
|
842
|
+
Args:
|
|
843
|
+
uid: The index's unique identifier.
|
|
844
|
+
|
|
845
|
+
Returns:
|
|
846
|
+
Index information rather than an AsyncIndex instance.
|
|
847
|
+
|
|
848
|
+
Raises:
|
|
849
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
850
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
851
|
+
|
|
852
|
+
Examples
|
|
853
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
854
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
855
|
+
>>> index = await client.get_raw_index("movies")
|
|
856
|
+
"""
|
|
857
|
+
response = await self.http_client.get(f"indexes/{uid}")
|
|
858
|
+
|
|
859
|
+
if response.status_code == 404:
|
|
860
|
+
return None
|
|
861
|
+
|
|
862
|
+
return IndexInfo(**response.json())
|
|
863
|
+
|
|
864
|
+
async def get_raw_indexes(
|
|
865
|
+
self, *, offset: int | None = None, limit: int | None = None
|
|
866
|
+
) -> list[IndexInfo] | None:
|
|
867
|
+
"""Gets all the indexes.
|
|
868
|
+
|
|
869
|
+
Args:
|
|
870
|
+
offset: Number of indexes to skip. The default of None will use the Meilisearch
|
|
871
|
+
default.
|
|
872
|
+
limit: Number of indexes to return. The default of None will use the Meilisearch
|
|
873
|
+
default.
|
|
874
|
+
|
|
875
|
+
Returns all the index information rather than an AsyncIndex instance.
|
|
876
|
+
|
|
877
|
+
Returns:
|
|
878
|
+
A list of the Index information rather than an AsyncIndex instances.
|
|
879
|
+
|
|
880
|
+
Raises:
|
|
881
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
882
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
883
|
+
|
|
884
|
+
Examples
|
|
885
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
886
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
887
|
+
>>> index = await client.get_raw_indexes()
|
|
888
|
+
"""
|
|
889
|
+
url = _build_offset_limit_url("indexes", offset, limit)
|
|
890
|
+
response = await self._http_requests.get(url)
|
|
891
|
+
|
|
892
|
+
if not response.json()["results"]:
|
|
893
|
+
return None
|
|
894
|
+
|
|
895
|
+
return [IndexInfo(**x) for x in response.json()["results"]]
|
|
896
|
+
|
|
897
|
+
async def get_version(self) -> Version:
|
|
898
|
+
"""Get the Meilisearch version.
|
|
899
|
+
|
|
900
|
+
Returns:
|
|
901
|
+
Information about the version of Meilisearch.
|
|
902
|
+
|
|
903
|
+
Raises:
|
|
904
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
905
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
906
|
+
|
|
907
|
+
Examples
|
|
908
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
909
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
910
|
+
>>> version = await client.get_version()
|
|
911
|
+
"""
|
|
912
|
+
response = await self._http_requests.get("version")
|
|
913
|
+
|
|
914
|
+
return Version(**response.json())
|
|
915
|
+
|
|
916
|
+
async def health(self) -> Health:
|
|
917
|
+
"""Get health of the Meilisearch server.
|
|
918
|
+
|
|
919
|
+
Returns:
|
|
920
|
+
The status of the Meilisearch server.
|
|
921
|
+
|
|
922
|
+
Raises:
|
|
923
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
924
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
925
|
+
|
|
926
|
+
Examples
|
|
927
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
928
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
929
|
+
>>> health = await client.get_health()
|
|
930
|
+
"""
|
|
931
|
+
response = await self._http_requests.get("health")
|
|
932
|
+
|
|
933
|
+
return Health(**response.json())
|
|
934
|
+
|
|
935
|
+
async def swap_indexes(self, indexes: list[tuple[str, str]], rename: bool = False) -> TaskInfo:
|
|
936
|
+
"""Swap two indexes.
|
|
937
|
+
|
|
938
|
+
Args:
|
|
939
|
+
indexes: A list of tuples, each tuple should contain the indexes to swap.
|
|
940
|
+
rename: Use rename false if you are swapping two existing indexes. Use rename true if
|
|
941
|
+
the second index in your array does not exist. Default = False
|
|
942
|
+
|
|
943
|
+
Returns:
|
|
944
|
+
The details of the task.
|
|
945
|
+
|
|
946
|
+
Raises:
|
|
947
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
948
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
949
|
+
|
|
950
|
+
Examples
|
|
951
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
952
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
953
|
+
>>> index = await client.swap_indexes([("index_a", "index_b")])
|
|
954
|
+
"""
|
|
955
|
+
if rename:
|
|
956
|
+
processed_indexes = [{"indexes": x, "rename": True} for x in indexes]
|
|
957
|
+
else:
|
|
958
|
+
processed_indexes = [{"indexes": x} for x in indexes]
|
|
959
|
+
response = await self._http_requests.post("swap-indexes", processed_indexes)
|
|
960
|
+
|
|
961
|
+
return TaskInfo(**response.json())
|
|
962
|
+
|
|
963
|
+
async def get_batch(self, batch_uid: int) -> BatchResult | None:
|
|
964
|
+
return await async_get_batch(self, batch_uid)
|
|
965
|
+
|
|
966
|
+
async def get_batches(
|
|
967
|
+
self,
|
|
968
|
+
*,
|
|
969
|
+
uids: list[int] | None = None,
|
|
970
|
+
batch_uids: list[int] | None = None,
|
|
971
|
+
index_uids: list[int] | None = None,
|
|
972
|
+
statuses: list[str] | None = None,
|
|
973
|
+
types: list[str] | None = None,
|
|
974
|
+
limit: int = 20,
|
|
975
|
+
from_: str | None = None,
|
|
976
|
+
reverse: bool = False,
|
|
977
|
+
before_enqueued_at: datetime | None = None,
|
|
978
|
+
after_enqueued_at: datetime | None = None,
|
|
979
|
+
before_started_at: datetime | None = None,
|
|
980
|
+
after_finished_at: datetime | None = None,
|
|
981
|
+
) -> BatchStatus:
|
|
982
|
+
return await async_get_batches(
|
|
983
|
+
self,
|
|
984
|
+
uids=uids,
|
|
985
|
+
batch_uids=batch_uids,
|
|
986
|
+
index_uids=index_uids,
|
|
987
|
+
statuses=statuses,
|
|
988
|
+
types=types,
|
|
989
|
+
limit=limit,
|
|
990
|
+
from_=from_,
|
|
991
|
+
reverse=reverse,
|
|
992
|
+
before_enqueued_at=before_enqueued_at,
|
|
993
|
+
after_enqueued_at=after_enqueued_at,
|
|
994
|
+
before_started_at=before_started_at,
|
|
995
|
+
after_finished_at=after_finished_at,
|
|
996
|
+
)
|
|
997
|
+
|
|
998
|
+
async def cancel_tasks(
|
|
999
|
+
self,
|
|
1000
|
+
*,
|
|
1001
|
+
uids: list[int] | None = None,
|
|
1002
|
+
index_uids: list[int] | None = None,
|
|
1003
|
+
statuses: list[str] | None = None,
|
|
1004
|
+
types: list[str] | None = None,
|
|
1005
|
+
before_enqueued_at: datetime | None = None,
|
|
1006
|
+
after_enqueued_at: datetime | None = None,
|
|
1007
|
+
before_started_at: datetime | None = None,
|
|
1008
|
+
after_finished_at: datetime | None = None,
|
|
1009
|
+
) -> TaskInfo:
|
|
1010
|
+
"""Cancel a list of enqueued or processing tasks.
|
|
1011
|
+
|
|
1012
|
+
Defaults to cancelling all tasks.
|
|
1013
|
+
|
|
1014
|
+
Args:
|
|
1015
|
+
uids: A list of task UIDs to cancel.
|
|
1016
|
+
index_uids: A list of index UIDs for which to cancel tasks.
|
|
1017
|
+
statuses: A list of statuses to cancel.
|
|
1018
|
+
types: A list of types to cancel.
|
|
1019
|
+
before_enqueued_at: Cancel tasks that were enqueued before the specified date time.
|
|
1020
|
+
after_enqueued_at: Cancel tasks that were enqueued after the specified date time.
|
|
1021
|
+
before_started_at: Cancel tasks that were started before the specified date time.
|
|
1022
|
+
after_finished_at: Cancel tasks that were finished after the specified date time.
|
|
1023
|
+
|
|
1024
|
+
Returns:
|
|
1025
|
+
The details of the task
|
|
1026
|
+
|
|
1027
|
+
Raises:
|
|
1028
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1029
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1030
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1031
|
+
|
|
1032
|
+
Examples
|
|
1033
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1034
|
+
>>>
|
|
1035
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1036
|
+
>>> await client.cancel_tasks(uids=[1, 2])
|
|
1037
|
+
"""
|
|
1038
|
+
return await _task.async_cancel_tasks(
|
|
1039
|
+
self.http_client,
|
|
1040
|
+
uids=uids,
|
|
1041
|
+
index_uids=index_uids,
|
|
1042
|
+
statuses=statuses,
|
|
1043
|
+
types=types,
|
|
1044
|
+
before_enqueued_at=before_enqueued_at,
|
|
1045
|
+
after_enqueued_at=after_enqueued_at,
|
|
1046
|
+
before_started_at=before_started_at,
|
|
1047
|
+
after_finished_at=after_finished_at,
|
|
1048
|
+
)
|
|
1049
|
+
|
|
1050
|
+
async def get_task(self, task_id: int) -> TaskResult:
|
|
1051
|
+
"""Get a single task from it's task id.
|
|
1052
|
+
|
|
1053
|
+
Args:
|
|
1054
|
+
task_id: Identifier of the task to retrieve.
|
|
1055
|
+
|
|
1056
|
+
Returns:
|
|
1057
|
+
Results of a task.
|
|
1058
|
+
|
|
1059
|
+
Raises:
|
|
1060
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1061
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1062
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1063
|
+
|
|
1064
|
+
Examples
|
|
1065
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1066
|
+
>>> from meilisearch_python_sdk.task import get_task
|
|
1067
|
+
>>>
|
|
1068
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1069
|
+
>>> await client.get_task(client, 1244)
|
|
1070
|
+
"""
|
|
1071
|
+
return await _task.async_get_task(self.http_client, task_id=task_id)
|
|
1072
|
+
|
|
1073
|
+
async def delete_tasks(
|
|
1074
|
+
self,
|
|
1075
|
+
*,
|
|
1076
|
+
uids: list[int] | None = None,
|
|
1077
|
+
index_uids: list[int] | None = None,
|
|
1078
|
+
statuses: list[str] | None = None,
|
|
1079
|
+
types: list[str] | None = None,
|
|
1080
|
+
before_enqueued_at: datetime | None = None,
|
|
1081
|
+
after_enqueued_at: datetime | None = None,
|
|
1082
|
+
before_started_at: datetime | None = None,
|
|
1083
|
+
after_finished_at: datetime | None = None,
|
|
1084
|
+
) -> TaskInfo:
|
|
1085
|
+
"""Delete a list of tasks.
|
|
1086
|
+
|
|
1087
|
+
Defaults to deleting all tasks.
|
|
1088
|
+
|
|
1089
|
+
Args:
|
|
1090
|
+
uids: A list of task UIDs to delete.
|
|
1091
|
+
index_uids: A list of index UIDs for which to delete tasks.
|
|
1092
|
+
statuses: A list of statuses to delete.
|
|
1093
|
+
types: A list of types to delete.
|
|
1094
|
+
before_enqueued_at: Delete tasks that were enqueued before the specified date time.
|
|
1095
|
+
after_enqueued_at: Delete tasks that were enqueued after the specified date time.
|
|
1096
|
+
before_started_at: Delete tasks that were started before the specified date time.
|
|
1097
|
+
after_finished_at: Delete tasks that were finished after the specified date time.
|
|
1098
|
+
|
|
1099
|
+
Returns:
|
|
1100
|
+
The details of the task
|
|
1101
|
+
|
|
1102
|
+
Raises:
|
|
1103
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1104
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1105
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1106
|
+
|
|
1107
|
+
Examples
|
|
1108
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1109
|
+
>>> from meilisearch_python_sdk.task import delete_tasks
|
|
1110
|
+
>>>
|
|
1111
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1112
|
+
>>> await client.delete_tasks(uids=[1, 2])
|
|
1113
|
+
"""
|
|
1114
|
+
return await _task.async_delete_tasks(
|
|
1115
|
+
self.http_client,
|
|
1116
|
+
uids=uids,
|
|
1117
|
+
index_uids=index_uids,
|
|
1118
|
+
statuses=statuses,
|
|
1119
|
+
types=types,
|
|
1120
|
+
before_enqueued_at=before_enqueued_at,
|
|
1121
|
+
after_enqueued_at=after_enqueued_at,
|
|
1122
|
+
before_started_at=before_started_at,
|
|
1123
|
+
after_finished_at=after_finished_at,
|
|
1124
|
+
)
|
|
1125
|
+
|
|
1126
|
+
async def get_tasks(
|
|
1127
|
+
self,
|
|
1128
|
+
*,
|
|
1129
|
+
index_ids: list[str] | None = None,
|
|
1130
|
+
types: str | list[str] | None = None,
|
|
1131
|
+
reverse: bool | None = None,
|
|
1132
|
+
) -> TaskStatus:
|
|
1133
|
+
"""Get multiple tasks.
|
|
1134
|
+
|
|
1135
|
+
Args:
|
|
1136
|
+
index_ids: A list of index UIDs for which to get the tasks. If provided this will get the
|
|
1137
|
+
tasks only for the specified indexes, if not all tasks will be returned. Default = None
|
|
1138
|
+
types: Specify specific task types to retrieve. Default = None
|
|
1139
|
+
reverse: If True the tasks will be returned in reverse order. Default = None
|
|
1140
|
+
|
|
1141
|
+
Returns:
|
|
1142
|
+
Task statuses.
|
|
1143
|
+
|
|
1144
|
+
Raises:
|
|
1145
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1146
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1147
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1148
|
+
|
|
1149
|
+
Examples
|
|
1150
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1151
|
+
>>>
|
|
1152
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1153
|
+
>>> await client.get_tasks()
|
|
1154
|
+
"""
|
|
1155
|
+
return await _task.async_get_tasks(
|
|
1156
|
+
self.http_client, index_ids=index_ids, types=types, reverse=reverse
|
|
1157
|
+
)
|
|
1158
|
+
|
|
1159
|
+
async def wait_for_task(
|
|
1160
|
+
self,
|
|
1161
|
+
task_id: int,
|
|
1162
|
+
*,
|
|
1163
|
+
timeout_in_ms: int | None = 5000,
|
|
1164
|
+
interval_in_ms: int = 50,
|
|
1165
|
+
raise_for_status: bool = False,
|
|
1166
|
+
) -> TaskResult:
|
|
1167
|
+
"""Wait until Meilisearch processes a task, and get its status.
|
|
1168
|
+
|
|
1169
|
+
Args:
|
|
1170
|
+
task_id: Identifier of the task to retrieve.
|
|
1171
|
+
timeout_in_ms: Amount of time in milliseconds to wait before raising a
|
|
1172
|
+
MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
|
|
1173
|
+
if the `None` option is used the wait time could be very long. Defaults to 5000.
|
|
1174
|
+
interval_in_ms: Time interval in milliseconds to sleep between requests. Defaults to 50.
|
|
1175
|
+
raise_for_status: When set to `True` a MeilisearchTaskFailedError will be raised if a task
|
|
1176
|
+
has a failed status. Defaults to False.
|
|
1177
|
+
|
|
1178
|
+
Returns:
|
|
1179
|
+
Details of the processed update status.
|
|
1180
|
+
|
|
1181
|
+
Raises:
|
|
1182
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1183
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1184
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1185
|
+
MeilisearchTaskFailedError: If `raise_for_status` is `True` and a task has a failed status.
|
|
1186
|
+
|
|
1187
|
+
Examples
|
|
1188
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1189
|
+
>>> documents = [
|
|
1190
|
+
>>> {"id": 1, "title": "Movie 1", "genre": "comedy"},
|
|
1191
|
+
>>> {"id": 2, "title": "Movie 2", "genre": "drama"},
|
|
1192
|
+
>>> ]
|
|
1193
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1194
|
+
>>> index = client.index("movies")
|
|
1195
|
+
>>> response = await index.add_documents(documents)
|
|
1196
|
+
>>> await client.wait_for_task(client, response.update_id)
|
|
1197
|
+
"""
|
|
1198
|
+
return await _task.async_wait_for_task(
|
|
1199
|
+
self.http_client,
|
|
1200
|
+
task_id=task_id,
|
|
1201
|
+
timeout_in_ms=timeout_in_ms,
|
|
1202
|
+
interval_in_ms=interval_in_ms,
|
|
1203
|
+
raise_for_status=raise_for_status,
|
|
1204
|
+
)
|
|
1205
|
+
|
|
1206
|
+
# No cover because it requires multiple instances of Meilisearch
|
|
1207
|
+
async def transfer_documents( # pragma: no cover
|
|
1208
|
+
self,
|
|
1209
|
+
url: str,
|
|
1210
|
+
*,
|
|
1211
|
+
api_key: str | None = None,
|
|
1212
|
+
payload_size: str | None = None,
|
|
1213
|
+
indexes: JsonMapping | None = None,
|
|
1214
|
+
) -> TaskInfo:
|
|
1215
|
+
"""Transfer settings and documents from one Meilisearch instance to another.
|
|
1216
|
+
|
|
1217
|
+
Args:
|
|
1218
|
+
url: Where to send our settings and documents.
|
|
1219
|
+
api_key: The API key with the rights to send the requests. Usually the master key of
|
|
1220
|
+
the remote machine. Defaults to None.
|
|
1221
|
+
payload_size: Human readable size defining the size of the payloads to send. Defaults
|
|
1222
|
+
to 50 MiB.
|
|
1223
|
+
indexes: A set of patterns of matching the indexes you want to export. Defaults to all
|
|
1224
|
+
indexes without filter.
|
|
1225
|
+
|
|
1226
|
+
Returns:
|
|
1227
|
+
The details of the task.
|
|
1228
|
+
|
|
1229
|
+
Raises:
|
|
1230
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1231
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1232
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1233
|
+
|
|
1234
|
+
Examples
|
|
1235
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1236
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1237
|
+
>>> await index.transfer_documents(
|
|
1238
|
+
>>> "https://another-instance.com", api_key="otherMasterKey"
|
|
1239
|
+
>>> )
|
|
1240
|
+
"""
|
|
1241
|
+
payload: JsonDict = {"url": url}
|
|
1242
|
+
|
|
1243
|
+
if api_key:
|
|
1244
|
+
payload["apiKey"] = api_key
|
|
1245
|
+
|
|
1246
|
+
if payload:
|
|
1247
|
+
payload["payloadSize"] = payload_size
|
|
1248
|
+
|
|
1249
|
+
if indexes:
|
|
1250
|
+
payload["indexes"] = indexes
|
|
1251
|
+
|
|
1252
|
+
response = await self._http_requests.post(url, body=payload)
|
|
1253
|
+
|
|
1254
|
+
return TaskInfo(**response.json())
|
|
1255
|
+
|
|
1256
|
+
async def get_experimental_features(self) -> dict[str, bool]:
|
|
1257
|
+
"""Gets all experimental features and if they are enabled or not.
|
|
1258
|
+
|
|
1259
|
+
Returns:
|
|
1260
|
+
The status of the experimental features.
|
|
1261
|
+
|
|
1262
|
+
Raises:
|
|
1263
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1264
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1265
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1266
|
+
|
|
1267
|
+
Examples
|
|
1268
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1269
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1270
|
+
>>> await index.get_experimental_feature()
|
|
1271
|
+
"""
|
|
1272
|
+
|
|
1273
|
+
response = await self._http_requests.get("/experimental-features")
|
|
1274
|
+
return response.json()
|
|
1275
|
+
|
|
1276
|
+
async def update_experimental_features(self, features: dict[str, bool]) -> dict[str, bool]:
|
|
1277
|
+
"""Update the status of an experimental feature.
|
|
1278
|
+
|
|
1279
|
+
Args:
|
|
1280
|
+
features: Dictionary of features to enable/disable. The dictionary keys can be in either
|
|
1281
|
+
camel case or snake case, the conversion to the correct type will be handed for you by
|
|
1282
|
+
the program. For example {"logsRoute": True} and {"logs_route": True} will both work.
|
|
1283
|
+
|
|
1284
|
+
Returns:
|
|
1285
|
+
The status of the experimental features.
|
|
1286
|
+
|
|
1287
|
+
Raises:
|
|
1288
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1289
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1290
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1291
|
+
|
|
1292
|
+
Examples
|
|
1293
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1294
|
+
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
|
|
1295
|
+
>>> await index.update_experimental_features({"logsRoute": True})
|
|
1296
|
+
"""
|
|
1297
|
+
payload = dict_to_camel(features)
|
|
1298
|
+
response = await self._http_requests.patch("/experimental-features", body=payload)
|
|
1299
|
+
|
|
1300
|
+
return response.json()
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
class Client(BaseClient):
|
|
1304
|
+
"""client to connect to the Meilisearch API."""
|
|
1305
|
+
|
|
1306
|
+
def __init__(
|
|
1307
|
+
self,
|
|
1308
|
+
url: str,
|
|
1309
|
+
api_key: str | None = None,
|
|
1310
|
+
*,
|
|
1311
|
+
timeout: int | None = None,
|
|
1312
|
+
verify: bool | SSLContext = True,
|
|
1313
|
+
custom_headers: dict[str, str] | None = None,
|
|
1314
|
+
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
|
|
1315
|
+
http2: bool = False,
|
|
1316
|
+
) -> None:
|
|
1317
|
+
"""Class initializer.
|
|
1318
|
+
|
|
1319
|
+
Args:
|
|
1320
|
+
url: The url to the Meilisearch API (ex: http://localhost:7700)
|
|
1321
|
+
api_key: The optional API key for Meilisearch. Defaults to None.
|
|
1322
|
+
timeout: The amount of time in seconds that the client will wait for a response before
|
|
1323
|
+
timing out. Defaults to None.
|
|
1324
|
+
verify: SSL certificates (a.k.a CA bundle) used to
|
|
1325
|
+
verify the identity of requested hosts. Either `True` (default CA bundle),
|
|
1326
|
+
a path to an SSL certificate file, or `False` (disable verification)
|
|
1327
|
+
custom_headers: Custom headers to add when sending data to Meilisearch. Defaults to
|
|
1328
|
+
None.
|
|
1329
|
+
json_handler: The module to use for json operations. The options are BuiltinHandler
|
|
1330
|
+
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
|
|
1331
|
+
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
|
|
1332
|
+
extra needs to be included. Default: BuiltinHandler.
|
|
1333
|
+
http2: If set to True, the client will use HTTP/2. Defaults to False.
|
|
1334
|
+
"""
|
|
1335
|
+
super().__init__(api_key, custom_headers, json_handler)
|
|
1336
|
+
|
|
1337
|
+
self.http_client = HttpxClient(
|
|
1338
|
+
base_url=url, timeout=timeout, headers=self._headers, verify=verify, http2=http2
|
|
1339
|
+
)
|
|
1340
|
+
|
|
1341
|
+
self._http_requests = HttpRequests(self.http_client, json_handler=self.json_handler)
|
|
1342
|
+
|
|
1343
|
+
def __enter__(self) -> Self:
|
|
1344
|
+
return self
|
|
1345
|
+
|
|
1346
|
+
def __exit__(
|
|
1347
|
+
self,
|
|
1348
|
+
et: type[BaseException] | None,
|
|
1349
|
+
ev: type[BaseException] | None,
|
|
1350
|
+
traceback: TracebackType | None,
|
|
1351
|
+
) -> None:
|
|
1352
|
+
self.close()
|
|
1353
|
+
|
|
1354
|
+
def close(self) -> None:
|
|
1355
|
+
"""Closes the client.
|
|
1356
|
+
|
|
1357
|
+
This only needs to be used if the client was not created with a context manager.
|
|
1358
|
+
"""
|
|
1359
|
+
self.http_client.close()
|
|
1360
|
+
|
|
1361
|
+
def add_or_update_networks(self, *, network: Network) -> Network:
|
|
1362
|
+
"""Set or update remote networks.
|
|
1363
|
+
|
|
1364
|
+
Args:
|
|
1365
|
+
network: Information to use for the networks.
|
|
1366
|
+
|
|
1367
|
+
Returns:
|
|
1368
|
+
An instance of Network containing the network information.
|
|
1369
|
+
|
|
1370
|
+
Raises:
|
|
1371
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1372
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1373
|
+
|
|
1374
|
+
Examples:
|
|
1375
|
+
>>> from meilisearch_python_sdk import Client
|
|
1376
|
+
>>> from meilisearch_python_sdk.models.client import Network, Remote
|
|
1377
|
+
>>>
|
|
1378
|
+
>>>
|
|
1379
|
+
>>> network = Network(
|
|
1380
|
+
>>> self_="remote_1",
|
|
1381
|
+
>>> remotes={
|
|
1382
|
+
>>> "remote_1": {"url": "http://localhost:7700", "searchApiKey": "xxxx"},
|
|
1383
|
+
>>> "remote_2": {"url": "http://localhost:7720", "searchApiKey": "xxxx"},
|
|
1384
|
+
>>> },
|
|
1385
|
+
>>> )
|
|
1386
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1387
|
+
>>> response = client.add_or_update_networks(network=network)
|
|
1388
|
+
"""
|
|
1389
|
+
response = self._http_requests.patch(
|
|
1390
|
+
"network", network.model_dump(by_alias=True, exclude_none=True)
|
|
1391
|
+
)
|
|
1392
|
+
|
|
1393
|
+
return Network(**response.json())
|
|
1394
|
+
|
|
1395
|
+
def get_networks(self) -> Network:
|
|
1396
|
+
"""Fetches the remote-networks
|
|
1397
|
+
|
|
1398
|
+
Returns:
|
|
1399
|
+
An instance of Network containing information about each remote.
|
|
1400
|
+
|
|
1401
|
+
Raises:
|
|
1402
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1403
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1404
|
+
|
|
1405
|
+
Examples:
|
|
1406
|
+
>>> from meilisearch_python_sdk import AsyncClient
|
|
1407
|
+
>>>
|
|
1408
|
+
>>>
|
|
1409
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1410
|
+
>>> response = client.get_networks()
|
|
1411
|
+
"""
|
|
1412
|
+
response = self._http_requests.get("network")
|
|
1413
|
+
|
|
1414
|
+
return Network(**response.json())
|
|
1415
|
+
|
|
1416
|
+
def get_webhooks(self) -> Webhooks:
|
|
1417
|
+
"""Get all webhooks.
|
|
1418
|
+
|
|
1419
|
+
Returns:
|
|
1420
|
+
An instance of Webhooks containing all configured webhooks.
|
|
1421
|
+
|
|
1422
|
+
Raises:
|
|
1423
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1424
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1425
|
+
|
|
1426
|
+
Examples:
|
|
1427
|
+
>>> from meilisearch_python_sdk import Client
|
|
1428
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1429
|
+
>>> webhooks = client.get_webhooks()
|
|
1430
|
+
"""
|
|
1431
|
+
response = self._http_requests.get("webhooks")
|
|
1432
|
+
|
|
1433
|
+
return Webhooks(**response.json())
|
|
1434
|
+
|
|
1435
|
+
def get_webhook(self, uuid: str) -> Webhook:
|
|
1436
|
+
"""Get a specific webhook by UUID.
|
|
1437
|
+
|
|
1438
|
+
Args:
|
|
1439
|
+
uuid: The webhook's unique identifier.
|
|
1440
|
+
|
|
1441
|
+
Returns:
|
|
1442
|
+
An instance of Webhook containing the webhook information.
|
|
1443
|
+
|
|
1444
|
+
Raises:
|
|
1445
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1446
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1447
|
+
|
|
1448
|
+
Examples:
|
|
1449
|
+
>>> from meilisearch_python_sdk import Client
|
|
1450
|
+
>>> with Client("http://localhost.com", "masterKey"):
|
|
1451
|
+
>>> webhook = client.get_webhook("abc-123")
|
|
1452
|
+
"""
|
|
1453
|
+
response = self._http_requests.get(f"webhooks/{uuid}")
|
|
1454
|
+
|
|
1455
|
+
return Webhook(**response.json())
|
|
1456
|
+
|
|
1457
|
+
def create_webhook(self, webhook: WebhookCreate) -> Webhook:
|
|
1458
|
+
"""Create a new webhook.
|
|
1459
|
+
|
|
1460
|
+
Args:
|
|
1461
|
+
webhook: The webhook configuration to create.
|
|
1462
|
+
|
|
1463
|
+
Returns:
|
|
1464
|
+
The created webhook.
|
|
1465
|
+
|
|
1466
|
+
Raises:
|
|
1467
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1468
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1469
|
+
|
|
1470
|
+
Examples:
|
|
1471
|
+
>>> from meilisearch_python_sdk import Client
|
|
1472
|
+
>>> from meilisearch_python_sdk.models.webhook import WebhookCreate
|
|
1473
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1474
|
+
>>> webhook_config = WebhookCreate(
|
|
1475
|
+
>>> url="https://example.com/webhook",
|
|
1476
|
+
>>> headers={"Authorization": "Bearer token"}
|
|
1477
|
+
>>> )
|
|
1478
|
+
>>> webhook = client.create_webhook(webhook_config)
|
|
1479
|
+
"""
|
|
1480
|
+
response = self._http_requests.post(
|
|
1481
|
+
"webhooks", webhook.model_dump(by_alias=True, exclude_none=True)
|
|
1482
|
+
)
|
|
1483
|
+
|
|
1484
|
+
return Webhook(**response.json())
|
|
1485
|
+
|
|
1486
|
+
def update_webhook(self, *, uuid: str, webhook: WebhookUpdate) -> Webhook:
|
|
1487
|
+
"""Update an existing webhook.
|
|
1488
|
+
|
|
1489
|
+
Args:
|
|
1490
|
+
uuid: The webhook's unique identifier.
|
|
1491
|
+
webhook: The webhook configuration updates.
|
|
1492
|
+
|
|
1493
|
+
Returns:
|
|
1494
|
+
The updated webhook.
|
|
1495
|
+
|
|
1496
|
+
Raises:
|
|
1497
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1498
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1499
|
+
|
|
1500
|
+
Examples:
|
|
1501
|
+
>>> from meilisearch_python_sdk import Client
|
|
1502
|
+
>>> from meilisearch_python_sdk.models.webhook import WebhookUpdate
|
|
1503
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1504
|
+
>>> webhook_update = WebhookUpdate(url="https://example.com/new-webhook")
|
|
1505
|
+
>>> webhook = client.update_webhook("abc-123", webhook_update)
|
|
1506
|
+
"""
|
|
1507
|
+
response = self._http_requests.patch(
|
|
1508
|
+
f"webhooks/{uuid}", webhook.model_dump(by_alias=True, exclude_none=True)
|
|
1509
|
+
)
|
|
1510
|
+
|
|
1511
|
+
return Webhook(**response.json())
|
|
1512
|
+
|
|
1513
|
+
def delete_webhook(self, uuid: str) -> int:
|
|
1514
|
+
"""Delete a webhook.
|
|
1515
|
+
|
|
1516
|
+
Args:
|
|
1517
|
+
uuid: The webhook's unique identifier.
|
|
1518
|
+
|
|
1519
|
+
Returns:
|
|
1520
|
+
The Response status code. 204 signifies a successful delete.
|
|
1521
|
+
|
|
1522
|
+
Raises:
|
|
1523
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1524
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1525
|
+
|
|
1526
|
+
Examples:
|
|
1527
|
+
>>> from meilisearch_python_sdk import Client
|
|
1528
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1529
|
+
>>> client.delete_webhook("abc-123")
|
|
1530
|
+
"""
|
|
1531
|
+
response = self._http_requests.delete(f"webhooks/{uuid}")
|
|
1532
|
+
return response.status_code
|
|
1533
|
+
|
|
1534
|
+
def create_dump(self) -> TaskInfo:
|
|
1535
|
+
"""Trigger the creation of a Meilisearch dump.
|
|
1536
|
+
|
|
1537
|
+
Returns:
|
|
1538
|
+
The details of the task.
|
|
1539
|
+
|
|
1540
|
+
Raises:
|
|
1541
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1542
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1543
|
+
|
|
1544
|
+
Examples
|
|
1545
|
+
>>> from meilisearch_python_sdk import Client
|
|
1546
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1547
|
+
>>> client.create_dump()
|
|
1548
|
+
"""
|
|
1549
|
+
response = self._http_requests.post("dumps")
|
|
1550
|
+
|
|
1551
|
+
return TaskInfo(**response.json())
|
|
1552
|
+
|
|
1553
|
+
def create_index(
|
|
1554
|
+
self,
|
|
1555
|
+
uid: str,
|
|
1556
|
+
primary_key: str | None = None,
|
|
1557
|
+
*,
|
|
1558
|
+
settings: MeilisearchSettings | None = None,
|
|
1559
|
+
wait: bool = True,
|
|
1560
|
+
timeout_in_ms: int | None = None,
|
|
1561
|
+
plugins: IndexPlugins | None = None,
|
|
1562
|
+
hits_type: Any = JsonDict,
|
|
1563
|
+
) -> Index:
|
|
1564
|
+
"""Creates a new index.
|
|
1565
|
+
|
|
1566
|
+
Args:
|
|
1567
|
+
uid: The index's unique identifier.
|
|
1568
|
+
primary_key: The primary key of the documents. Defaults to None.
|
|
1569
|
+
settings: Settings for the index. The settings can also be updated independently of
|
|
1570
|
+
creating the index. The advantage to updating them here is updating the settings after
|
|
1571
|
+
adding documents will cause the documents to be re-indexed. Because of this it will be
|
|
1572
|
+
faster to update them before adding documents. Defaults to None (i.e. default
|
|
1573
|
+
Meilisearch index settings).
|
|
1574
|
+
wait: If set to True and settings are being updated, the index will be returned after
|
|
1575
|
+
the settings update has completed. If False it will not wait for settings to complete.
|
|
1576
|
+
Default: True
|
|
1577
|
+
timeout_in_ms: Amount of time in milliseconds to wait before raising a
|
|
1578
|
+
MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
|
|
1579
|
+
if the `None` option is used the wait time could be very long. Defaults to None.
|
|
1580
|
+
plugins: Optional plugins can be provided to extend functionality.
|
|
1581
|
+
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
|
|
1582
|
+
JsonDict
|
|
1583
|
+
|
|
1584
|
+
Returns:
|
|
1585
|
+
An instance of Index containing the information of the newly created index.
|
|
1586
|
+
|
|
1587
|
+
Raises:
|
|
1588
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1589
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1590
|
+
|
|
1591
|
+
Examples
|
|
1592
|
+
>>> from meilisearch_python_sdk import Client
|
|
1593
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1594
|
+
>>> index = client.create_index("movies")
|
|
1595
|
+
"""
|
|
1596
|
+
return Index.create(
|
|
1597
|
+
self.http_client,
|
|
1598
|
+
uid,
|
|
1599
|
+
primary_key,
|
|
1600
|
+
settings=settings,
|
|
1601
|
+
wait=wait,
|
|
1602
|
+
timeout_in_ms=timeout_in_ms,
|
|
1603
|
+
plugins=plugins,
|
|
1604
|
+
json_handler=self.json_handler,
|
|
1605
|
+
hits_type=hits_type,
|
|
1606
|
+
)
|
|
1607
|
+
|
|
1608
|
+
def create_snapshot(self) -> TaskInfo:
|
|
1609
|
+
"""Trigger the creation of a Meilisearch snapshot.
|
|
1610
|
+
|
|
1611
|
+
Returns:
|
|
1612
|
+
The details of the task.
|
|
1613
|
+
|
|
1614
|
+
Raises:
|
|
1615
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1616
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1617
|
+
|
|
1618
|
+
Examples
|
|
1619
|
+
>>> from meilisearch_python_sdk import Client
|
|
1620
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1621
|
+
>>> client.create_snapshot()
|
|
1622
|
+
"""
|
|
1623
|
+
response = self._http_requests.post("snapshots")
|
|
1624
|
+
|
|
1625
|
+
return TaskInfo(**response.json())
|
|
1626
|
+
|
|
1627
|
+
def delete_index_if_exists(self, uid: str) -> bool:
|
|
1628
|
+
"""Deletes an index if it already exists.
|
|
1629
|
+
|
|
1630
|
+
Args:
|
|
1631
|
+
uid: The index's unique identifier.
|
|
1632
|
+
|
|
1633
|
+
Returns:
|
|
1634
|
+
True if an index was deleted for False if not.
|
|
1635
|
+
|
|
1636
|
+
Raises:
|
|
1637
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1638
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1639
|
+
|
|
1640
|
+
Examples
|
|
1641
|
+
>>> from meilisearch_python_sdk import Client
|
|
1642
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1643
|
+
>>> client.delete_index_if_exists()
|
|
1644
|
+
"""
|
|
1645
|
+
response = self._http_requests.delete(f"indexes/{uid}")
|
|
1646
|
+
status = self.wait_for_task(response.json()["taskUid"], timeout_in_ms=100000)
|
|
1647
|
+
if status.status == "succeeded":
|
|
1648
|
+
return True
|
|
1649
|
+
return False
|
|
1650
|
+
|
|
1651
|
+
def get_indexes(
|
|
1652
|
+
self, *, offset: int | None = None, limit: int | None = None
|
|
1653
|
+
) -> list[Index] | None:
|
|
1654
|
+
"""Get all indexes.
|
|
1655
|
+
Args:
|
|
1656
|
+
offset: Number of indexes to skip. The default of None will use the Meilisearch
|
|
1657
|
+
default.
|
|
1658
|
+
limit: Number of indexes to return. The default of None will use the Meilisearch
|
|
1659
|
+
default.
|
|
1660
|
+
|
|
1661
|
+
Returns:
|
|
1662
|
+
A list of all indexes.
|
|
1663
|
+
|
|
1664
|
+
Raises:
|
|
1665
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1666
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1667
|
+
|
|
1668
|
+
Examples
|
|
1669
|
+
>>> from meilisearch_python_sdk import Client
|
|
1670
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1671
|
+
>>> indexes = client.get_indexes()
|
|
1672
|
+
"""
|
|
1673
|
+
url = _build_offset_limit_url("indexes", offset, limit)
|
|
1674
|
+
response = self._http_requests.get(url)
|
|
1675
|
+
|
|
1676
|
+
if not response.json()["results"]:
|
|
1677
|
+
return None
|
|
1678
|
+
|
|
1679
|
+
return [
|
|
1680
|
+
Index(
|
|
1681
|
+
http_client=self.http_client,
|
|
1682
|
+
uid=x["uid"],
|
|
1683
|
+
primary_key=x["primaryKey"],
|
|
1684
|
+
created_at=x["createdAt"],
|
|
1685
|
+
updated_at=x["updatedAt"],
|
|
1686
|
+
json_handler=self.json_handler,
|
|
1687
|
+
)
|
|
1688
|
+
for x in response.json()["results"]
|
|
1689
|
+
]
|
|
1690
|
+
|
|
1691
|
+
def get_index(self, uid: str) -> Index:
|
|
1692
|
+
"""Gets a single index based on the uid of the index.
|
|
1693
|
+
|
|
1694
|
+
Args:
|
|
1695
|
+
uid: The index's unique identifier.
|
|
1696
|
+
|
|
1697
|
+
Returns:
|
|
1698
|
+
An Index instance containing the information of the fetched index.
|
|
1699
|
+
|
|
1700
|
+
Raises:
|
|
1701
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1702
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1703
|
+
|
|
1704
|
+
Examples
|
|
1705
|
+
>>> from meilisearch_python_sdk import Client
|
|
1706
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1707
|
+
>>> index = client.get_index()
|
|
1708
|
+
"""
|
|
1709
|
+
return Index(self.http_client, uid, json_handler=self.json_handler).fetch_info()
|
|
1710
|
+
|
|
1711
|
+
def index(self, uid: str, *, plugins: IndexPlugins | None = None) -> Index:
|
|
1712
|
+
"""Create a local reference to an index identified by UID, without making an HTTP call.
|
|
1713
|
+
|
|
1714
|
+
Args:
|
|
1715
|
+
uid: The index's unique identifier.
|
|
1716
|
+
plugins: Optional plugins can be provided to extend functionality.
|
|
1717
|
+
|
|
1718
|
+
Returns:
|
|
1719
|
+
An Index instance.
|
|
1720
|
+
|
|
1721
|
+
Raises:
|
|
1722
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1723
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1724
|
+
|
|
1725
|
+
Examples
|
|
1726
|
+
>>> from meilisearch_python_sdk import Client
|
|
1727
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1728
|
+
>>> index = client.index("movies")
|
|
1729
|
+
"""
|
|
1730
|
+
return Index(self.http_client, uid=uid, plugins=plugins, json_handler=self.json_handler)
|
|
1731
|
+
|
|
1732
|
+
def get_all_stats(self) -> ClientStats:
|
|
1733
|
+
"""Get stats for all indexes.
|
|
1734
|
+
|
|
1735
|
+
Returns:
|
|
1736
|
+
Information about database size and all indexes.
|
|
1737
|
+
https://docs.meilisearch.com/reference/api/stats.html
|
|
1738
|
+
|
|
1739
|
+
Raises:
|
|
1740
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1741
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1742
|
+
|
|
1743
|
+
Examples
|
|
1744
|
+
>>> from meilisearch_python_sdk import Client
|
|
1745
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1746
|
+
>>> stats = client.get_all_stats()
|
|
1747
|
+
"""
|
|
1748
|
+
response = self._http_requests.get("stats")
|
|
1749
|
+
|
|
1750
|
+
return ClientStats(**response.json())
|
|
1751
|
+
|
|
1752
|
+
def get_or_create_index(
|
|
1753
|
+
self,
|
|
1754
|
+
uid: str,
|
|
1755
|
+
primary_key: str | None = None,
|
|
1756
|
+
*,
|
|
1757
|
+
plugins: IndexPlugins | None = None,
|
|
1758
|
+
hits_type: Any = JsonDict,
|
|
1759
|
+
) -> Index:
|
|
1760
|
+
"""Get an index, or create it if it doesn't exist.
|
|
1761
|
+
|
|
1762
|
+
Args:
|
|
1763
|
+
uid: The index's unique identifier.
|
|
1764
|
+
primary_key: The primary key of the documents. Defaults to None.
|
|
1765
|
+
plugins: Optional plugins can be provided to extend functionality.
|
|
1766
|
+
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
|
|
1767
|
+
JsonDict
|
|
1768
|
+
|
|
1769
|
+
Returns:
|
|
1770
|
+
An instance of Index containing the information of the retrieved or newly created index.
|
|
1771
|
+
|
|
1772
|
+
Raises:
|
|
1773
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1774
|
+
MeilisearchApiError: If the Meilisearch API returned an error.MeilisearchTimeoutError: If the connection times out.
|
|
1775
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
1776
|
+
|
|
1777
|
+
Examples
|
|
1778
|
+
>>> from meilisearch_python_sdk import Client
|
|
1779
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1780
|
+
>>> index = client.get_or_create_index("movies")
|
|
1781
|
+
"""
|
|
1782
|
+
try:
|
|
1783
|
+
index_instance = self.get_index(uid)
|
|
1784
|
+
except MeilisearchApiError as err:
|
|
1785
|
+
if "index_not_found" not in err.code:
|
|
1786
|
+
raise
|
|
1787
|
+
index_instance = self.create_index(
|
|
1788
|
+
uid, primary_key, plugins=plugins, hits_type=hits_type
|
|
1789
|
+
)
|
|
1790
|
+
return index_instance
|
|
1791
|
+
|
|
1792
|
+
def create_key(self, key: KeyCreate) -> Key:
|
|
1793
|
+
"""Creates a new API key.
|
|
1794
|
+
|
|
1795
|
+
Args:
|
|
1796
|
+
key: The information to use in creating the key. Note that if an expires_at value
|
|
1797
|
+
is included it should be in UTC time.
|
|
1798
|
+
|
|
1799
|
+
Returns:
|
|
1800
|
+
The new API key.
|
|
1801
|
+
|
|
1802
|
+
Raises:
|
|
1803
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1804
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1805
|
+
|
|
1806
|
+
Examples
|
|
1807
|
+
>>> from meilisearch_python_sdk import Client
|
|
1808
|
+
>>> from meilissearch_async_client.models.client import KeyCreate
|
|
1809
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1810
|
+
>>> key_info = KeyCreate(
|
|
1811
|
+
>>> description="My new key",
|
|
1812
|
+
>>> actions=["search"],
|
|
1813
|
+
>>> indexes=["movies"],
|
|
1814
|
+
>>> )
|
|
1815
|
+
>>> keys = client.create_key(key_info)
|
|
1816
|
+
"""
|
|
1817
|
+
response = self._http_requests.post(
|
|
1818
|
+
"keys", self.json_handler.loads(key.model_dump_json(by_alias=True))
|
|
1819
|
+
) # type: ignore[attr-defined]
|
|
1820
|
+
|
|
1821
|
+
return Key(**response.json())
|
|
1822
|
+
|
|
1823
|
+
def delete_key(self, key: str) -> int:
|
|
1824
|
+
"""Deletes an API key.
|
|
1825
|
+
|
|
1826
|
+
Args:
|
|
1827
|
+
key: The key or uid to delete.
|
|
1828
|
+
|
|
1829
|
+
Returns:
|
|
1830
|
+
The Response status code. 204 signifies a successful delete.
|
|
1831
|
+
|
|
1832
|
+
Raises:
|
|
1833
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1834
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1835
|
+
|
|
1836
|
+
Examples
|
|
1837
|
+
>>> from meilisearch_python_sdk import Client
|
|
1838
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1839
|
+
>>> client.delete_key("abc123")
|
|
1840
|
+
"""
|
|
1841
|
+
response = self._http_requests.delete(f"keys/{key}")
|
|
1842
|
+
return response.status_code
|
|
1843
|
+
|
|
1844
|
+
def get_keys(self, *, offset: int | None = None, limit: int | None = None) -> KeySearch:
|
|
1845
|
+
"""Gets the Meilisearch API keys.
|
|
1846
|
+
Args:
|
|
1847
|
+
offset: Number of indexes to skip. The default of None will use the Meilisearch
|
|
1848
|
+
default.
|
|
1849
|
+
limit: Number of indexes to return. The default of None will use the Meilisearch
|
|
1850
|
+
default.
|
|
1851
|
+
|
|
1852
|
+
Returns:
|
|
1853
|
+
API keys.
|
|
1854
|
+
|
|
1855
|
+
Raises:
|
|
1856
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1857
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1858
|
+
|
|
1859
|
+
Examples
|
|
1860
|
+
>>> from meilisearch_python_sdk import Client
|
|
1861
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1862
|
+
>>> keys = client.get_keys()
|
|
1863
|
+
"""
|
|
1864
|
+
url = _build_offset_limit_url("keys", offset, limit)
|
|
1865
|
+
response = self._http_requests.get(url)
|
|
1866
|
+
|
|
1867
|
+
return KeySearch(**response.json())
|
|
1868
|
+
|
|
1869
|
+
def get_key(self, key: str) -> Key:
|
|
1870
|
+
"""Gets information about a specific API key.
|
|
1871
|
+
|
|
1872
|
+
Args:
|
|
1873
|
+
key: The key for which to retrieve the information.
|
|
1874
|
+
|
|
1875
|
+
Returns:
|
|
1876
|
+
The API key, or `None` if the key is not found.
|
|
1877
|
+
|
|
1878
|
+
Raises:
|
|
1879
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1880
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1881
|
+
|
|
1882
|
+
Examples
|
|
1883
|
+
>>> from meilisearch_python_sdk import Client
|
|
1884
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1885
|
+
>>> keys = client.get_key("abc123")
|
|
1886
|
+
"""
|
|
1887
|
+
response = self._http_requests.get(f"keys/{key}")
|
|
1888
|
+
|
|
1889
|
+
return Key(**response.json())
|
|
1890
|
+
|
|
1891
|
+
def update_key(self, key: KeyUpdate) -> Key:
|
|
1892
|
+
"""Update an API key.
|
|
1893
|
+
|
|
1894
|
+
Args:
|
|
1895
|
+
key: The information to use in updating the key. Note that if an expires_at value
|
|
1896
|
+
is included it should be in UTC time.
|
|
1897
|
+
|
|
1898
|
+
Returns:
|
|
1899
|
+
The updated API key.
|
|
1900
|
+
|
|
1901
|
+
Raises:
|
|
1902
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1903
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1904
|
+
|
|
1905
|
+
Examples
|
|
1906
|
+
>>> from meilisearch_python_sdk import Client
|
|
1907
|
+
>>> from meilissearch_async_client.models.client import KeyUpdate
|
|
1908
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1909
|
+
>>> key_info = KeyUpdate(
|
|
1910
|
+
key="abc123",
|
|
1911
|
+
>>> indexes=["*"],
|
|
1912
|
+
>>> )
|
|
1913
|
+
>>> keys = client.update_key(key_info)
|
|
1914
|
+
"""
|
|
1915
|
+
payload = _build_update_key_payload(key, self.json_handler)
|
|
1916
|
+
response = self._http_requests.patch(f"keys/{key.key}", payload)
|
|
1917
|
+
|
|
1918
|
+
return Key(**response.json())
|
|
1919
|
+
|
|
1920
|
+
def multi_search(
|
|
1921
|
+
self,
|
|
1922
|
+
queries: list[SearchParams],
|
|
1923
|
+
*,
|
|
1924
|
+
federation: Federation | FederationMerged | None = None,
|
|
1925
|
+
hits_type: Any = JsonDict,
|
|
1926
|
+
) -> list[SearchResultsWithUID] | SearchResultsFederated:
|
|
1927
|
+
"""Multi-index search.
|
|
1928
|
+
|
|
1929
|
+
Args:
|
|
1930
|
+
queries: List of SearchParameters
|
|
1931
|
+
federation: If included a single search result with hits built from all queries will
|
|
1932
|
+
be returned. This parameter can only be used with Meilisearch >= v1.10.0. Defaults
|
|
1933
|
+
to None.
|
|
1934
|
+
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
|
|
1935
|
+
JsonDict
|
|
1936
|
+
|
|
1937
|
+
Returns:
|
|
1938
|
+
Results of the search
|
|
1939
|
+
|
|
1940
|
+
Raises:
|
|
1941
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
1942
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
1943
|
+
|
|
1944
|
+
Examples
|
|
1945
|
+
>>> from meilisearch_python_sdk import Client
|
|
1946
|
+
>>> from meilisearch_python_sdk.models.search import SearchParams
|
|
1947
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
1948
|
+
>>> queries = [
|
|
1949
|
+
>>> SearchParams(index_uid="my_first_index", query"Some search"),
|
|
1950
|
+
>>> SearchParams(index_uid="my_second_index", query="Another search")
|
|
1951
|
+
>>> ]
|
|
1952
|
+
>>> search_results = client.search(queries)
|
|
1953
|
+
"""
|
|
1954
|
+
url = "multi-search"
|
|
1955
|
+
processed_queries = []
|
|
1956
|
+
for query in queries:
|
|
1957
|
+
q = query.model_dump(by_alias=True)
|
|
1958
|
+
|
|
1959
|
+
if query.retrieve_vectors is None:
|
|
1960
|
+
del q["retrieveVectors"]
|
|
1961
|
+
|
|
1962
|
+
if federation:
|
|
1963
|
+
del q["limit"]
|
|
1964
|
+
del q["offset"]
|
|
1965
|
+
|
|
1966
|
+
processed_queries.append(q)
|
|
1967
|
+
|
|
1968
|
+
if federation:
|
|
1969
|
+
federation_payload = federation.model_dump(by_alias=True)
|
|
1970
|
+
if federation.facets_by_index is None:
|
|
1971
|
+
del federation_payload["facetsByIndex"]
|
|
1972
|
+
|
|
1973
|
+
else:
|
|
1974
|
+
federation_payload = None
|
|
1975
|
+
|
|
1976
|
+
response = self._http_requests.post(
|
|
1977
|
+
url,
|
|
1978
|
+
body={
|
|
1979
|
+
"federation": federation_payload,
|
|
1980
|
+
"queries": processed_queries,
|
|
1981
|
+
},
|
|
1982
|
+
)
|
|
1983
|
+
|
|
1984
|
+
if federation:
|
|
1985
|
+
results = response.json()
|
|
1986
|
+
return SearchResultsFederated[hits_type](**results)
|
|
1987
|
+
|
|
1988
|
+
return [SearchResultsWithUID[hits_type](**x) for x in response.json()["results"]]
|
|
1989
|
+
|
|
1990
|
+
def get_raw_index(self, uid: str) -> IndexInfo | None:
|
|
1991
|
+
"""Gets the index and returns all the index information rather than an Index instance.
|
|
1992
|
+
|
|
1993
|
+
Args:
|
|
1994
|
+
uid: The index's unique identifier.
|
|
1995
|
+
|
|
1996
|
+
Returns:
|
|
1997
|
+
Index information rather than an Index instance.
|
|
1998
|
+
|
|
1999
|
+
Raises:
|
|
2000
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2001
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2002
|
+
|
|
2003
|
+
Examples
|
|
2004
|
+
>>> from meilisearch_python_sdk import Client
|
|
2005
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2006
|
+
>>> index = client.get_raw_index("movies")
|
|
2007
|
+
"""
|
|
2008
|
+
response = self.http_client.get(f"indexes/{uid}")
|
|
2009
|
+
|
|
2010
|
+
if response.status_code == 404:
|
|
2011
|
+
return None
|
|
2012
|
+
|
|
2013
|
+
return IndexInfo(**response.json())
|
|
2014
|
+
|
|
2015
|
+
def get_raw_indexes(
|
|
2016
|
+
self, *, offset: int | None = None, limit: int | None = None
|
|
2017
|
+
) -> list[IndexInfo] | None:
|
|
2018
|
+
"""Gets all the indexes.
|
|
2019
|
+
Args:
|
|
2020
|
+
offset: Number of indexes to skip. The default of None will use the Meilisearch
|
|
2021
|
+
default.
|
|
2022
|
+
limit: Number of indexes to return. The default of None will use the Meilisearch
|
|
2023
|
+
default.
|
|
2024
|
+
|
|
2025
|
+
Returns all the index information rather than an AsyncIndex instance.
|
|
2026
|
+
|
|
2027
|
+
Returns:
|
|
2028
|
+
A list of the Index information rather than an AsyncIndex instances.
|
|
2029
|
+
|
|
2030
|
+
Raises:
|
|
2031
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2032
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2033
|
+
|
|
2034
|
+
Examples
|
|
2035
|
+
>>> from meilisearch_python_sdk import Client
|
|
2036
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2037
|
+
>>> index = client.get_raw_indexes()
|
|
2038
|
+
"""
|
|
2039
|
+
url = _build_offset_limit_url("indexes", offset, limit)
|
|
2040
|
+
response = self._http_requests.get(url)
|
|
2041
|
+
|
|
2042
|
+
if not response.json()["results"]:
|
|
2043
|
+
return None
|
|
2044
|
+
|
|
2045
|
+
return [IndexInfo(**x) for x in response.json()["results"]]
|
|
2046
|
+
|
|
2047
|
+
def get_version(self) -> Version:
|
|
2048
|
+
"""Get the Meilisearch version.
|
|
2049
|
+
|
|
2050
|
+
Returns:
|
|
2051
|
+
Information about the version of Meilisearch.
|
|
2052
|
+
|
|
2053
|
+
Raises:
|
|
2054
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2055
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2056
|
+
|
|
2057
|
+
Examples
|
|
2058
|
+
>>> from meilisearch_python_sdk import Client
|
|
2059
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2060
|
+
>>> version = client.get_version()
|
|
2061
|
+
"""
|
|
2062
|
+
response = self._http_requests.get("version")
|
|
2063
|
+
|
|
2064
|
+
return Version(**response.json())
|
|
2065
|
+
|
|
2066
|
+
def health(self) -> Health:
|
|
2067
|
+
"""Get health of the Meilisearch server.
|
|
2068
|
+
|
|
2069
|
+
Returns:
|
|
2070
|
+
The status of the Meilisearch server.
|
|
2071
|
+
|
|
2072
|
+
Raises:
|
|
2073
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2074
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2075
|
+
|
|
2076
|
+
Examples
|
|
2077
|
+
>>> from meilisearch_python_sdk import Client
|
|
2078
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2079
|
+
>>> health = client.get_health()
|
|
2080
|
+
"""
|
|
2081
|
+
response = self._http_requests.get("health")
|
|
2082
|
+
|
|
2083
|
+
return Health(**response.json())
|
|
2084
|
+
|
|
2085
|
+
def swap_indexes(self, indexes: list[tuple[str, str]], rename: bool = False) -> TaskInfo:
|
|
2086
|
+
"""Swap two indexes.
|
|
2087
|
+
|
|
2088
|
+
Args:
|
|
2089
|
+
indexes: A list of tuples, each tuple should contain the indexes to swap.
|
|
2090
|
+
rename: Use rename false if you are swapping two existing indexes. Use rename true if
|
|
2091
|
+
the second index in your array does not exist. Default = False
|
|
2092
|
+
|
|
2093
|
+
Returns:
|
|
2094
|
+
The details of the task.
|
|
2095
|
+
|
|
2096
|
+
Raises:
|
|
2097
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2098
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2099
|
+
|
|
2100
|
+
Examples
|
|
2101
|
+
>>> from meilisearch_python_sdk import Client
|
|
2102
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2103
|
+
>>> index = client.swap_indexes([("index_a", "index_b")])
|
|
2104
|
+
"""
|
|
2105
|
+
if rename:
|
|
2106
|
+
processed_indexes = [{"indexes": x, "rename": True} for x in indexes]
|
|
2107
|
+
else:
|
|
2108
|
+
processed_indexes = [{"indexes": x} for x in indexes]
|
|
2109
|
+
response = self._http_requests.post("swap-indexes", processed_indexes)
|
|
2110
|
+
|
|
2111
|
+
return TaskInfo(**response.json())
|
|
2112
|
+
|
|
2113
|
+
def get_batch(self, batch_uid: int) -> BatchResult | None:
|
|
2114
|
+
return _get_batch(self, batch_uid)
|
|
2115
|
+
|
|
2116
|
+
def get_batches(
|
|
2117
|
+
self,
|
|
2118
|
+
*,
|
|
2119
|
+
uids: list[int] | None = None,
|
|
2120
|
+
batch_uids: list[int] | None = None,
|
|
2121
|
+
index_uids: list[int] | None = None,
|
|
2122
|
+
statuses: list[str] | None = None,
|
|
2123
|
+
types: list[str] | None = None,
|
|
2124
|
+
limit: int = 20,
|
|
2125
|
+
from_: str | None = None,
|
|
2126
|
+
reverse: bool = False,
|
|
2127
|
+
before_enqueued_at: datetime | None = None,
|
|
2128
|
+
after_enqueued_at: datetime | None = None,
|
|
2129
|
+
before_started_at: datetime | None = None,
|
|
2130
|
+
after_finished_at: datetime | None = None,
|
|
2131
|
+
) -> BatchStatus:
|
|
2132
|
+
return _get_batches(
|
|
2133
|
+
self,
|
|
2134
|
+
uids=uids,
|
|
2135
|
+
batch_uids=batch_uids,
|
|
2136
|
+
index_uids=index_uids,
|
|
2137
|
+
statuses=statuses,
|
|
2138
|
+
types=types,
|
|
2139
|
+
limit=limit,
|
|
2140
|
+
from_=from_,
|
|
2141
|
+
reverse=reverse,
|
|
2142
|
+
before_enqueued_at=before_enqueued_at,
|
|
2143
|
+
after_enqueued_at=after_enqueued_at,
|
|
2144
|
+
before_started_at=before_started_at,
|
|
2145
|
+
after_finished_at=after_finished_at,
|
|
2146
|
+
)
|
|
2147
|
+
|
|
2148
|
+
def cancel_tasks(
|
|
2149
|
+
self,
|
|
2150
|
+
*,
|
|
2151
|
+
uids: list[int] | None = None,
|
|
2152
|
+
index_uids: list[int] | None = None,
|
|
2153
|
+
statuses: list[str] | None = None,
|
|
2154
|
+
types: list[str] | None = None,
|
|
2155
|
+
before_enqueued_at: datetime | None = None,
|
|
2156
|
+
after_enqueued_at: datetime | None = None,
|
|
2157
|
+
before_started_at: datetime | None = None,
|
|
2158
|
+
after_finished_at: datetime | None = None,
|
|
2159
|
+
) -> TaskInfo:
|
|
2160
|
+
"""Cancel a list of enqueued or processing tasks.
|
|
2161
|
+
|
|
2162
|
+
Defaults to cancelling all tasks.
|
|
2163
|
+
|
|
2164
|
+
Args:
|
|
2165
|
+
uids: A list of task UIDs to cancel.
|
|
2166
|
+
index_uids: A list of index UIDs for which to cancel tasks.
|
|
2167
|
+
statuses: A list of statuses to cancel.
|
|
2168
|
+
types: A list of types to cancel.
|
|
2169
|
+
before_enqueued_at: Cancel tasks that were enqueued before the specified date time.
|
|
2170
|
+
after_enqueued_at: Cancel tasks that were enqueued after the specified date time.
|
|
2171
|
+
before_started_at: Cancel tasks that were started before the specified date time.
|
|
2172
|
+
after_finished_at: Cancel tasks that were finished after the specified date time.
|
|
2173
|
+
|
|
2174
|
+
Returns:
|
|
2175
|
+
The details of the task
|
|
2176
|
+
|
|
2177
|
+
Raises:
|
|
2178
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2179
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2180
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2181
|
+
|
|
2182
|
+
Examples
|
|
2183
|
+
>>> from meilisearch_python_sdk import Client
|
|
2184
|
+
>>> from meilisearch_python_sdk.task import cancel_tasks
|
|
2185
|
+
>>>
|
|
2186
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2187
|
+
>>> client.cancel_tasks(uids=[1, 2])
|
|
2188
|
+
"""
|
|
2189
|
+
return _task.cancel_tasks(
|
|
2190
|
+
self.http_client,
|
|
2191
|
+
uids=uids,
|
|
2192
|
+
index_uids=index_uids,
|
|
2193
|
+
statuses=statuses,
|
|
2194
|
+
types=types,
|
|
2195
|
+
before_enqueued_at=before_enqueued_at,
|
|
2196
|
+
after_enqueued_at=after_enqueued_at,
|
|
2197
|
+
before_started_at=before_started_at,
|
|
2198
|
+
after_finished_at=after_finished_at,
|
|
2199
|
+
)
|
|
2200
|
+
|
|
2201
|
+
def delete_tasks(
|
|
2202
|
+
self,
|
|
2203
|
+
*,
|
|
2204
|
+
uids: list[int] | None = None,
|
|
2205
|
+
index_uids: list[int] | None = None,
|
|
2206
|
+
statuses: list[str] | None = None,
|
|
2207
|
+
types: list[str] | None = None,
|
|
2208
|
+
before_enqueued_at: datetime | None = None,
|
|
2209
|
+
after_enqueued_at: datetime | None = None,
|
|
2210
|
+
before_started_at: datetime | None = None,
|
|
2211
|
+
after_finished_at: datetime | None = None,
|
|
2212
|
+
) -> TaskInfo:
|
|
2213
|
+
"""Delete a list of tasks.
|
|
2214
|
+
|
|
2215
|
+
Defaults to deleting all tasks.
|
|
2216
|
+
|
|
2217
|
+
Args:
|
|
2218
|
+
uids: A list of task UIDs to delete.
|
|
2219
|
+
index_uids: A list of index UIDs for which to delete tasks.
|
|
2220
|
+
statuses: A list of statuses to delete.
|
|
2221
|
+
types: A list of types to delete.
|
|
2222
|
+
before_enqueued_at: Delete tasks that were enqueued before the specified date time.
|
|
2223
|
+
after_enqueued_at: Delete tasks that were enqueued after the specified date time.
|
|
2224
|
+
before_started_at: Delete tasks that were started before the specified date time.
|
|
2225
|
+
after_finished_at: Delete tasks that were finished after the specified date time.
|
|
2226
|
+
|
|
2227
|
+
Returns:
|
|
2228
|
+
The details of the task
|
|
2229
|
+
|
|
2230
|
+
Raises:
|
|
2231
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2232
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2233
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2234
|
+
|
|
2235
|
+
Examples
|
|
2236
|
+
>>> from meilisearch_python_sdk import Client
|
|
2237
|
+
>>>
|
|
2238
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2239
|
+
>>> client.delete_tasks(client, uids=[1, 2])
|
|
2240
|
+
"""
|
|
2241
|
+
return _task.delete_tasks(
|
|
2242
|
+
self.http_client,
|
|
2243
|
+
uids=uids,
|
|
2244
|
+
index_uids=index_uids,
|
|
2245
|
+
statuses=statuses,
|
|
2246
|
+
types=types,
|
|
2247
|
+
before_enqueued_at=before_enqueued_at,
|
|
2248
|
+
after_enqueued_at=after_enqueued_at,
|
|
2249
|
+
before_started_at=before_started_at,
|
|
2250
|
+
after_finished_at=after_finished_at,
|
|
2251
|
+
)
|
|
2252
|
+
|
|
2253
|
+
def get_task(self, task_id: int) -> TaskResult:
|
|
2254
|
+
"""Get a single task from it's task id.
|
|
2255
|
+
|
|
2256
|
+
Args:
|
|
2257
|
+
task_id: Identifier of the task to retrieve.
|
|
2258
|
+
|
|
2259
|
+
Returns:
|
|
2260
|
+
Results of a task.
|
|
2261
|
+
|
|
2262
|
+
Raises:
|
|
2263
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2264
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2265
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2266
|
+
|
|
2267
|
+
Examples
|
|
2268
|
+
>>> from meilisearch_python_sdk import Client
|
|
2269
|
+
>>>
|
|
2270
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2271
|
+
>>> client.get_task(client, 1244)
|
|
2272
|
+
"""
|
|
2273
|
+
return _task.get_task(self.http_client, task_id=task_id)
|
|
2274
|
+
|
|
2275
|
+
def get_tasks(
|
|
2276
|
+
self,
|
|
2277
|
+
*,
|
|
2278
|
+
index_ids: list[str] | None = None,
|
|
2279
|
+
types: str | list[str] | None = None,
|
|
2280
|
+
reverse: bool | None = None,
|
|
2281
|
+
) -> TaskStatus:
|
|
2282
|
+
"""Get multiple tasks.
|
|
2283
|
+
|
|
2284
|
+
Args:
|
|
2285
|
+
index_ids: A list of index UIDs for which to get the tasks. If provided this will get the
|
|
2286
|
+
tasks only for the specified indexes, if not all tasks will be returned. Default = None
|
|
2287
|
+
types: Specify specific task types to retrieve. Default = None
|
|
2288
|
+
reverse: If True the tasks will be returned in reverse order. Default = None
|
|
2289
|
+
|
|
2290
|
+
Returns:
|
|
2291
|
+
Task statuses.
|
|
2292
|
+
|
|
2293
|
+
Raises:
|
|
2294
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2295
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2296
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2297
|
+
|
|
2298
|
+
Examples
|
|
2299
|
+
>>> from meilisearch_python_sdk import Client
|
|
2300
|
+
>>>
|
|
2301
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2302
|
+
>>> client.get_tasks(client)
|
|
2303
|
+
"""
|
|
2304
|
+
return _task.get_tasks(self.http_client, index_ids=index_ids, types=types, reverse=reverse)
|
|
2305
|
+
|
|
2306
|
+
def wait_for_task(
|
|
2307
|
+
self,
|
|
2308
|
+
task_id: int,
|
|
2309
|
+
*,
|
|
2310
|
+
timeout_in_ms: int | None = 5000,
|
|
2311
|
+
interval_in_ms: int = 50,
|
|
2312
|
+
raise_for_status: bool = False,
|
|
2313
|
+
) -> TaskResult:
|
|
2314
|
+
"""Wait until Meilisearch processes a task, and get its status.
|
|
2315
|
+
|
|
2316
|
+
Args:
|
|
2317
|
+
task_id: Identifier of the task to retrieve.
|
|
2318
|
+
timeout_in_ms: Amount of time in milliseconds to wait before raising a
|
|
2319
|
+
MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
|
|
2320
|
+
if the `None` option is used the wait time could be very long. Defaults to 5000.
|
|
2321
|
+
interval_in_ms: Time interval in milliseconds to sleep between requests. Defaults to 50.
|
|
2322
|
+
raise_for_status: When set to `True` a MeilisearchTaskFailedError will be raised if a task
|
|
2323
|
+
has a failed status. Defaults to False.
|
|
2324
|
+
|
|
2325
|
+
Returns:
|
|
2326
|
+
Details of the processed update status.
|
|
2327
|
+
|
|
2328
|
+
Raises:
|
|
2329
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2330
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2331
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2332
|
+
MeilisearchTaskFailedError: If `raise_for_status` is `True` and a task has a failed status.
|
|
2333
|
+
|
|
2334
|
+
Examples
|
|
2335
|
+
>>> from meilisearch_python_sdk import Client
|
|
2336
|
+
>>> documents = [
|
|
2337
|
+
>>> {"id": 1, "title": "Movie 1", "genre": "comedy"},
|
|
2338
|
+
>>> {"id": 2, "title": "Movie 2", "genre": "drama"},
|
|
2339
|
+
>>> ]
|
|
2340
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2341
|
+
>>> index = client.index("movies")
|
|
2342
|
+
>>> response = await index.add_documents(documents)
|
|
2343
|
+
>>> client.wait_for_task(response.update_id)
|
|
2344
|
+
"""
|
|
2345
|
+
return _task.wait_for_task(
|
|
2346
|
+
self.http_client,
|
|
2347
|
+
task_id=task_id,
|
|
2348
|
+
timeout_in_ms=timeout_in_ms,
|
|
2349
|
+
interval_in_ms=interval_in_ms,
|
|
2350
|
+
raise_for_status=raise_for_status,
|
|
2351
|
+
)
|
|
2352
|
+
|
|
2353
|
+
# No cover because it requires multiple instances of Meilisearch
|
|
2354
|
+
def transfer_documents( # pragma: no cover
|
|
2355
|
+
self,
|
|
2356
|
+
url: str,
|
|
2357
|
+
*,
|
|
2358
|
+
api_key: str | None = None,
|
|
2359
|
+
payload_size: str | None = None,
|
|
2360
|
+
indexes: JsonMapping | None = None,
|
|
2361
|
+
) -> TaskInfo:
|
|
2362
|
+
"""Transfer settings and documents from one Meilisearch instance to another.
|
|
2363
|
+
|
|
2364
|
+
Args:
|
|
2365
|
+
url: Where to send our settings and documents.
|
|
2366
|
+
api_key: The API key with the rights to send the requests. Usually the master key of
|
|
2367
|
+
the remote machine. Defaults to None.
|
|
2368
|
+
payload_size: Human readable size defining the size of the payloads to send. Defaults
|
|
2369
|
+
to 50 MiB.
|
|
2370
|
+
indexes: A set of patterns of matching the indexes you want to export. Defaults to all
|
|
2371
|
+
indexes without filter.
|
|
2372
|
+
|
|
2373
|
+
Returns:
|
|
2374
|
+
The details of the task.
|
|
2375
|
+
|
|
2376
|
+
Raises:
|
|
2377
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2378
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2379
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2380
|
+
|
|
2381
|
+
Examples
|
|
2382
|
+
>>> from meilisearch_python_sdk import Client
|
|
2383
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2384
|
+
>>> index.transfer_documents("https://another-instance.com", api_key="otherMasterKey")
|
|
2385
|
+
"""
|
|
2386
|
+
payload: JsonDict = {"url": url}
|
|
2387
|
+
|
|
2388
|
+
if api_key:
|
|
2389
|
+
payload["apiKey"] = api_key
|
|
2390
|
+
|
|
2391
|
+
if payload:
|
|
2392
|
+
payload["payloadSize"] = payload_size
|
|
2393
|
+
|
|
2394
|
+
if indexes:
|
|
2395
|
+
payload["indexes"] = indexes
|
|
2396
|
+
|
|
2397
|
+
response = self._http_requests.post(url, body=payload)
|
|
2398
|
+
|
|
2399
|
+
return TaskInfo(**response.json())
|
|
2400
|
+
|
|
2401
|
+
def get_experimental_features(self) -> dict[str, bool]:
|
|
2402
|
+
"""Gets all experimental features and if they are enabled or not.
|
|
2403
|
+
|
|
2404
|
+
Returns:
|
|
2405
|
+
The status of the experimental features.
|
|
2406
|
+
|
|
2407
|
+
Raises:
|
|
2408
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2409
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2410
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2411
|
+
|
|
2412
|
+
Examples
|
|
2413
|
+
>>> from meilisearch_python_sdk import Client
|
|
2414
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2415
|
+
>>> index.get_experimental_feature()
|
|
2416
|
+
"""
|
|
2417
|
+
|
|
2418
|
+
response = self._http_requests.get("/experimental-features")
|
|
2419
|
+
return response.json()
|
|
2420
|
+
|
|
2421
|
+
def update_experimental_features(self, features: dict[str, bool]) -> dict[str, bool]:
|
|
2422
|
+
"""Update the status of an experimental feature.
|
|
2423
|
+
|
|
2424
|
+
Args:
|
|
2425
|
+
features: Dictionary of features to enable/disable. The dictionary keys can be in either
|
|
2426
|
+
camel case or snake case, the conversion to the correct type will be handed for you by
|
|
2427
|
+
the program. For example {"logsRoute": True} and {"logs_route": True} will both work.
|
|
2428
|
+
|
|
2429
|
+
Returns:
|
|
2430
|
+
The status of the experimental features.
|
|
2431
|
+
|
|
2432
|
+
Raises:
|
|
2433
|
+
MeilisearchCommunicationError: If there was an error communicating with the server.
|
|
2434
|
+
MeilisearchApiError: If the Meilisearch API returned an error.
|
|
2435
|
+
MeilisearchTimeoutError: If the connection times out.
|
|
2436
|
+
|
|
2437
|
+
Examples
|
|
2438
|
+
>>> from meilisearch_python_sdk import Client
|
|
2439
|
+
>>> with Client("http://localhost.com", "masterKey") as client:
|
|
2440
|
+
>>> index.update_experimental_features({"logsRoute": True})
|
|
2441
|
+
"""
|
|
2442
|
+
payload = dict_to_camel(features)
|
|
2443
|
+
response = self._http_requests.patch("/experimental-features", body=payload)
|
|
2444
|
+
|
|
2445
|
+
return response.json()
|
|
2446
|
+
|
|
2447
|
+
|
|
2448
|
+
def _build_offset_limit_url(base: str, offset: int | None, limit: int | None) -> str:
|
|
2449
|
+
if offset is not None and limit is not None:
|
|
2450
|
+
return f"{base}?offset={offset}&limit={limit}"
|
|
2451
|
+
elif offset is not None:
|
|
2452
|
+
return f"{base}?offset={offset}"
|
|
2453
|
+
elif limit is not None:
|
|
2454
|
+
return f"{base}?limit={limit}"
|
|
2455
|
+
|
|
2456
|
+
return base
|
|
2457
|
+
|
|
2458
|
+
|
|
2459
|
+
def _build_update_key_payload(
|
|
2460
|
+
key: KeyUpdate, json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler
|
|
2461
|
+
) -> JsonDict:
|
|
2462
|
+
# The json_handler.loads(key.json()) is because Pydantic can't serialize a date in a Python dict,
|
|
2463
|
+
# but can when converting to a json string.
|
|
2464
|
+
return { # type: ignore[attr-defined]
|
|
2465
|
+
k: v
|
|
2466
|
+
for k, v in json_handler.loads(key.model_dump_json(by_alias=True)).items()
|
|
2467
|
+
if v is not None and k != "key"
|
|
2468
|
+
}
|