meilisearch-python-sdk 7.5.2__py3-none-any.whl → 8.0.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.
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from datetime import datetime
4
- from typing import TYPE_CHECKING, Any, Literal
4
+ from typing import TYPE_CHECKING, Any, Literal, Self
5
5
 
6
6
  from camel_converter import dict_to_camel
7
7
  from httpx2 import AsyncClient as HttpxAsyncClient
@@ -45,18 +45,12 @@ from meilisearch_python_sdk.plugins import AsyncIndexPlugins
45
45
  from meilisearch_python_sdk.types import JsonDict
46
46
 
47
47
  if TYPE_CHECKING:
48
- import sys
49
48
  from ssl import SSLContext
50
49
  from types import TracebackType
51
50
 
52
51
  from meilisearch_python_sdk.models.batch import BatchResult, BatchStatus
53
52
  from meilisearch_python_sdk.types import JsonMapping
54
53
 
55
- if sys.version_info >= (3, 11):
56
- from typing import Self
57
- else:
58
- from typing_extensions import Self
59
-
60
54
 
61
55
  class AsyncClient(BaseClient):
62
56
  """Async client to connect to the Meilisearch API."""
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from datetime import datetime, timezone
3
+ from datetime import UTC, datetime
4
4
  from typing import TYPE_CHECKING
5
5
 
6
6
  from meilisearch_python_sdk._utils import encode_jwt
@@ -106,7 +106,7 @@ class BaseClient:
106
106
 
107
107
  payload["apiKeyUid"] = api_key.uid
108
108
  if expires_at:
109
- if expires_at <= datetime.now(tz=timezone.utc):
109
+ if expires_at <= datetime.now(tz=UTC):
110
110
  raise ValueError("expires_at must be a time in the future")
111
111
 
112
112
  payload["exp"] = int(datetime.timestamp(expires_at))
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from datetime import datetime
4
- from typing import TYPE_CHECKING, Any, Literal
4
+ from typing import TYPE_CHECKING, Any, Literal, Self
5
5
 
6
6
  from camel_converter import dict_to_camel
7
7
  from httpx2 import Client as HttpxClient
@@ -46,18 +46,12 @@ from meilisearch_python_sdk.plugins import IndexPlugins
46
46
  from meilisearch_python_sdk.types import JsonDict
47
47
 
48
48
  if TYPE_CHECKING:
49
- import sys
50
49
  from ssl import SSLContext
51
50
  from types import TracebackType
52
51
 
53
52
  from meilisearch_python_sdk.models.batch import BatchResult, BatchStatus
54
53
  from meilisearch_python_sdk.types import JsonMapping
55
54
 
56
- if sys.version_info >= (3, 11):
57
- from typing import Self
58
- else:
59
- from typing_extensions import Self
60
-
61
55
 
62
56
  class Client(BaseClient):
63
57
  """client to connect to the Meilisearch API."""
@@ -3,10 +3,8 @@ from __future__ import annotations
3
3
  import base64
4
4
  import hashlib
5
5
  import hmac
6
- import sys
7
6
  from calendar import timegm
8
- from datetime import datetime, timezone
9
- from functools import lru_cache
7
+ from datetime import UTC, datetime
10
8
  from typing import TYPE_CHECKING
11
9
 
12
10
  from httpx2 import AsyncClient as HttpxAsyncClient
@@ -46,11 +44,6 @@ def get_client(
46
44
  return client.http_client
47
45
 
48
46
 
49
- @lru_cache(maxsize=1)
50
- def use_task_groups() -> bool:
51
- return True if sys.version_info >= (3, 11) else False
52
-
53
-
54
47
  def _jwt_b64encode(data: bytes) -> str:
55
48
  return base64.urlsafe_b64encode(data).rstrip(b"=").decode()
56
49
 
@@ -97,7 +90,7 @@ def decode_jwt(
97
90
  if not isinstance(payload, dict):
98
91
  raise DecodeError("Invalid payload string: must be a json object")
99
92
 
100
- now = datetime.now(tz=timezone.utc).timestamp()
93
+ now = datetime.now(tz=UTC).timestamp()
101
94
 
102
95
  if "iat" in payload:
103
96
  try:
@@ -1 +1 @@
1
- VERSION = "7.5.2"
1
+ VERSION = "8.0.0"
@@ -6,7 +6,6 @@ from functools import wraps
6
6
  from typing import Any, NamedTuple
7
7
 
8
8
  from meilisearch_python_sdk import AsyncClient, Client
9
- from meilisearch_python_sdk._utils import use_task_groups
10
9
  from meilisearch_python_sdk.types import JsonMapping
11
10
 
12
11
 
@@ -210,11 +209,6 @@ async def _async_add_documents(
210
209
  )
211
210
 
212
211
  if wait_for_task:
213
- if not use_task_groups():
214
- waits = [async_client.wait_for_task(x.task_uid) for x in tasks]
215
- await asyncio.gather(*waits)
216
- return
217
-
218
212
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
219
213
  [tg.create_task(async_client.wait_for_task(x.task_uid)) for x in tasks]
220
214
 
@@ -5,7 +5,7 @@ from csv import DictReader
5
5
  from datetime import datetime
6
6
  from functools import cached_property, partial
7
7
  from pathlib import Path
8
- from typing import TYPE_CHECKING, Any, Literal
8
+ from typing import TYPE_CHECKING, Any, Literal, Self
9
9
 
10
10
  import aiofiles
11
11
  from camel_converter import to_snake
@@ -13,7 +13,6 @@ from httpx2 import AsyncClient
13
13
 
14
14
  from meilisearch_python_sdk._http_requests import AsyncHttpRequests
15
15
  from meilisearch_python_sdk._task import async_wait_for_task
16
- from meilisearch_python_sdk._utils import use_task_groups
17
16
  from meilisearch_python_sdk.errors import InvalidDocumentError
18
17
  from meilisearch_python_sdk.index._common import (
19
18
  BaseIndex,
@@ -63,16 +62,10 @@ from meilisearch_python_sdk.plugins import (
63
62
  from meilisearch_python_sdk.types import JsonDict
64
63
 
65
64
  if TYPE_CHECKING:
66
- import sys
67
65
  from collections.abc import Sequence
68
66
 
69
67
  from meilisearch_python_sdk.types import Filter, JsonMapping
70
68
 
71
- if sys.version_info >= (3, 11):
72
- from typing import Self
73
- else:
74
- from typing_extensions import Self
75
-
76
69
 
77
70
  class AsyncIndex(BaseIndex):
78
71
  """AsyncIndex class gives access to all indexes routes and child routes."""
@@ -748,52 +741,6 @@ class AsyncIndex(BaseIndex):
748
741
  )
749
742
 
750
743
  if self._concurrent_search_plugins:
751
- if not use_task_groups():
752
- concurrent_tasks: Any = []
753
- for plugin in self._concurrent_search_plugins:
754
- if plugin_has_method(plugin, "run_plugin"):
755
- concurrent_tasks.append(
756
- plugin.run_plugin( # type: ignore[union-attr]
757
- event=AsyncEvent.CONCURRENT,
758
- query=query,
759
- offset=offset,
760
- limit=limit,
761
- filter=filter,
762
- facets=facets,
763
- attributes_to_retrieve=attributes_to_retrieve,
764
- attributes_to_crop=attributes_to_crop,
765
- crop_length=crop_length,
766
- attributes_to_highlight=attributes_to_highlight,
767
- sort=sort,
768
- show_matches_position=show_matches_position,
769
- highlight_pre_tag=highlight_pre_tag,
770
- highlight_post_tag=highlight_post_tag,
771
- crop_marker=crop_marker,
772
- matching_strategy=matching_strategy,
773
- hits_per_page=hits_per_page,
774
- page=page,
775
- attributes_to_search_on=attributes_to_search_on,
776
- distinct=distinct,
777
- show_ranking_score=show_ranking_score,
778
- show_ranking_score_details=show_ranking_score_details,
779
- vector=vector,
780
- personalize=personalize,
781
- )
782
- )
783
-
784
- concurrent_tasks.append(self._http_requests.post(search_url, body=body))
785
-
786
- responses = await asyncio.gather(*concurrent_tasks)
787
- result = SearchResults[self.hits_type](**responses[-1].json()) # type: ignore[name-defined]
788
- if self._post_search_plugins:
789
- post = await _run_plugins(
790
- self._post_search_plugins, AsyncEvent.POST, search_results=result
791
- )
792
- if post.get("search_result"):
793
- result = post["search_result"]
794
-
795
- return result
796
-
797
744
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
798
745
  for plugin in self._concurrent_search_plugins:
799
746
  if plugin_has_method(plugin, "run_plugin"):
@@ -1023,52 +970,6 @@ class AsyncIndex(BaseIndex):
1023
970
  )
1024
971
 
1025
972
  if self._concurrent_facet_search_plugins:
1026
- if not use_task_groups():
1027
- tasks: Any = []
1028
- for plugin in self._concurrent_facet_search_plugins:
1029
- if plugin_has_method(plugin, "run_plugin"):
1030
- tasks.append(
1031
- plugin.run_plugin( # type: ignore[union-attr]
1032
- event=AsyncEvent.CONCURRENT,
1033
- query=query,
1034
- offset=offset,
1035
- limit=limit,
1036
- filter=filter,
1037
- facets=facets,
1038
- attributes_to_retrieve=attributes_to_retrieve,
1039
- attributes_to_crop=attributes_to_crop,
1040
- crop_length=crop_length,
1041
- attributes_to_highlight=attributes_to_highlight,
1042
- sort=sort,
1043
- show_matches_position=show_matches_position,
1044
- highlight_pre_tag=highlight_pre_tag,
1045
- highlight_post_tag=highlight_post_tag,
1046
- crop_marker=crop_marker,
1047
- matching_strategy=matching_strategy,
1048
- hits_per_page=hits_per_page,
1049
- page=page,
1050
- attributes_to_search_on=attributes_to_search_on,
1051
- show_ranking_score=show_ranking_score,
1052
- show_ranking_score_details=show_ranking_score_details,
1053
- ranking_score_threshold=ranking_score_threshold,
1054
- vector=vector,
1055
- exhaustive_facet_count=exhaustive_facet_count,
1056
- personalize=personalize,
1057
- )
1058
- )
1059
-
1060
- tasks.append(self._http_requests.post(search_url, body=body))
1061
- responses = await asyncio.gather(*tasks)
1062
- result = FacetSearchResults(**responses[-1].json())
1063
- if self._post_facet_search_plugins:
1064
- post = await _run_plugins(
1065
- self._post_facet_search_plugins, AsyncEvent.POST, result=result
1066
- )
1067
- if isinstance(post["generic_result"], FacetSearchResults):
1068
- result = post["generic_result"]
1069
-
1070
- return result
1071
-
1072
973
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
1073
974
  for plugin in self._concurrent_facet_search_plugins:
1074
975
  if plugin_has_method(plugin, "run_plugin"):
@@ -1368,42 +1269,6 @@ class AsyncIndex(BaseIndex):
1368
1269
  documents = pre["document_result"]
1369
1270
 
1370
1271
  if self._concurrent_add_documents_plugins:
1371
- if not use_task_groups():
1372
- tasks: Any = []
1373
- for plugin in self._concurrent_add_documents_plugins:
1374
- if plugin_has_method(plugin, "run_plugin"):
1375
- tasks.append(
1376
- plugin.run_plugin( # type: ignore[union-attr]
1377
- event=AsyncEvent.CONCURRENT,
1378
- documents=documents,
1379
- primary_key=primary_key,
1380
- )
1381
- )
1382
- if plugin_has_method(plugin, "run_document_plugin"):
1383
- tasks.append(
1384
- plugin.run_document_plugin( # type: ignore[union-attr]
1385
- event=AsyncEvent.CONCURRENT,
1386
- documents=documents,
1387
- primary_key=primary_key,
1388
- )
1389
- )
1390
-
1391
- tasks.append(self._http_requests.post(url, documents, compress=compress))
1392
-
1393
- responses = await asyncio.gather(*tasks)
1394
- result = TaskInfo(**responses[-1].json())
1395
- if self._post_add_documents_plugins:
1396
- post = await _run_plugins(
1397
- self._post_add_documents_plugins,
1398
- AsyncEvent.POST,
1399
- result=result,
1400
- documents=documents,
1401
- primary_key=primary_key,
1402
- )
1403
- if isinstance(post["generic_result"], TaskInfo):
1404
- result = post["generic_result"]
1405
- return result
1406
-
1407
1272
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
1408
1273
  for plugin in self._concurrent_add_documents_plugins:
1409
1274
  if plugin_has_method(plugin, "run_plugin"):
@@ -1508,10 +1373,6 @@ class AsyncIndex(BaseIndex):
1508
1373
  batch_data, primary_key, custom_metadata=custom_metadata, compress=compress
1509
1374
  )
1510
1375
 
1511
- if not use_task_groups():
1512
- batches = [add_batch_with_limit(data) for data in batch(documents, batch_size)]
1513
- return await asyncio.gather(*batches)
1514
-
1515
1376
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
1516
1377
  tasks = [
1517
1378
  tg.create_task(add_batch_with_limit(x)) for x in batch(documents, batch_size)
@@ -1519,15 +1380,6 @@ class AsyncIndex(BaseIndex):
1519
1380
 
1520
1381
  return [x.result() for x in tasks]
1521
1382
 
1522
- if not use_task_groups():
1523
- batches = [
1524
- self.add_documents(
1525
- x, primary_key, custom_metadata=custom_metadata, compress=compress
1526
- )
1527
- for x in batch(documents, batch_size)
1528
- ]
1529
- return await asyncio.gather(*batches)
1530
-
1531
1383
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
1532
1384
  tasks = [
1533
1385
  tg.create_task(
@@ -1622,29 +1474,6 @@ class AsyncIndex(BaseIndex):
1622
1474
  compress=compress,
1623
1475
  )
1624
1476
 
1625
- if not use_task_groups():
1626
- add_documents = []
1627
- for path in directory.iterdir():
1628
- if path.suffix == f".{document_type}":
1629
- documents = await _async_load_documents_from_file(
1630
- path, csv_delimiter, json_handler=self._json_handler
1631
- )
1632
- add_documents.append(add_docs_with_limit(documents))
1633
-
1634
- raise_on_no_documents(add_documents, document_type, directory_path)
1635
-
1636
- if len(add_documents) > 1:
1637
- # Send the first document on its own before starting the gather. Otherwise Meilisearch
1638
- # returns an error because it thinks all entries are trying to create the same index.
1639
- first_response = [await add_documents.pop(0)]
1640
-
1641
- responses = await asyncio.gather(*add_documents)
1642
- responses = [*first_response, *responses]
1643
- else:
1644
- responses = [await add_documents[0]]
1645
-
1646
- return responses
1647
-
1648
1477
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
1649
1478
  tasks = []
1650
1479
  all_results = []
@@ -1660,36 +1489,6 @@ class AsyncIndex(BaseIndex):
1660
1489
 
1661
1490
  return [*all_results, *[x.result() for x in tasks]]
1662
1491
 
1663
- if not use_task_groups():
1664
- add_documents = []
1665
- for path in directory.iterdir():
1666
- if path.suffix == f".{document_type}":
1667
- documents = await _async_load_documents_from_file(
1668
- path, csv_delimiter, json_handler=self._json_handler
1669
- )
1670
- add_documents.append(
1671
- self.add_documents(
1672
- documents,
1673
- primary_key,
1674
- custom_metadata=custom_metadata,
1675
- compress=compress,
1676
- )
1677
- )
1678
-
1679
- raise_on_no_documents(add_documents, document_type, directory_path)
1680
-
1681
- if len(add_documents) > 1:
1682
- # Send the first document on its own before starting the gather. Otherwise Meilisearch
1683
- # returns an error because it thinks all entries are trying to create the same index.
1684
- first_response = [await add_documents.pop()]
1685
-
1686
- responses = await asyncio.gather(*add_documents)
1687
- responses = [*first_response, *responses]
1688
- else:
1689
- responses = [await add_documents[0]]
1690
-
1691
- return responses
1692
-
1693
1492
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
1694
1493
  tasks = []
1695
1494
  all_results = []
@@ -2109,43 +1908,6 @@ class AsyncIndex(BaseIndex):
2109
1908
  documents = pre["document_result"]
2110
1909
 
2111
1910
  if self._concurrent_update_documents_plugins:
2112
- if not use_task_groups():
2113
- tasks: Any = []
2114
- for plugin in self._concurrent_update_documents_plugins:
2115
- if plugin_has_method(plugin, "run_plugin"):
2116
- tasks.append(
2117
- plugin.run_plugin( # type: ignore[union-attr]
2118
- event=AsyncEvent.CONCURRENT,
2119
- documents=documents,
2120
- primary_key=primary_key,
2121
- )
2122
- )
2123
- if plugin_has_method(plugin, "run_document_plugin"):
2124
- tasks.append(
2125
- plugin.run_document_plugin( # type: ignore[union-attr]
2126
- event=AsyncEvent.CONCURRENT,
2127
- documents=documents,
2128
- primary_key=primary_key,
2129
- )
2130
- )
2131
-
2132
- tasks.append(self._http_requests.put(url, documents, compress=compress))
2133
-
2134
- responses = await asyncio.gather(*tasks)
2135
- result = TaskInfo(**responses[-1].json())
2136
- if self._post_update_documents_plugins:
2137
- post = await _run_plugins(
2138
- self._post_update_documents_plugins,
2139
- AsyncEvent.POST,
2140
- result=result,
2141
- documents=documents,
2142
- primary_key=primary_key,
2143
- )
2144
- if isinstance(post["generic_result"], TaskInfo):
2145
- result = post["generic_result"]
2146
-
2147
- return result
2148
-
2149
1911
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2150
1912
  for plugin in self._concurrent_update_documents_plugins:
2151
1913
  if plugin_has_method(plugin, "run_plugin"):
@@ -2259,29 +2021,12 @@ class AsyncIndex(BaseIndex):
2259
2021
  compress=compress,
2260
2022
  )
2261
2023
 
2262
- if not use_task_groups():
2263
- batches = [update_batch_with_limit(x) for x in batch(documents, batch_size)]
2264
- return await asyncio.gather(*batches)
2265
-
2266
2024
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2267
2025
  tasks = [
2268
2026
  tg.create_task(update_batch_with_limit(x)) for x in batch(documents, batch_size)
2269
2027
  ]
2270
2028
  return [x.result() for x in tasks]
2271
2029
 
2272
- if not use_task_groups():
2273
- batches = [
2274
- self.update_documents(
2275
- x,
2276
- primary_key,
2277
- custom_metadata=custom_metadata,
2278
- skip_creation=skip_creation,
2279
- compress=compress,
2280
- )
2281
- for x in batch(documents, batch_size)
2282
- ]
2283
- return await asyncio.gather(*batches)
2284
-
2285
2030
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2286
2031
  tasks = [
2287
2032
  tg.create_task(
@@ -2369,36 +2114,6 @@ class AsyncIndex(BaseIndex):
2369
2114
  )
2370
2115
  return [response]
2371
2116
 
2372
- if not use_task_groups():
2373
- update_documents = []
2374
- for path in directory.iterdir():
2375
- if path.suffix == f".{document_type}":
2376
- documents = await _async_load_documents_from_file(
2377
- path, csv_delimiter, json_handler=self._json_handler
2378
- )
2379
- update_documents.append(
2380
- self.update_documents(
2381
- documents,
2382
- primary_key,
2383
- custom_metadata=custom_metadata,
2384
- skip_creation=skip_creation,
2385
- compress=compress,
2386
- )
2387
- )
2388
-
2389
- raise_on_no_documents(update_documents, document_type, directory_path)
2390
-
2391
- if len(update_documents) > 1:
2392
- # Send the first document on its own before starting the gather. Otherwise Meilisearch
2393
- # returns an error because it thinks all entries are trying to create the same index.
2394
- first_response = [await update_documents.pop()]
2395
- responses = await asyncio.gather(*update_documents)
2396
- responses = [*first_response, *responses]
2397
- else:
2398
- responses = [await update_documents[0]]
2399
-
2400
- return responses
2401
-
2402
2117
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2403
2118
  tasks = []
2404
2119
  results = []
@@ -2514,40 +2229,6 @@ class AsyncIndex(BaseIndex):
2514
2229
  concurrency_limit=concurrency_limit,
2515
2230
  )
2516
2231
 
2517
- if not use_task_groups():
2518
- responses: list[TaskInfo] = []
2519
-
2520
- update_documents = []
2521
- for path in directory.iterdir():
2522
- if path.suffix == f".{document_type}":
2523
- documents = await _async_load_documents_from_file(
2524
- path, csv_delimiter, json_handler=self._json_handler
2525
- )
2526
- update_documents.append(
2527
- self.update_documents_in_batches(
2528
- documents,
2529
- batch_size=batch_size,
2530
- primary_key=primary_key,
2531
- custom_metadata=custom_metadata,
2532
- compress=compress,
2533
- skip_creation=skip_creation,
2534
- concurrency_limit=concurrency_limit,
2535
- )
2536
- )
2537
-
2538
- raise_on_no_documents(update_documents, document_type, directory_path)
2539
-
2540
- if len(update_documents) > 1:
2541
- # Send the first document on its own before starting the gather. Otherwise Meilisearch
2542
- # returns an error because it thinks all entries are trying to create the same index.
2543
- first_response = await update_documents.pop()
2544
- responses_gather = await asyncio.gather(*update_documents)
2545
- responses = [*first_response, *[x for y in responses_gather for x in y]]
2546
- else:
2547
- responses = await update_documents[0]
2548
-
2549
- return responses
2550
-
2551
2232
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2552
2233
  results = []
2553
2234
  tasks = []
@@ -2795,25 +2476,6 @@ class AsyncIndex(BaseIndex):
2795
2476
  )
2796
2477
 
2797
2478
  if self._concurrent_delete_document_plugins:
2798
- if not use_task_groups():
2799
- tasks: Any = []
2800
- for plugin in self._concurrent_delete_document_plugins:
2801
- tasks.append(
2802
- plugin.run_plugin(event=AsyncEvent.CONCURRENT, document_id=document_id)
2803
- )
2804
-
2805
- tasks.append(self._http_requests.delete(url))
2806
-
2807
- responses = await asyncio.gather(*tasks)
2808
- result = TaskInfo(**responses[-1].json())
2809
- if self._post_delete_document_plugins:
2810
- post = await _run_plugins(
2811
- self._post_delete_document_plugins, AsyncEvent.POST, result=result
2812
- )
2813
- if isinstance(post.get("generic_result"), TaskInfo):
2814
- result = post["generic_result"]
2815
- return result
2816
-
2817
2479
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2818
2480
  for plugin in self._concurrent_delete_document_plugins:
2819
2481
  tg.create_task(
@@ -2874,23 +2536,6 @@ class AsyncIndex(BaseIndex):
2874
2536
  await _run_plugins(self._pre_delete_documents_plugins, AsyncEvent.PRE, ids=ids)
2875
2537
 
2876
2538
  if self._concurrent_delete_documents_plugins:
2877
- if not use_task_groups():
2878
- tasks: Any = []
2879
- for plugin in self._concurrent_delete_documents_plugins:
2880
- tasks.append(plugin.run_plugin(event=AsyncEvent.CONCURRENT, ids=ids))
2881
-
2882
- tasks.append(self._http_requests.post(url, ids))
2883
-
2884
- responses = await asyncio.gather(*tasks)
2885
- result = TaskInfo(**responses[-1].json())
2886
- if self._post_delete_documents_plugins:
2887
- post = await _run_plugins(
2888
- self._post_delete_documents_plugins, AsyncEvent.POST, result=result
2889
- )
2890
- if isinstance(post.get("generic_result"), TaskInfo):
2891
- result = post["generic_result"]
2892
- return result
2893
-
2894
2539
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2895
2540
  for plugin in self._concurrent_delete_documents_plugins:
2896
2541
  tg.create_task(plugin.run_plugin(event=AsyncEvent.CONCURRENT, ids=ids))
@@ -2951,25 +2596,6 @@ class AsyncIndex(BaseIndex):
2951
2596
  )
2952
2597
 
2953
2598
  if self._concurrent_delete_documents_by_filter_plugins:
2954
- if not use_task_groups():
2955
- tasks: Any = []
2956
- for plugin in self._concurrent_delete_documents_by_filter_plugins:
2957
- tasks.append(plugin.run_plugin(event=AsyncEvent.CONCURRENT, filter=filter))
2958
-
2959
- tasks.append(self._http_requests.post(url, body={"filter": filter}))
2960
-
2961
- responses = await asyncio.gather(*tasks)
2962
- result = TaskInfo(**responses[-1].json())
2963
- if self._post_delete_documents_by_filter_plugins:
2964
- post = await _run_plugins(
2965
- self._post_delete_documents_by_filter_plugins,
2966
- AsyncEvent.POST,
2967
- result=result,
2968
- )
2969
- if isinstance(post["generic_result"], TaskInfo):
2970
- result = post["generic_result"]
2971
- return result
2972
-
2973
2599
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
2974
2600
  for plugin in self._concurrent_delete_documents_by_filter_plugins:
2975
2601
  tg.create_task(plugin.run_plugin(event=AsyncEvent.CONCURRENT, filter=filter))
@@ -3044,22 +2670,11 @@ class AsyncIndex(BaseIndex):
3044
2670
  filter_value, custom_metadata=custom_metadata
3045
2671
  )
3046
2672
 
3047
- if not use_task_groups():
3048
- tasks = [delete_with_limit(filter) for filter in filters]
3049
- return await asyncio.gather(*tasks)
3050
-
3051
2673
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
3052
2674
  tg_tasks = [tg.create_task(delete_with_limit(filter)) for filter in filters]
3053
2675
 
3054
2676
  return [x.result() for x in tg_tasks]
3055
2677
 
3056
- if not use_task_groups():
3057
- tasks = [
3058
- self.delete_documents_by_filter(filter, custom_metadata=custom_metadata)
3059
- for filter in filters
3060
- ]
3061
- return await asyncio.gather(*tasks)
3062
-
3063
2678
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
3064
2679
  tg_tasks = [
3065
2680
  tg.create_task(
@@ -3098,23 +2713,6 @@ class AsyncIndex(BaseIndex):
3098
2713
  await _run_plugins(self._pre_delete_all_documents_plugins, AsyncEvent.PRE)
3099
2714
 
3100
2715
  if self._concurrent_delete_all_documents_plugins:
3101
- if not use_task_groups():
3102
- tasks: Any = []
3103
- for plugin in self._concurrent_delete_all_documents_plugins:
3104
- tasks.append(plugin.run_plugin(event=AsyncEvent.CONCURRENT))
3105
-
3106
- tasks.append(self._http_requests.delete(url))
3107
-
3108
- responses = await asyncio.gather(*tasks)
3109
- result = TaskInfo(**responses[-1].json())
3110
- if self._post_delete_all_documents_plugins:
3111
- post = await _run_plugins(
3112
- self._post_delete_all_documents_plugins, AsyncEvent.POST, result=result
3113
- )
3114
- if isinstance(post.get("generic_result"), TaskInfo):
3115
- result = post["generic_result"]
3116
- return result
3117
-
3118
2716
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
3119
2717
  for plugin in self._concurrent_delete_all_documents_plugins:
3120
2718
  tg.create_task(plugin.run_plugin(event=AsyncEvent.CONCURRENT))
@@ -4800,45 +4398,11 @@ async def _run_plugins(
4800
4398
  event: AsyncEvent,
4801
4399
  **kwargs: Any, # noqa: ANN401
4802
4400
  ) -> dict[str, Any]:
4803
- generic_plugins = []
4804
- document_plugins = []
4805
- search_plugins = []
4806
4401
  results: dict[str, Any] = {
4807
4402
  "generic_result": None,
4808
4403
  "document_result": None,
4809
4404
  "search_result": None,
4810
4405
  }
4811
- if not use_task_groups():
4812
- for plugin in plugins:
4813
- if plugin_has_method(plugin, "run_plugin"):
4814
- generic_plugins.append(plugin.run_plugin(event=event, **kwargs)) # type: ignore[union-attr]
4815
- if plugin_has_method(plugin, "run_document_plugin"):
4816
- document_plugins.append(plugin.run_document_plugin(event=event, **kwargs)) # type: ignore[union-attr]
4817
- if plugin_has_method(plugin, "run_post_search_plugin"):
4818
- search_plugins.append(plugin.run_post_search_plugin(event=event, **kwargs)) # type: ignore[union-attr]
4819
- if generic_plugins:
4820
- generic_results = await asyncio.gather(*generic_plugins)
4821
- for result in reversed(generic_results):
4822
- if result is not None:
4823
- results["generic_result"] = result
4824
- break
4825
-
4826
- if document_plugins:
4827
- document_results = await asyncio.gather(*document_plugins)
4828
- for result in reversed(document_results):
4829
- if result is not None:
4830
- results["document_result"] = result
4831
- break
4832
-
4833
- if search_plugins:
4834
- search_results = await asyncio.gather(*search_plugins)
4835
- for result in reversed(search_results):
4836
- if result is not None:
4837
- results["search_result"] = result
4838
- break
4839
-
4840
- return results
4841
-
4842
4406
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
4843
4407
  generic_tasks = []
4844
4408
  document_tasks = []
@@ -4,7 +4,7 @@ from csv import DictReader
4
4
  from datetime import datetime
5
5
  from functools import cached_property
6
6
  from pathlib import Path
7
- from typing import TYPE_CHECKING, Any, Literal
7
+ from typing import TYPE_CHECKING, Any, Literal, Self
8
8
 
9
9
  from camel_converter import to_snake
10
10
  from httpx2 import Client
@@ -60,16 +60,10 @@ from meilisearch_python_sdk.plugins import (
60
60
  from meilisearch_python_sdk.types import JsonDict
61
61
 
62
62
  if TYPE_CHECKING:
63
- import sys
64
63
  from collections.abc import Sequence
65
64
 
66
65
  from meilisearch_python_sdk.types import Filter, JsonMapping
67
66
 
68
- if sys.version_info >= (3, 11):
69
- from typing import Self
70
- else:
71
- from typing_extensions import Self
72
-
73
67
 
74
68
  class Index(BaseIndex):
75
69
  """Index class gives access to all indexes routes and child routes."""
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from enum import Enum
3
+ from enum import StrEnum
4
4
  from typing import Any, Literal
5
5
 
6
6
  from camel_converter.pydantic_base import CamelBase
@@ -138,7 +138,7 @@ class Embedders(CamelBase):
138
138
  ]
139
139
 
140
140
 
141
- class ProximityPrecision(str, Enum):
141
+ class ProximityPrecision(StrEnum):
142
142
  BY_WORD = "byWord"
143
143
  BY_ATTRIBUTE = "byAttribute"
144
144
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: meilisearch-python-sdk
3
- Version: 7.5.2
3
+ Version: 8.0.0
4
4
  Summary: A Python client providing both async and sync support for the Meilisearch API
5
5
  Project-URL: repository, https://github.com/sanders41/meilisearch-python-sdk
6
6
  Project-URL: homepage, https://github.com/sanders41/meilisearch-python-sdk
@@ -34,13 +34,12 @@ Classifier: Development Status :: 5 - Production/Stable
34
34
  Classifier: Intended Audience :: Developers
35
35
  Classifier: License :: OSI Approved :: MIT License
36
36
  Classifier: Operating System :: OS Independent
37
- Classifier: Programming Language :: Python :: 3.10
38
37
  Classifier: Programming Language :: Python :: 3.11
39
38
  Classifier: Programming Language :: Python :: 3.12
40
39
  Classifier: Programming Language :: Python :: 3.13
41
40
  Classifier: Programming Language :: Python :: 3.14
42
41
  Classifier: Typing :: Typed
43
- Requires-Python: >=3.10
42
+ Requires-Python: >=3.11
44
43
  Requires-Dist: aiofiles>=0.7
45
44
  Requires-Dist: camel-converter[pydantic]>=1.0.0
46
45
  Requires-Dist: httpx2[http2]>=2.0.0
@@ -2,23 +2,23 @@ meilisearch_python_sdk/__init__.py,sha256=SB0Jlm6FwT13J9xasZKseZzTWBk0hkfe1CWyWm
2
2
  meilisearch_python_sdk/_batch.py,sha256=Nies12NEo-o6qhi729Ily_ufLK_4lxUUIAiAtU30LiY,5920
3
3
  meilisearch_python_sdk/_http_requests.py,sha256=IWNEZll2W1jYen7aZY70kTXU4oXl-bfXl82QyfPvaoo,7900
4
4
  meilisearch_python_sdk/_task.py,sha256=NoXg7stOUfb874G3npu4GpaAWIMXd_ZFntiH7AiCrb4,15947
5
- meilisearch_python_sdk/_utils.py,sha256=6Yy0tRe6V0kocVmaYb0rO2Hw2GmvEeY_XLY05P5bMq0,4317
6
- meilisearch_python_sdk/_version.py,sha256=hDQo9HBRSBTvAOP7CE5G9xjcdKI6HFf-8K5do_VBkrc,18
7
- meilisearch_python_sdk/decorators.py,sha256=wgznbwCYRc1_nVfQaOgj7DcOMejB9mJIWqltW6CimnY,8836
5
+ meilisearch_python_sdk/_utils.py,sha256=9_yLUq3mMNCrMWl5rSV9Y6bMTgRzqb7wcfCfHUxUE0k,4147
6
+ meilisearch_python_sdk/_version.py,sha256=piBa6YAu0RK9obt-TZ0uo6V7DZ1GWEW0CSxyexKCmJs,18
7
+ meilisearch_python_sdk/decorators.py,sha256=IzjBeNDKjmTLvRgkDr3XJBfRI5NxiJnGQv1XM6PkjJc,8607
8
8
  meilisearch_python_sdk/errors.py,sha256=8cJpHJbJR7t6Tyt15yXVUpNYKbfWt2HTKiBCISDIBrA,3352
9
9
  meilisearch_python_sdk/json_handler.py,sha256=lzwiBP4ASjdBiBLQAjp9akbL-9TnaWnu8Ayy380R_s0,2121
10
10
  meilisearch_python_sdk/plugins.py,sha256=ACk07_3ySHnz_clF3IiJRKeAlSGhpyQfn4taqAozIjo,3750
11
11
  meilisearch_python_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  meilisearch_python_sdk/types.py,sha256=nf-_ZjbPVGdVg-spkfFoaGebQvzmWqiDWuyBwR_qWJk,473
13
13
  meilisearch_python_sdk/_client/__init__.py,sha256=ld4FGQM5wt-Ygtt4z4UgZKL8dQ1jY98NY1Fst_-bhA4,164
14
- meilisearch_python_sdk/_client/_async_client.py,sha256=L0BlaFdDWjeYqZsbYVMD_hRt0VNPWGRLzhTnWStkn9k,51123
15
- meilisearch_python_sdk/_client/_base_client.py,sha256=z5YYi_ke6SVd58kwlVTrlbA_2CnxwCMCoMZxJxg8Tuo,4238
16
- meilisearch_python_sdk/_client/_client.py,sha256=k70ofAzxRI14Ge3ynrZY_k0BCF8ipCLfetrC9R5KJPw,49614
14
+ meilisearch_python_sdk/_client/_async_client.py,sha256=GwpEPMnfB74lyr8oEW3v2gx7mXemiYMByf0cO_NjygI,50992
15
+ meilisearch_python_sdk/_client/_base_client.py,sha256=azGDRTmVDIciF-kZ9NQ0o75kLqsYRaepf07HW1iGgV8,4224
16
+ meilisearch_python_sdk/_client/_client.py,sha256=a9-7EemSP84Sw8UeSMtpEQYedGZqs-sceeHNuDM7_Nk,49483
17
17
  meilisearch_python_sdk/_client/_common.py,sha256=WLssNzHkSRw_j98kTV-qfzqc5AcCZ_Utar2hn2fShso,3141
18
18
  meilisearch_python_sdk/index/__init__.py,sha256=sULiCF_Gqa66SDLuyvlHQ1NW-6ch5sWU6UNZ572sdEA,152
19
19
  meilisearch_python_sdk/index/_common.py,sha256=zX0vE4C9dMYzijJzGFFVWDy5fw_xwP7ZCJFRMaprT58,11298
20
- meilisearch_python_sdk/index/async_index.py,sha256=AaBWu0_z-fdu-ccIkwRDC_YTTnqpavrOEEmsSTSTD-U,212048
21
- meilisearch_python_sdk/index/index.py,sha256=x4zqZYoC9E5Eq0kERjObHItEPA1axFeHQD8MsGIsrnM,161580
20
+ meilisearch_python_sdk/index/async_index.py,sha256=eUo63ZlvggcapoAHoI3wZhr73Gzg79SjOCkLNzLYyvw,191846
21
+ meilisearch_python_sdk/index/index.py,sha256=EAktEKuqUNtw2ajDInIHNufZkhQjSkJu47Vupq2HU5Y,161449
22
22
  meilisearch_python_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  meilisearch_python_sdk/models/batch.py,sha256=xgEfOuHKBmxzmzOddt6ZW-o1G6s0QVeIBt7S94k7QrE,1147
24
24
  meilisearch_python_sdk/models/client.py,sha256=BlYQtckkREp3_-kvxSqGfn2UhFvDp23QyxtlrSDwinA,1769
@@ -26,11 +26,11 @@ meilisearch_python_sdk/models/documents.py,sha256=eT3FHrPND-g2IzNRyOHQApTTJ1WbFc
26
26
  meilisearch_python_sdk/models/health.py,sha256=hvruti7ylsk7bAh8RPOhTPcRrjx6MPgdkDFX9vZ5Qks,95
27
27
  meilisearch_python_sdk/models/index.py,sha256=oXosJk36cnDcWIaN-ZBUlqhxH_oPk3ZekxPVgeveIRs,1830
28
28
  meilisearch_python_sdk/models/search.py,sha256=URNS9zlpyiic2IKNc8RNtHohLZqjrbC8GOQWR5RAUb0,3904
29
- meilisearch_python_sdk/models/settings.py,sha256=kocYiTiAqPXi6-wCUs0sUkxJouks0747tnAW_iUATtY,5874
29
+ meilisearch_python_sdk/models/settings.py,sha256=ynrQ1CMj2HrGl1yTyXqROnyAy7GLMcXmvhrj-KAsYEc,5875
30
30
  meilisearch_python_sdk/models/task.py,sha256=nDD-S7K-uL4gcYU-tyPstBWcnJi_8MiDwc53GG6i304,1105
31
31
  meilisearch_python_sdk/models/version.py,sha256=ISU-ZHgpXLBFDuMpWWfKdVo9Dq1HcD7s6HFnCiGTF8Y,184
32
32
  meilisearch_python_sdk/models/webhook.py,sha256=zSkEJJdEflinW3_seJTLQ_ZWs4w-pjTD3SS1ZawC32k,455
33
- meilisearch_python_sdk-7.5.2.dist-info/METADATA,sha256=OdOegStWkKIqy_Sdkc4XZFKKzlal2W_5OC71bQzOjR4,9403
34
- meilisearch_python_sdk-7.5.2.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
35
- meilisearch_python_sdk-7.5.2.dist-info/licenses/LICENSE,sha256=xVzevI1TrlKfM0plmJ7vfK1Muu0V9n-dGE8RnDrOFlM,1069
36
- meilisearch_python_sdk-7.5.2.dist-info/RECORD,,
33
+ meilisearch_python_sdk-8.0.0.dist-info/METADATA,sha256=_vtKvXShqRdqTvlVT-iz21jeRQTuF799SP68-CDQFj8,9352
34
+ meilisearch_python_sdk-8.0.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
35
+ meilisearch_python_sdk-8.0.0.dist-info/licenses/LICENSE,sha256=xVzevI1TrlKfM0plmJ7vfK1Muu0V9n-dGE8RnDrOFlM,1069
36
+ meilisearch_python_sdk-8.0.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.32.0
2
+ Generator: hatchling 1.32.4
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any