meilisearch-python-sdk 3.0.0__py3-none-any.whl → 3.1.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.

Potentially problematic release.


This version of meilisearch-python-sdk might be problematic. Click here for more details.

@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from datetime import datetime, timezone
4
4
  from ssl import SSLContext
5
- from typing import TYPE_CHECKING
5
+ from typing import TYPE_CHECKING, Any
6
6
 
7
7
  import jwt
8
8
  from httpx import AsyncClient as HttpxAsyncClient
@@ -27,12 +27,13 @@ from meilisearch_python_sdk.models.settings import MeilisearchSettings
27
27
  from meilisearch_python_sdk.models.task import TaskInfo, TaskResult, TaskStatus
28
28
  from meilisearch_python_sdk.models.version import Version
29
29
  from meilisearch_python_sdk.plugins import AsyncIndexPlugins, IndexPlugins
30
+ from meilisearch_python_sdk.types import JsonDict
30
31
 
31
32
  if TYPE_CHECKING: # pragma: no cover
32
33
  import sys
33
34
  from types import TracebackType
34
35
 
35
- from meilisearch_python_sdk.types import JsonDict, JsonMapping
36
+ from meilisearch_python_sdk.types import JsonMapping
36
37
 
37
38
  if sys.version_info >= (3, 11):
38
39
  from typing import Self
@@ -219,6 +220,7 @@ class AsyncClient(BaseClient):
219
220
  wait: bool = True,
220
221
  timeout_in_ms: int | None = None,
221
222
  plugins: AsyncIndexPlugins | None = None,
223
+ hits_type: Any = JsonDict,
222
224
  ) -> AsyncIndex:
223
225
  """Creates a new index.
224
226
 
@@ -238,6 +240,8 @@ class AsyncClient(BaseClient):
238
240
  MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
239
241
  if the `None` option is used the wait time could be very long. Defaults to None.
240
242
  plugins: Optional plugins can be provided to extend functionality.
243
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
244
+ JsonDict
241
245
 
242
246
  Returns:
243
247
 
@@ -263,6 +267,7 @@ class AsyncClient(BaseClient):
263
267
  timeout_in_ms=timeout_in_ms,
264
268
  plugins=plugins,
265
269
  json_handler=self.json_handler,
270
+ hits_type=hits_type,
266
271
  )
267
272
 
268
273
  async def create_snapshot(self) -> TaskInfo:
@@ -436,7 +441,12 @@ class AsyncClient(BaseClient):
436
441
  return ClientStats(**response.json())
437
442
 
438
443
  async def get_or_create_index(
439
- self, uid: str, primary_key: str | None = None, *, plugins: AsyncIndexPlugins | None = None
444
+ self,
445
+ uid: str,
446
+ primary_key: str | None = None,
447
+ *,
448
+ plugins: AsyncIndexPlugins | None = None,
449
+ hits_type: Any = JsonDict,
440
450
  ) -> AsyncIndex:
441
451
  """Get an index, or create it if it doesn't exist.
442
452
 
@@ -445,6 +455,8 @@ class AsyncClient(BaseClient):
445
455
  uid: The index's unique identifier.
446
456
  primary_key: The primary key of the documents. Defaults to None.
447
457
  plugins: Optional plugins can be provided to extend functionality.
458
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
459
+ JsonDict
448
460
 
449
461
  Returns:
450
462
 
@@ -467,7 +479,9 @@ class AsyncClient(BaseClient):
467
479
  except MeilisearchApiError as err:
468
480
  if "index_not_found" not in err.code:
469
481
  raise
470
- index_instance = await self.create_index(uid, primary_key, plugins=plugins)
482
+ index_instance = await self.create_index(
483
+ uid, primary_key, plugins=plugins, hits_type=hits_type
484
+ )
471
485
  return index_instance
472
486
 
473
487
  async def create_key(self, key: KeyCreate) -> Key:
@@ -618,12 +632,16 @@ class AsyncClient(BaseClient):
618
632
 
619
633
  return Key(**response.json())
620
634
 
621
- async def multi_search(self, queries: list[SearchParams]) -> list[SearchResultsWithUID]:
635
+ async def multi_search(
636
+ self, queries: list[SearchParams], *, hits_type: Any = JsonDict
637
+ ) -> list[SearchResultsWithUID]:
622
638
  """Multi-index search.
623
639
 
624
640
  Args:
625
641
 
626
642
  queries: List of SearchParameters
643
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
644
+ JsonDict
627
645
 
628
646
  Returns:
629
647
 
@@ -651,7 +669,7 @@ class AsyncClient(BaseClient):
651
669
  body={"queries": [x.model_dump(by_alias=True) for x in queries]}, # type: ignore[attr-defined]
652
670
  )
653
671
 
654
- return [SearchResultsWithUID(**x) for x in response.json()["results"]]
672
+ return [SearchResultsWithUID[hits_type](**x) for x in response.json()["results"]]
655
673
 
656
674
  async def get_raw_index(self, uid: str) -> IndexInfo | None:
657
675
  """Gets the index and returns all the index information rather than an AsyncIndex instance.
@@ -1083,6 +1101,7 @@ class Client(BaseClient):
1083
1101
  wait: bool = True,
1084
1102
  timeout_in_ms: int | None = None,
1085
1103
  plugins: IndexPlugins | None = None,
1104
+ hits_type: Any = JsonDict,
1086
1105
  ) -> Index:
1087
1106
  """Creates a new index.
1088
1107
 
@@ -1102,6 +1121,8 @@ class Client(BaseClient):
1102
1121
  MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
1103
1122
  if the `None` option is used the wait time could be very long. Defaults to None.
1104
1123
  plugins: Optional plugins can be provided to extend functionality.
1124
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
1125
+ JsonDict
1105
1126
 
1106
1127
  Returns:
1107
1128
 
@@ -1127,6 +1148,7 @@ class Client(BaseClient):
1127
1148
  timeout_in_ms=timeout_in_ms,
1128
1149
  plugins=plugins,
1129
1150
  json_handler=self.json_handler,
1151
+ hits_type=hits_type,
1130
1152
  )
1131
1153
 
1132
1154
  def create_snapshot(self) -> TaskInfo:
@@ -1296,7 +1318,12 @@ class Client(BaseClient):
1296
1318
  return ClientStats(**response.json())
1297
1319
 
1298
1320
  def get_or_create_index(
1299
- self, uid: str, primary_key: str | None = None, *, plugins: IndexPlugins | None = None
1321
+ self,
1322
+ uid: str,
1323
+ primary_key: str | None = None,
1324
+ *,
1325
+ plugins: IndexPlugins | None = None,
1326
+ hits_type: Any = JsonDict,
1300
1327
  ) -> Index:
1301
1328
  """Get an index, or create it if it doesn't exist.
1302
1329
 
@@ -1305,6 +1332,8 @@ class Client(BaseClient):
1305
1332
  uid: The index's unique identifier.
1306
1333
  primary_key: The primary key of the documents. Defaults to None.
1307
1334
  plugins: Optional plugins can be provided to extend functionality.
1335
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
1336
+ JsonDict
1308
1337
 
1309
1338
  Returns:
1310
1339
 
@@ -1327,7 +1356,9 @@ class Client(BaseClient):
1327
1356
  except MeilisearchApiError as err:
1328
1357
  if "index_not_found" not in err.code:
1329
1358
  raise
1330
- index_instance = self.create_index(uid, primary_key, plugins=plugins)
1359
+ index_instance = self.create_index(
1360
+ uid, primary_key, plugins=plugins, hits_type=hits_type
1361
+ )
1331
1362
  return index_instance
1332
1363
 
1333
1364
  def create_key(self, key: KeyCreate) -> Key:
@@ -1478,12 +1509,16 @@ class Client(BaseClient):
1478
1509
 
1479
1510
  return Key(**response.json())
1480
1511
 
1481
- def multi_search(self, queries: list[SearchParams]) -> list[SearchResultsWithUID]:
1512
+ def multi_search(
1513
+ self, queries: list[SearchParams], *, hits_type: Any = JsonDict
1514
+ ) -> list[SearchResultsWithUID]:
1482
1515
  """Multi-index search.
1483
1516
 
1484
1517
  Args:
1485
1518
 
1486
1519
  queries: List of SearchParameters
1520
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
1521
+ JsonDict
1487
1522
 
1488
1523
  Returns:
1489
1524
 
@@ -1511,7 +1546,7 @@ class Client(BaseClient):
1511
1546
  body={"queries": [x.model_dump(by_alias=True) for x in queries]}, # type: ignore[attr-defined]
1512
1547
  )
1513
1548
 
1514
- return [SearchResultsWithUID(**x) for x in response.json()["results"]]
1549
+ return [SearchResultsWithUID[hits_type](**x) for x in response.json()["results"]]
1515
1550
 
1516
1551
  def get_raw_index(self, uid: str) -> IndexInfo | None:
1517
1552
  """Gets the index and returns all the index information rather than an Index instance.
@@ -1 +1 @@
1
- VERSION = "3.0.0"
1
+ VERSION = "3.1.0"
@@ -52,11 +52,12 @@ from meilisearch_python_sdk.plugins import (
52
52
  Plugin,
53
53
  PostSearchPlugin,
54
54
  )
55
+ from meilisearch_python_sdk.types import JsonDict
55
56
 
56
57
  if TYPE_CHECKING: # pragma: no cover
57
58
  import sys
58
59
 
59
- from meilisearch_python_sdk.types import Filter, JsonDict, JsonMapping
60
+ from meilisearch_python_sdk.types import Filter, JsonMapping
60
61
 
61
62
  if sys.version_info >= (3, 11):
62
63
  from typing import Self
@@ -72,11 +73,13 @@ class _BaseIndex:
72
73
  created_at: str | datetime | None = None,
73
74
  updated_at: str | datetime | None = None,
74
75
  json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
76
+ hits_type: Any = JsonDict,
75
77
  ):
76
78
  self.uid = uid
77
79
  self.primary_key = primary_key
78
80
  self.created_at: datetime | None = iso_to_date_time(created_at)
79
81
  self.updated_at: datetime | None = iso_to_date_time(updated_at)
82
+ self.hits_type = hits_type
80
83
  self._base_url = "indexes/"
81
84
  self._base_url_with_uid = f"{self._base_url}{self.uid}"
82
85
  self._documents_url = f"{self._base_url_with_uid}/documents"
@@ -113,6 +116,8 @@ class AsyncIndex(_BaseIndex):
113
116
  updated_at: str | datetime | None = None,
114
117
  plugins: AsyncIndexPlugins | None = None,
115
118
  json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
119
+ *,
120
+ hits_type: Any = JsonDict,
116
121
  ):
117
122
  """Class initializer.
118
123
 
@@ -129,8 +134,17 @@ class AsyncIndex(_BaseIndex):
129
134
  (uses the json module from the standard library), OrjsonHandler (uses orjson), or
130
135
  UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
131
136
  extra needs to be included. Default: BuiltinHandler.
137
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
138
+ JsonDict
132
139
  """
133
- super().__init__(uid, primary_key, created_at, updated_at, json_handler=json_handler)
140
+ super().__init__(
141
+ uid=uid,
142
+ primary_key=primary_key,
143
+ created_at=created_at,
144
+ updated_at=updated_at,
145
+ json_handler=json_handler,
146
+ hits_type=hits_type,
147
+ )
134
148
  self.http_client = http_client
135
149
  self._http_requests = AsyncHttpRequests(http_client, json_handler=self._json_handler)
136
150
  self.plugins = plugins
@@ -639,6 +653,7 @@ class AsyncIndex(_BaseIndex):
639
653
  timeout_in_ms: int | None = None,
640
654
  plugins: AsyncIndexPlugins | None = None,
641
655
  json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
656
+ hits_type: Any = JsonDict,
642
657
  ) -> Self:
643
658
  """Creates a new index.
644
659
 
@@ -667,6 +682,8 @@ class AsyncIndex(_BaseIndex):
667
682
  (uses the json module from the standard library), OrjsonHandler (uses orjson), or
668
683
  UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
669
684
  extra needs to be included. Default: BuiltinHandler.
685
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
686
+ JsonDict
670
687
 
671
688
  Returns:
672
689
 
@@ -708,6 +725,7 @@ class AsyncIndex(_BaseIndex):
708
725
  updated_at=index_dict["updatedAt"],
709
726
  plugins=plugins,
710
727
  json_handler=json_handler,
728
+ hits_type=hits_type,
711
729
  )
712
730
 
713
731
  if settings:
@@ -759,7 +777,7 @@ class AsyncIndex(_BaseIndex):
759
777
  highlight_pre_tag: str = "<em>",
760
778
  highlight_post_tag: str = "</em>",
761
779
  crop_marker: str = "...",
762
- matching_strategy: str = "all",
780
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
763
781
  hits_per_page: int | None = None,
764
782
  page: int | None = None,
765
783
  attributes_to_search_on: list[str] | None = None,
@@ -785,13 +803,14 @@ class AsyncIndex(_BaseIndex):
785
803
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
786
804
  Defaults to None.
787
805
  sort: Attributes by which to sort the results. Defaults to None.
788
- show_matches_position: Defines whether an object that contains information about the matches should be
789
- returned or not. Defaults to False.
806
+ show_matches_position: Defines whether an object that contains information about the
807
+ matches should be returned or not. Defaults to False.
790
808
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
791
809
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
792
810
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
793
811
  Defaults to ...
794
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
812
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
813
+ `last`.
795
814
  hits_per_page: Sets the number of results returned per page.
796
815
  page: Sets the specific results page to fetch.
797
816
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -933,7 +952,7 @@ class AsyncIndex(_BaseIndex):
933
952
  concurrent_tasks.append(self._http_requests.post(search_url, body=body))
934
953
 
935
954
  responses = await asyncio.gather(*concurrent_tasks)
936
- result = SearchResults(**responses[-1].json())
955
+ result = SearchResults[self.hits_type](**responses[-1].json()) # type: ignore[name-defined]
937
956
  if self._post_search_plugins:
938
957
  post = await AsyncIndex._run_plugins(
939
958
  self._post_search_plugins, AsyncEvent.POST, search_results=result
@@ -976,7 +995,7 @@ class AsyncIndex(_BaseIndex):
976
995
  response_coroutine = tg.create_task(self._http_requests.post(search_url, body=body))
977
996
 
978
997
  response = await response_coroutine
979
- result = SearchResults(**response.json())
998
+ result = SearchResults[self.hits_type](**response.json()) # type: ignore[name-defined]
980
999
  if self._post_search_plugins:
981
1000
  post = await AsyncIndex._run_plugins(
982
1001
  self._post_search_plugins, AsyncEvent.POST, search_results=result
@@ -987,7 +1006,7 @@ class AsyncIndex(_BaseIndex):
987
1006
  return result
988
1007
 
989
1008
  response = await self._http_requests.post(search_url, body=body)
990
- result = SearchResults(**response.json())
1009
+ result = SearchResults[self.hits_type](**response.json()) # type: ignore[name-defined]
991
1010
 
992
1011
  if self._post_search_plugins:
993
1012
  post = await AsyncIndex._run_plugins(
@@ -1017,7 +1036,7 @@ class AsyncIndex(_BaseIndex):
1017
1036
  highlight_pre_tag: str = "<em>",
1018
1037
  highlight_post_tag: str = "</em>",
1019
1038
  crop_marker: str = "...",
1020
- matching_strategy: Literal["all", "last", "frequency"] = "all",
1039
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
1021
1040
  hits_per_page: int | None = None,
1022
1041
  page: int | None = None,
1023
1042
  attributes_to_search_on: list[str] | None = None,
@@ -1044,13 +1063,14 @@ class AsyncIndex(_BaseIndex):
1044
1063
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
1045
1064
  Defaults to None.
1046
1065
  sort: Attributes by which to sort the results. Defaults to None.
1047
- show_matches_position: Defines whether an object that contains information about the matches should be
1048
- returned or not. Defaults to False.
1066
+ show_matches_position: Defines whether an object that contains information about the
1067
+ matches should be returned or not. Defaults to False.
1049
1068
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
1050
1069
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
1051
1070
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
1052
1071
  Defaults to ...
1053
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
1072
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
1073
+ `last`.
1054
1074
  hits_per_page: Sets the number of results returned per page.
1055
1075
  page: Sets the specific results page to fetch.
1056
1076
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -1322,7 +1342,7 @@ class AsyncIndex(_BaseIndex):
1322
1342
  f"{self._base_url_with_uid}/similar", body=payload
1323
1343
  )
1324
1344
 
1325
- return SimilarSearchResults(**response.json())
1345
+ return SimilarSearchResults[self.hits_type](**response.json()) # type: ignore[name-defined]
1326
1346
 
1327
1347
  async def get_document(self, document_id: str) -> JsonDict:
1328
1348
  """Get one document with given document identifier.
@@ -4514,6 +4534,8 @@ class Index(_BaseIndex):
4514
4534
  updated_at: str | datetime | None = None,
4515
4535
  plugins: IndexPlugins | None = None,
4516
4536
  json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
4537
+ *,
4538
+ hits_type: Any = JsonDict,
4517
4539
  ):
4518
4540
  """Class initializer.
4519
4541
 
@@ -4530,8 +4552,17 @@ class Index(_BaseIndex):
4530
4552
  (uses the json module from the standard library), OrjsonHandler (uses orjson), or
4531
4553
  UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
4532
4554
  extra needs to be included. Default: BuiltinHandler.
4555
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
4556
+ JsonDict
4533
4557
  """
4534
- super().__init__(uid, primary_key, created_at, updated_at, json_handler=json_handler)
4558
+ super().__init__(
4559
+ uid=uid,
4560
+ primary_key=primary_key,
4561
+ created_at=created_at,
4562
+ updated_at=updated_at,
4563
+ json_handler=json_handler,
4564
+ hits_type=hits_type,
4565
+ )
4535
4566
  self.http_client = http_client
4536
4567
  self._http_requests = HttpRequests(http_client, json_handler=self._json_handler)
4537
4568
  self.plugins = plugins
@@ -4914,6 +4945,7 @@ class Index(_BaseIndex):
4914
4945
  timeout_in_ms: int | None = None,
4915
4946
  plugins: IndexPlugins | None = None,
4916
4947
  json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
4948
+ hits_type: Any = JsonDict,
4917
4949
  ) -> Self:
4918
4950
  """Creates a new index.
4919
4951
 
@@ -4942,6 +4974,8 @@ class Index(_BaseIndex):
4942
4974
  (uses the json module from the standard library), OrjsonHandler (uses orjson), or
4943
4975
  UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
4944
4976
  extra needs to be included. Default: BuiltinHandler.
4977
+ hits_type: Allows for a custom type to be passed to use for hits. Defaults to
4978
+ JsonDict
4945
4979
 
4946
4980
  Returns:
4947
4981
 
@@ -4978,6 +5012,7 @@ class Index(_BaseIndex):
4978
5012
  updated_at=index_dict["updatedAt"],
4979
5013
  plugins=plugins,
4980
5014
  json_handler=json_handler,
5015
+ hits_type=hits_type,
4981
5016
  )
4982
5017
 
4983
5018
  if settings:
@@ -5027,7 +5062,7 @@ class Index(_BaseIndex):
5027
5062
  highlight_pre_tag: str = "<em>",
5028
5063
  highlight_post_tag: str = "</em>",
5029
5064
  crop_marker: str = "...",
5030
- matching_strategy: Literal["all", "last", "frequency"] = "all",
5065
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
5031
5066
  hits_per_page: int | None = None,
5032
5067
  page: int | None = None,
5033
5068
  attributes_to_search_on: list[str] | None = None,
@@ -5053,13 +5088,14 @@ class Index(_BaseIndex):
5053
5088
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
5054
5089
  Defaults to None.
5055
5090
  sort: Attributes by which to sort the results. Defaults to None.
5056
- show_matches_position: Defines whether an object that contains information about the matches should be
5057
- returned or not. Defaults to False.
5091
+ show_matches_position: Defines whether an object that contains information about the
5092
+ matches should be returned or not. Defaults to False.
5058
5093
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
5059
5094
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
5060
5095
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
5061
5096
  Defaults to ...
5062
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
5097
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
5098
+ `last`.
5063
5099
  hits_per_page: Sets the number of results returned per page.
5064
5100
  page: Sets the specific results page to fetch.
5065
5101
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -5166,7 +5202,7 @@ class Index(_BaseIndex):
5166
5202
  )
5167
5203
 
5168
5204
  response = self._http_requests.post(f"{self._base_url_with_uid}/search", body=body)
5169
- result = SearchResults(**response.json())
5205
+ result = SearchResults[self.hits_type](**response.json()) # type: ignore[name-defined]
5170
5206
  if self._post_search_plugins:
5171
5207
  post = Index._run_plugins(self._post_search_plugins, Event.POST, search_results=result)
5172
5208
  if post.get("search_result"):
@@ -5193,7 +5229,7 @@ class Index(_BaseIndex):
5193
5229
  highlight_pre_tag: str = "<em>",
5194
5230
  highlight_post_tag: str = "</em>",
5195
5231
  crop_marker: str = "...",
5196
- matching_strategy: str = "all",
5232
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
5197
5233
  hits_per_page: int | None = None,
5198
5234
  page: int | None = None,
5199
5235
  attributes_to_search_on: list[str] | None = None,
@@ -5220,13 +5256,14 @@ class Index(_BaseIndex):
5220
5256
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
5221
5257
  Defaults to None.
5222
5258
  sort: Attributes by which to sort the results. Defaults to None.
5223
- show_matches_position: Defines whether an object that contains information about the matches should be
5224
- returned or not. Defaults to False.
5259
+ show_matches_position: Defines whether an object that contains information about the
5260
+ matches should be returned or not. Defaults to False.
5225
5261
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
5226
5262
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
5227
5263
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
5228
5264
  Defaults to ...
5229
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
5265
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
5266
+ `last`.
5230
5267
  hits_per_page: Sets the number of results returned per page.
5231
5268
  page: Sets the specific results page to fetch.
5232
5269
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -5404,7 +5441,7 @@ class Index(_BaseIndex):
5404
5441
 
5405
5442
  response = self._http_requests.post(f"{self._base_url_with_uid}/similar", body=payload)
5406
5443
 
5407
- return SimilarSearchResults(**response.json())
5444
+ return SimilarSearchResults[self.hits_type](**response.json()) # type: ignore[name-defined]
5408
5445
 
5409
5446
  def get_document(self, document_id: str) -> JsonDict:
5410
5447
  """Get one document with given document identifier.
@@ -8196,7 +8233,7 @@ def _process_search_parameters(
8196
8233
  highlight_pre_tag: str = "<em>",
8197
8234
  highlight_post_tag: str = "</em>",
8198
8235
  crop_marker: str = "...",
8199
- matching_strategy: str = "all",
8236
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
8200
8237
  hits_per_page: int | None = None,
8201
8238
  page: int | None = None,
8202
8239
  attributes_to_search_on: list[str] | None = None,
@@ -1,11 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- import pydantic
3
+ from typing import Generic, Literal, TypeVar
4
+
4
5
  from camel_converter.pydantic_base import CamelBase
6
+ from pydantic import Field, field_validator
5
7
 
6
8
  from meilisearch_python_sdk.errors import MeilisearchError
7
9
  from meilisearch_python_sdk.types import Filter, JsonDict
8
10
 
11
+ T = TypeVar("T")
12
+
9
13
 
10
14
  class FacetHits(CamelBase):
11
15
  value: str
@@ -25,7 +29,7 @@ class Hybrid(CamelBase):
25
29
 
26
30
  class SearchParams(CamelBase):
27
31
  index_uid: str
28
- query: str | None = pydantic.Field(None, alias="q")
32
+ query: str | None = Field(None, alias="q")
29
33
  offset: int = 0
30
34
  limit: int = 20
31
35
  filter: Filter | None = None
@@ -39,7 +43,7 @@ class SearchParams(CamelBase):
39
43
  highlight_pre_tag: str = "<em>"
40
44
  highlight_post_tag: str = "</em>"
41
45
  crop_marker: str = "..."
42
- matching_strategy: str = "all"
46
+ matching_strategy: Literal["all", "last", "frequency"] = "last"
43
47
  hits_per_page: int | None = None
44
48
  page: int | None = None
45
49
  attributes_to_search_on: list[str] | None = None
@@ -49,7 +53,7 @@ class SearchParams(CamelBase):
49
53
  vector: list[float] | None = None
50
54
  hybrid: Hybrid | None = None
51
55
 
52
- @pydantic.field_validator("ranking_score_threshold", mode="before") # type: ignore[attr-defined]
56
+ @field_validator("ranking_score_threshold", mode="before") # type: ignore[attr-defined]
53
57
  @classmethod
54
58
  def validate_ranking_score_threshold(cls, v: float | None) -> float | None:
55
59
  if v and not 0.0 <= v <= 1.0:
@@ -58,8 +62,8 @@ class SearchParams(CamelBase):
58
62
  return v
59
63
 
60
64
 
61
- class SearchResults(CamelBase):
62
- hits: list[JsonDict]
65
+ class SearchResults(CamelBase, Generic[T]):
66
+ hits: list[T]
63
67
  offset: int | None = None
64
68
  limit: int | None = None
65
69
  estimated_total_hits: int | None = None
@@ -73,12 +77,12 @@ class SearchResults(CamelBase):
73
77
  semantic_hit_count: int | None = None
74
78
 
75
79
 
76
- class SearchResultsWithUID(SearchResults):
80
+ class SearchResultsWithUID(SearchResults, Generic[T]):
77
81
  index_uid: str
78
82
 
79
83
 
80
- class SimilarSearchResults(CamelBase):
81
- hits: list[JsonDict]
84
+ class SimilarSearchResults(CamelBase, Generic[T]):
85
+ hits: list[T]
82
86
  id: str
83
87
  processing_time_ms: int
84
88
  limit: int | None = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: meilisearch-python-sdk
3
- Version: 3.0.0
3
+ Version: 3.1.0
4
4
  Summary: A Python client providing both async and sync support for the Meilisearch API
5
5
  Home-page: https://github.com/sanders41/meilisearch-python-sdk
6
6
  License: MIT
@@ -1,26 +1,26 @@
1
1
  meilisearch_python_sdk/__init__.py,sha256=SB0Jlm6FwT13J9xasZKseZzTWBk0hkfe1CWyWmIIZnE,258
2
- meilisearch_python_sdk/_client.py,sha256=pNX_lz6zAtN1OXihvYOdyGxxJtYGO2GPzpftmZ86ikQ,66951
2
+ meilisearch_python_sdk/_client.py,sha256=I4HVtgzuwlQ-BmyUlVXQTZ3dJR7YIhyfs0qQTXEYBfM,68170
3
3
  meilisearch_python_sdk/_http_requests.py,sha256=TwpqsOvfgaJ1lQXwam1q1_UC6NvRWy4m9W3c5KNe0RI,6741
4
4
  meilisearch_python_sdk/_task.py,sha256=dB0cpX1u7HDM1OW_TC8gSiGJe985bNCz7hPMZW_qogY,12352
5
5
  meilisearch_python_sdk/_utils.py,sha256=k6SYMJSiVjfF-vlhQRMaE1ziJsVf5FrL94mFwrMfdLY,957
6
- meilisearch_python_sdk/_version.py,sha256=qckxTKowVHHdLYuDeVRWcIaYVKeKZEw0YwwUIm6QtNY,18
6
+ meilisearch_python_sdk/_version.py,sha256=3vf_fJuJ1GKgsLolRXa0KsZlsevgoI4iyhPFl5-KJnM,18
7
7
  meilisearch_python_sdk/decorators.py,sha256=KpS5gAgks28BtPMZJumRaXfgXK4A3QNVPR8Z4BpZC0g,8346
8
8
  meilisearch_python_sdk/errors.py,sha256=0sAKYt47-zFpKsEU6W8Qnvf4uHBynKtlGPpPl-5laSA,2085
9
- meilisearch_python_sdk/index.py,sha256=Hs9jvPOzCw2iLil_KuKCS7Co_j4gQiM4Kdi3H5iAEh4,312943
9
+ meilisearch_python_sdk/index.py,sha256=uW9m5gnLwHdQKiDf4DV0k4ksr252HzmkJQT3KCicg8g,314470
10
10
  meilisearch_python_sdk/json_handler.py,sha256=q_87zSnJfDNuVEI9cEvuOQOGBC7AGWJMEqCh2kGAAqA,2107
11
11
  meilisearch_python_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  meilisearch_python_sdk/models/client.py,sha256=wBZzO1n6DDQq7F9Acf1rCWYEYRY19g04uFiEf9JCMjc,2423
13
13
  meilisearch_python_sdk/models/documents.py,sha256=eT3FHrPND-g2IzNRyOHQApTTJ1WbFcGlqgxZ6aKrRgI,247
14
14
  meilisearch_python_sdk/models/health.py,sha256=hvruti7ylsk7bAh8RPOhTPcRrjx6MPgdkDFX9vZ5Qks,95
15
15
  meilisearch_python_sdk/models/index.py,sha256=GGwuhx5Wsn5iyj1ov3f4eWjfw6ttM8WzvyrnSsC4vRg,1132
16
- meilisearch_python_sdk/models/search.py,sha256=fCLjf_Ha8HskfMFD6UReNtfBW6Ng7v_ui6-BlHOh--M,2457
16
+ meilisearch_python_sdk/models/search.py,sha256=roaP0ElXMfa-NQF_bS3wuAEHHxTRJpT-qSnTsls5qjw,2586
17
17
  meilisearch_python_sdk/models/settings.py,sha256=FugCLAMESWQknHoViD84XfghlEWXcYIlnufb05Qq6IQ,3852
18
18
  meilisearch_python_sdk/models/task.py,sha256=P3NLaZhrY8H02Q9lDEkoq-3Z6_qGESglOxs4dNRyMWg,2100
19
19
  meilisearch_python_sdk/models/version.py,sha256=YDu-aj5H-d6nSaWRTXzlwWghmZAoiknaw250UyEd48I,215
20
20
  meilisearch_python_sdk/plugins.py,sha256=YySzTuVr4IrogTgrP8q-gZPsew8TwedopjWnTj5eV48,3607
21
21
  meilisearch_python_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  meilisearch_python_sdk/types.py,sha256=VBzt-JF6w1f5V_aTAM3NetDQxs9fscnRy8t-Y1HWZXM,404
23
- meilisearch_python_sdk-3.0.0.dist-info/LICENSE,sha256=xVzevI1TrlKfM0plmJ7vfK1Muu0V9n-dGE8RnDrOFlM,1069
24
- meilisearch_python_sdk-3.0.0.dist-info/METADATA,sha256=S5u7FPiYRVcXfTWCEasqSqI_E8EOqg2qNuWGPmtnGMA,8491
25
- meilisearch_python_sdk-3.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
26
- meilisearch_python_sdk-3.0.0.dist-info/RECORD,,
23
+ meilisearch_python_sdk-3.1.0.dist-info/LICENSE,sha256=xVzevI1TrlKfM0plmJ7vfK1Muu0V9n-dGE8RnDrOFlM,1069
24
+ meilisearch_python_sdk-3.1.0.dist-info/METADATA,sha256=Nf5ywGBA550PlIm1bvQy3_WE0BjXa6n0QDDlkSgWt6Y,8491
25
+ meilisearch_python_sdk-3.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
26
+ meilisearch_python_sdk-3.1.0.dist-info/RECORD,,