Skip to content

Commit 9069614

Browse files
authored
Merge pull request #1145 from sanders41/meilisearch-1.12.0
Update for Meilisearch v1.12
2 parents 8674fce + 0b4d438 commit 9069614

19 files changed

+739
-37
lines changed

meilisearch_python_sdk/_batch.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
5+
from meilisearch_python_sdk._utils import get_async_client, get_client
6+
from meilisearch_python_sdk.errors import BatchNotFoundError
7+
from meilisearch_python_sdk.models.batch import BatchResult, BatchStatus
8+
9+
if TYPE_CHECKING:
10+
from httpx import AsyncClient as HttpxAsyncClient # pragma: no cover
11+
from httpx import Client as HttpxClient # pragma: no cover
12+
13+
from meilisearch_python_sdk._client import ( # pragma: no cover
14+
AsyncClient,
15+
Client,
16+
)
17+
18+
19+
async def async_get_batch(
20+
client: HttpxAsyncClient | AsyncClient, batch_uid: int
21+
) -> BatchResult | None:
22+
client_ = get_async_client(client)
23+
response = await client_.get(f"batches/{batch_uid}")
24+
25+
if response.status_code == 404:
26+
raise BatchNotFoundError(f"Batch {batch_uid} not found")
27+
28+
return BatchResult(**response.json())
29+
30+
31+
async def async_get_batches(client: HttpxAsyncClient | AsyncClient) -> BatchStatus:
32+
client_ = get_async_client(client)
33+
response = await client_.get("batches")
34+
35+
return BatchStatus(**response.json())
36+
37+
38+
def get_batch(client: HttpxClient | Client, batch_uid: int) -> BatchResult | None:
39+
client_ = get_client(client)
40+
response = client_.get(f"batches/{batch_uid}")
41+
42+
if response.status_code == 404:
43+
raise BatchNotFoundError(f"Batch {batch_uid} not found")
44+
45+
return BatchResult(**response.json())
46+
47+
48+
def get_batches(client: HttpxClient | Client) -> BatchStatus:
49+
client_ = get_client(client)
50+
response = client_.get("batches")
51+
52+
return BatchStatus(**response.json())

meilisearch_python_sdk/_client.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from httpx import Client as HttpxClient
1010

1111
from meilisearch_python_sdk import _task
12+
from meilisearch_python_sdk._batch import async_get_batch, async_get_batches, get_batch, get_batches
1213
from meilisearch_python_sdk._http_requests import AsyncHttpRequests, HttpRequests
1314
from meilisearch_python_sdk.errors import InvalidRestriction, MeilisearchApiError
1415
from meilisearch_python_sdk.index import AsyncIndex, Index
@@ -39,6 +40,7 @@
3940
import sys
4041
from types import TracebackType
4142

43+
from meilisearch_python_sdk.models.batch import BatchResult, BatchStatus
4244
from meilisearch_python_sdk.types import JsonMapping
4345

4446
if sys.version_info >= (3, 11):
@@ -770,6 +772,12 @@ async def swap_indexes(self, indexes: list[tuple[str, str]]) -> TaskInfo:
770772

771773
return TaskInfo(**response.json())
772774

775+
async def get_batch(self, batch_uid: int) -> BatchResult | None:
776+
return await async_get_batch(self, batch_uid)
777+
778+
async def get_batches(self) -> BatchStatus:
779+
return await async_get_batches(self)
780+
773781
async def cancel_tasks(
774782
self,
775783
*,
@@ -903,13 +911,15 @@ async def get_tasks(
903911
*,
904912
index_ids: list[str] | None = None,
905913
types: str | list[str] | None = None,
914+
reverse: bool | None = None,
906915
) -> TaskStatus:
907916
"""Get multiple tasks.
908917
909918
Args:
910919
index_ids: A list of index UIDs for which to get the tasks. If provided this will get the
911920
tasks only for the specified indexes, if not all tasks will be returned. Default = None
912921
types: Specify specific task types to retrieve. Default = None
922+
reverse: If True the tasks will be returned in reverse order. Default = None
913923
914924
Returns:
915925
Task statuses.
@@ -925,7 +935,9 @@ async def get_tasks(
925935
>>> async with AsyncClient("http://localhost.com", "masterKey") as client:
926936
>>> await client.get_tasks()
927937
"""
928-
return await _task.async_get_tasks(self.http_client, index_ids=index_ids, types=types)
938+
return await _task.async_get_tasks(
939+
self.http_client, index_ids=index_ids, types=types, reverse=reverse
940+
)
929941

930942
async def wait_for_task(
931943
self,
@@ -1586,6 +1598,12 @@ def swap_indexes(self, indexes: list[tuple[str, str]]) -> TaskInfo:
15861598

15871599
return TaskInfo(**response.json())
15881600

1601+
def get_batch(self, batch_uid: int) -> BatchResult | None:
1602+
return get_batch(self, batch_uid)
1603+
1604+
def get_batches(self) -> BatchStatus:
1605+
return get_batches(self)
1606+
15891607
def cancel_tasks(
15901608
self,
15911609
*,
@@ -1718,13 +1736,15 @@ def get_tasks(
17181736
*,
17191737
index_ids: list[str] | None = None,
17201738
types: str | list[str] | None = None,
1739+
reverse: bool | None = None,
17211740
) -> TaskStatus:
17221741
"""Get multiple tasks.
17231742
17241743
Args:
17251744
index_ids: A list of index UIDs for which to get the tasks. If provided this will get the
17261745
tasks only for the specified indexes, if not all tasks will be returned. Default = None
17271746
types: Specify specific task types to retrieve. Default = None
1747+
reverse: If True the tasks will be returned in reverse order. Default = None
17281748
17291749
Returns:
17301750
Task statuses.
@@ -1740,7 +1760,7 @@ def get_tasks(
17401760
>>> client = Client("http://localhost.com", "masterKey")
17411761
>>> client.get_tasks(client)
17421762
"""
1743-
return _task.get_tasks(self.http_client, index_ids=index_ids, types=types)
1763+
return _task.get_tasks(self.http_client, index_ids=index_ids, types=types, reverse=reverse)
17441764

17451765
def wait_for_task(
17461766
self,

meilisearch_python_sdk/_http_requests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def _send_request(
116116
http_method: Callable,
117117
path: str,
118118
body: Any | None = None,
119-
content_type: str = "applicaton/json",
119+
content_type: str = "application/json",
120120
compress: bool = False,
121121
) -> Response:
122122
headers = build_headers(content_type, compress)

meilisearch_python_sdk/_task.py

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from httpx import Client as HttpxClient
1111

1212
from meilisearch_python_sdk._http_requests import AsyncHttpRequests, HttpRequests
13+
from meilisearch_python_sdk._utils import get_async_client, get_client
1314
from meilisearch_python_sdk.errors import MeilisearchTaskFailedError, MeilisearchTimeoutError
1415
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
1516
from meilisearch_python_sdk.models.task import TaskInfo, TaskResult, TaskStatus
@@ -76,7 +77,7 @@ async def async_cancel_tasks(
7677
parameters["statuses"] = "enqueued,processing"
7778

7879
url = f"tasks/cancel?{urlencode(parameters)}"
79-
client_ = _get_async_client(client)
80+
client_ = get_async_client(client)
8081
response = await client_.post(url)
8182

8283
return TaskInfo(**response.json())
@@ -110,14 +111,17 @@ async def async_delete_tasks(
110111
parameters["statuses"] = "canceled,enqueued,failed,processing,succeeded"
111112

112113
url = f"tasks?{urlencode(parameters)}"
113-
client_ = _get_async_client(client)
114+
client_ = get_async_client(client)
114115
response = await client_.delete(url)
115116

116117
return TaskInfo(**response.json())
117118

118119

119-
async def async_get_task(client: HttpxAsyncClient | AsyncClient, task_id: int) -> TaskResult:
120-
client_ = _get_async_client(client)
120+
async def async_get_task(
121+
client: HttpxAsyncClient | AsyncClient,
122+
task_id: int,
123+
) -> TaskResult:
124+
client_ = get_async_client(client)
121125
response = await client_.get(f"tasks/{task_id}")
122126

123127
return TaskResult(**response.json())
@@ -128,12 +132,19 @@ async def async_get_tasks(
128132
*,
129133
index_ids: list[str] | None = None,
130134
types: str | list[str] | None = None,
135+
reverse: bool | None = None,
131136
) -> TaskStatus:
132137
url = f"tasks?indexUids={','.join(index_ids)}" if index_ids else "tasks"
133138
if types:
134139
formatted_types = ",".join(types) if isinstance(types, list) else types
135140
url = f"{url}&types={formatted_types}" if "?" in url else f"{url}?types={formatted_types}"
136-
client_ = _get_async_client(client)
141+
if reverse:
142+
url = (
143+
f"{url}&reverse={str(reverse).lower()}"
144+
if "?" in url
145+
else f"{url}?reverse={str(reverse).lower()}"
146+
)
147+
client_ = get_async_client(client)
137148
response = await client_.get(url)
138149

139150
return TaskStatus(**response.json())
@@ -147,7 +158,7 @@ async def async_wait_for_task(
147158
interval_in_ms: int = 50,
148159
raise_for_status: bool = False,
149160
) -> TaskResult:
150-
client_ = _get_async_client(client)
161+
client_ = get_async_client(client)
151162
handler = _get_json_handler(client)
152163
url = f"tasks/{task_id}"
153164
http_requests = AsyncHttpRequests(client_, handler)
@@ -207,7 +218,7 @@ def cancel_tasks(
207218
parameters["statuses"] = "enqueued,processing"
208219

209220
url = f"tasks/cancel?{urlencode(parameters)}"
210-
client_ = _get_client(client)
221+
client_ = get_client(client)
211222
response = client_.post(url)
212223

213224
return TaskInfo(**response.json())
@@ -241,14 +252,14 @@ def delete_tasks(
241252
parameters["statuses"] = "canceled,enqueued,failed,processing,succeeded"
242253

243254
url = f"tasks?{urlencode(parameters)}"
244-
client_ = _get_client(client)
255+
client_ = get_client(client)
245256
response = client_.delete(url)
246257

247258
return TaskInfo(**response.json())
248259

249260

250261
def get_task(client: HttpxClient | Client, task_id: int) -> TaskResult:
251-
client_ = _get_client(client)
262+
client_ = get_client(client)
252263
response = client_.get(f"tasks/{task_id}")
253264

254265
return TaskResult(**response.json())
@@ -259,12 +270,19 @@ def get_tasks(
259270
*,
260271
index_ids: list[str] | None = None,
261272
types: str | list[str] | None = None,
273+
reverse: bool | None = None,
262274
) -> TaskStatus:
263275
url = f"tasks?indexUids={','.join(index_ids)}" if index_ids else "tasks"
264276
if types:
265277
formatted_types = ",".join(types) if isinstance(types, list) else types
266278
url = f"{url}&types={formatted_types}" if "?" in url else f"{url}?types={formatted_types}"
267-
client_ = _get_client(client)
279+
if reverse:
280+
url = (
281+
f"{url}&reverse={str(reverse).lower()}"
282+
if "?" in url
283+
else f"{url}?reverse={str(reverse).lower()}"
284+
)
285+
client_ = get_client(client)
268286
response = client_.get(url)
269287

270288
return TaskStatus(**response.json())
@@ -278,7 +296,7 @@ def wait_for_task(
278296
interval_in_ms: int = 50,
279297
raise_for_status: bool = False,
280298
) -> TaskResult:
281-
client_ = _get_client(client)
299+
client_ = get_client(client)
282300
handler = _get_json_handler(client)
283301
url = f"tasks/{task_id}"
284302
http_requests = HttpRequests(client_, json_handler=handler)
@@ -310,24 +328,6 @@ def wait_for_task(
310328
time.sleep(interval_in_ms / 1000)
311329

312330

313-
def _get_async_client(
314-
client: AsyncClient | HttpxAsyncClient,
315-
) -> HttpxAsyncClient:
316-
if isinstance(client, HttpxAsyncClient):
317-
return client
318-
319-
return client.http_client
320-
321-
322-
def _get_client(
323-
client: Client | HttpxClient,
324-
) -> HttpxClient:
325-
if isinstance(client, HttpxClient):
326-
return client
327-
328-
return client.http_client
329-
330-
331331
def _get_json_handler(
332332
client: AsyncClient | Client | HttpxAsyncClient | HttpxClient,
333333
) -> BuiltinHandler | OrjsonHandler | UjsonHandler:

meilisearch_python_sdk/_utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,31 @@
33
import sys
44
from datetime import datetime
55
from functools import lru_cache
6+
from typing import TYPE_CHECKING
7+
8+
from httpx import AsyncClient as HttpxAsyncClient
9+
from httpx import Client as HttpxClient
10+
11+
if TYPE_CHECKING:
12+
from meilisearch_python_sdk._client import AsyncClient, Client # pragma: no cover
13+
14+
15+
def get_async_client(
16+
client: AsyncClient | HttpxAsyncClient,
17+
) -> HttpxAsyncClient:
18+
if isinstance(client, HttpxAsyncClient):
19+
return client
20+
21+
return client.http_client
22+
23+
24+
def get_client(
25+
client: Client | HttpxClient,
26+
) -> HttpxClient:
27+
if isinstance(client, HttpxClient):
28+
return client
29+
30+
return client.http_client
631

732

833
def iso_to_date_time(iso_date: datetime | str | None) -> datetime | None:

meilisearch_python_sdk/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = "3.6.2"
1+
VERSION = "4.0.0"

meilisearch_python_sdk/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from httpx import Response
22

33

4+
class BatchNotFoundError(Exception):
5+
pass
6+
7+
48
class InvalidDocumentError(Exception):
59
"""Error for documents that are not in a valid format for Meilisearch."""
610

0 commit comments

Comments
 (0)