meilisearch-python-sdk 2.12.1__py3-none-any.whl → 3.0.1__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.

@@ -1,14 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import json
4
+ from collections.abc import Generator, MutableMapping, Sequence
5
5
  from csv import DictReader
6
6
  from datetime import datetime
7
7
  from functools import cached_property, partial
8
8
  from pathlib import Path
9
- from typing import TYPE_CHECKING, Any, Generator, Literal, MutableMapping, Sequence
9
+ from typing import TYPE_CHECKING, Any, Literal
10
10
  from urllib.parse import urlencode
11
- from warnings import warn
12
11
 
13
12
  import aiofiles
14
13
  from camel_converter import to_snake
@@ -16,8 +15,9 @@ from httpx import AsyncClient, Client
16
15
 
17
16
  from meilisearch_python_sdk._http_requests import AsyncHttpRequests, HttpRequests
18
17
  from meilisearch_python_sdk._task import async_wait_for_task, wait_for_task
19
- from meilisearch_python_sdk._utils import is_pydantic_2, iso_to_date_time, use_task_groups
18
+ from meilisearch_python_sdk._utils import iso_to_date_time, use_task_groups
20
19
  from meilisearch_python_sdk.errors import InvalidDocumentError, MeilisearchError
20
+ from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
21
21
  from meilisearch_python_sdk.models.documents import DocumentsInfo
22
22
  from meilisearch_python_sdk.models.index import IndexStats
23
23
  from meilisearch_python_sdk.models.search import (
@@ -71,6 +71,7 @@ class _BaseIndex:
71
71
  primary_key: str | None = None,
72
72
  created_at: str | datetime | None = None,
73
73
  updated_at: str | datetime | None = None,
74
+ json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
74
75
  ):
75
76
  self.uid = uid
76
77
  self.primary_key = primary_key
@@ -81,6 +82,7 @@ class _BaseIndex:
81
82
  self._documents_url = f"{self._base_url_with_uid}/documents"
82
83
  self._stats_url = f"{self._base_url_with_uid}/stats"
83
84
  self._settings_url = f"{self._base_url_with_uid}/settings"
85
+ self._json_handler = json_handler if json_handler else BuiltinHandler()
84
86
 
85
87
  def __str__(self) -> str:
86
88
  return f"{type(self).__name__}(uid={self.uid}, primary_key={self.primary_key}, created_at={self.created_at}, updated_at={self.updated_at})"
@@ -110,6 +112,7 @@ class AsyncIndex(_BaseIndex):
110
112
  created_at: str | datetime | None = None,
111
113
  updated_at: str | datetime | None = None,
112
114
  plugins: AsyncIndexPlugins | None = None,
115
+ json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
113
116
  ):
114
117
  """Class initializer.
115
118
 
@@ -122,10 +125,14 @@ class AsyncIndex(_BaseIndex):
122
125
  created_at: The date and time the index was created. Defaults to None.
123
126
  updated_at: The date and time the index was last updated. Defaults to None.
124
127
  plugins: Optional plugins can be provided to extend functionality.
128
+ json_handler: The module to use for json operations. The options are BuiltinHandler
129
+ (uses the json module from the standard library), OrjsonHandler (uses orjson), or
130
+ UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
131
+ extra needs to be included. Default: BuiltinHandler.
125
132
  """
126
- super().__init__(uid, primary_key, created_at, updated_at)
133
+ super().__init__(uid, primary_key, created_at, updated_at, json_handler=json_handler)
127
134
  self.http_client = http_client
128
- self._http_requests = AsyncHttpRequests(http_client)
135
+ self._http_requests = AsyncHttpRequests(http_client, json_handler=self._json_handler)
129
136
  self.plugins = plugins
130
137
 
131
138
  @cached_property
@@ -631,6 +638,7 @@ class AsyncIndex(_BaseIndex):
631
638
  wait: bool = True,
632
639
  timeout_in_ms: int | None = None,
633
640
  plugins: AsyncIndexPlugins | None = None,
641
+ json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
634
642
  ) -> Self:
635
643
  """Creates a new index.
636
644
 
@@ -655,6 +663,10 @@ class AsyncIndex(_BaseIndex):
655
663
  MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
656
664
  if the `None` option is used the wait time could be very long. Defaults to None.
657
665
  plugins: Optional plugins can be provided to extend functionality.
666
+ json_handler: The module to use for json operations. The options are BuiltinHandler
667
+ (uses the json module from the standard library), OrjsonHandler (uses orjson), or
668
+ UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
669
+ extra needs to be included. Default: BuiltinHandler.
658
670
 
659
671
  Returns:
660
672
 
@@ -677,10 +689,13 @@ class AsyncIndex(_BaseIndex):
677
689
  payload = {"primaryKey": primary_key, "uid": uid}
678
690
 
679
691
  url = "indexes"
680
- http_request = AsyncHttpRequests(http_client)
692
+ handler = json_handler if json_handler else BuiltinHandler()
693
+ http_request = AsyncHttpRequests(http_client, json_handler=handler)
681
694
  response = await http_request.post(url, payload)
682
695
  await async_wait_for_task(
683
- http_client, response.json()["taskUid"], timeout_in_ms=timeout_in_ms
696
+ http_client,
697
+ response.json()["taskUid"],
698
+ timeout_in_ms=timeout_in_ms,
684
699
  )
685
700
 
686
701
  index_response = await http_request.get(f"{url}/{uid}")
@@ -692,6 +707,7 @@ class AsyncIndex(_BaseIndex):
692
707
  created_at=index_dict["createdAt"],
693
708
  updated_at=index_dict["updatedAt"],
694
709
  plugins=plugins,
710
+ json_handler=json_handler,
695
711
  )
696
712
 
697
713
  if settings:
@@ -743,7 +759,7 @@ class AsyncIndex(_BaseIndex):
743
759
  highlight_pre_tag: str = "<em>",
744
760
  highlight_post_tag: str = "</em>",
745
761
  crop_marker: str = "...",
746
- matching_strategy: str = "all",
762
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
747
763
  hits_per_page: int | None = None,
748
764
  page: int | None = None,
749
765
  attributes_to_search_on: list[str] | None = None,
@@ -769,13 +785,14 @@ class AsyncIndex(_BaseIndex):
769
785
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
770
786
  Defaults to None.
771
787
  sort: Attributes by which to sort the results. Defaults to None.
772
- show_matches_position: Defines whether an object that contains information about the matches should be
773
- returned or not. Defaults to False.
788
+ show_matches_position: Defines whether an object that contains information about the
789
+ matches should be returned or not. Defaults to False.
774
790
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
775
791
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
776
792
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
777
793
  Defaults to ...
778
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
794
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
795
+ `last`.
779
796
  hits_per_page: Sets the number of results returned per page.
780
797
  page: Sets the specific results page to fetch.
781
798
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -1001,7 +1018,7 @@ class AsyncIndex(_BaseIndex):
1001
1018
  highlight_pre_tag: str = "<em>",
1002
1019
  highlight_post_tag: str = "</em>",
1003
1020
  crop_marker: str = "...",
1004
- matching_strategy: Literal["all", "last", "frequency"] = "all",
1021
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
1005
1022
  hits_per_page: int | None = None,
1006
1023
  page: int | None = None,
1007
1024
  attributes_to_search_on: list[str] | None = None,
@@ -1028,13 +1045,14 @@ class AsyncIndex(_BaseIndex):
1028
1045
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
1029
1046
  Defaults to None.
1030
1047
  sort: Attributes by which to sort the results. Defaults to None.
1031
- show_matches_position: Defines whether an object that contains information about the matches should be
1032
- returned or not. Defaults to False.
1048
+ show_matches_position: Defines whether an object that contains information about the
1049
+ matches should be returned or not. Defaults to False.
1033
1050
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
1034
1051
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
1035
1052
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
1036
1053
  Defaults to ...
1037
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
1054
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
1055
+ `last`.
1038
1056
  hits_per_page: Sets the number of results returned per page.
1039
1057
  page: Sets the specific results page to fetch.
1040
1058
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -1400,7 +1418,6 @@ class AsyncIndex(_BaseIndex):
1400
1418
  primary_key: str | None = None,
1401
1419
  *,
1402
1420
  compress: bool = False,
1403
- serializer: type[json.JSONEncoder] | None = None,
1404
1421
  ) -> TaskInfo:
1405
1422
  """Add documents to the index.
1406
1423
 
@@ -1410,8 +1427,6 @@ class AsyncIndex(_BaseIndex):
1410
1427
  primary_key: The primary key of the documents. This will be ignored if already set.
1411
1428
  Defaults to None.
1412
1429
  compress: If set to True the data will be sent in gzip format. Defaults to False.
1413
- serializer: A custom JSONEncode to handle serializing fields that the build in
1414
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
1415
1430
 
1416
1431
  Returns:
1417
1432
 
@@ -1469,11 +1484,7 @@ class AsyncIndex(_BaseIndex):
1469
1484
  )
1470
1485
  )
1471
1486
 
1472
- tasks.append(
1473
- self._http_requests.post(
1474
- url, documents, compress=compress, serializer=serializer
1475
- )
1476
- )
1487
+ tasks.append(self._http_requests.post(url, documents, compress=compress))
1477
1488
 
1478
1489
  responses = await asyncio.gather(*tasks)
1479
1490
  result = TaskInfo(**responses[-1].json())
@@ -1509,9 +1520,7 @@ class AsyncIndex(_BaseIndex):
1509
1520
  )
1510
1521
 
1511
1522
  response_coroutine = tg.create_task(
1512
- self._http_requests.post(
1513
- url, documents, compress=compress, serializer=serializer
1514
- )
1523
+ self._http_requests.post(url, documents, compress=compress)
1515
1524
  )
1516
1525
 
1517
1526
  response = await response_coroutine
@@ -1529,9 +1538,7 @@ class AsyncIndex(_BaseIndex):
1529
1538
 
1530
1539
  return result
1531
1540
 
1532
- response = await self._http_requests.post(
1533
- url, documents, compress=compress, serializer=serializer
1534
- )
1541
+ response = await self._http_requests.post(url, documents, compress=compress)
1535
1542
 
1536
1543
  result = TaskInfo(**response.json())
1537
1544
  if self._post_add_documents_plugins:
@@ -1554,7 +1561,6 @@ class AsyncIndex(_BaseIndex):
1554
1561
  batch_size: int = 1000,
1555
1562
  primary_key: str | None = None,
1556
1563
  compress: bool = False,
1557
- serializer: type[json.JSONEncoder] | None = None,
1558
1564
  ) -> list[TaskInfo]:
1559
1565
  """Adds documents in batches to reduce RAM usage with indexing.
1560
1566
 
@@ -1566,8 +1572,6 @@ class AsyncIndex(_BaseIndex):
1566
1572
  primary_key: The primary key of the documents. This will be ignored if already set.
1567
1573
  Defaults to None.
1568
1574
  compress: If set to True the data will be sent in gzip format. Defaults to False.
1569
- serializer: A custom JSONEncode to handle serializing fields that the build in
1570
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
1571
1575
 
1572
1576
  Returns:
1573
1577
 
@@ -1591,16 +1595,14 @@ class AsyncIndex(_BaseIndex):
1591
1595
  """
1592
1596
  if not use_task_groups():
1593
1597
  batches = [
1594
- self.add_documents(x, primary_key, compress=compress, serializer=serializer)
1598
+ self.add_documents(x, primary_key, compress=compress)
1595
1599
  for x in _batch(documents, batch_size)
1596
1600
  ]
1597
1601
  return await asyncio.gather(*batches)
1598
1602
 
1599
1603
  async with asyncio.TaskGroup() as tg: # type: ignore[attr-defined]
1600
1604
  tasks = [
1601
- tg.create_task(
1602
- self.add_documents(x, primary_key, compress=compress, serializer=serializer)
1603
- )
1605
+ tg.create_task(self.add_documents(x, primary_key, compress=compress))
1604
1606
  for x in _batch(documents, batch_size)
1605
1607
  ]
1606
1608
 
@@ -1615,7 +1617,6 @@ class AsyncIndex(_BaseIndex):
1615
1617
  csv_delimiter: str | None = None,
1616
1618
  combine_documents: bool = True,
1617
1619
  compress: bool = False,
1618
- serializer: type[json.JSONEncoder] | None = None,
1619
1620
  ) -> list[TaskInfo]:
1620
1621
  """Load all json files from a directory and add the documents to the index.
1621
1622
 
@@ -1632,8 +1633,6 @@ class AsyncIndex(_BaseIndex):
1632
1633
  combine_documents: If set to True this will combine the documents from all the files
1633
1634
  before indexing them. Defaults to True.
1634
1635
  compress: If set to True the data will be sent in gzip format. Defaults to False.
1635
- serializer: A custom JSONEncode to handle serializing fields that the build in
1636
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
1637
1636
 
1638
1637
  Returns:
1639
1638
 
@@ -1661,7 +1660,9 @@ class AsyncIndex(_BaseIndex):
1661
1660
  all_documents = []
1662
1661
  for path in directory.iterdir():
1663
1662
  if path.suffix == f".{document_type}":
1664
- documents = await _async_load_documents_from_file(path, csv_delimiter)
1663
+ documents = await _async_load_documents_from_file(
1664
+ path, csv_delimiter, json_handler=self._json_handler
1665
+ )
1665
1666
  all_documents.append(documents)
1666
1667
 
1667
1668
  _raise_on_no_documents(all_documents, document_type, directory_path)
@@ -1669,9 +1670,7 @@ class AsyncIndex(_BaseIndex):
1669
1670
  loop = asyncio.get_running_loop()
1670
1671
  combined = await loop.run_in_executor(None, partial(_combine_documents, all_documents))
1671
1672
 
1672
- response = await self.add_documents(
1673
- combined, primary_key, compress=compress, serializer=serializer
1674
- )
1673
+ response = await self.add_documents(combined, primary_key, compress=compress)
1675
1674
 
1676
1675
  return [response]
1677
1676
 
@@ -1679,11 +1678,11 @@ class AsyncIndex(_BaseIndex):
1679
1678
  add_documents = []
1680
1679
  for path in directory.iterdir():
1681
1680
  if path.suffix == f".{document_type}":
1682
- documents = await _async_load_documents_from_file(path, csv_delimiter)
1681
+ documents = await _async_load_documents_from_file(
1682
+ path, csv_delimiter, json_handler=self._json_handler
1683
+ )
1683
1684
  add_documents.append(
1684
- self.add_documents(
1685
- documents, primary_key, compress=compress, serializer=serializer
1686
- )
1685
+ self.add_documents(documents, primary_key, compress=compress)
1687
1686
  )
1688
1687
 
1689
1688
  _raise_on_no_documents(add_documents, document_type, directory_path)
@@ -1705,19 +1704,15 @@ class AsyncIndex(_BaseIndex):
1705
1704
  all_results = []
1706
1705
  for i, path in enumerate(directory.iterdir()):
1707
1706
  if path.suffix == f".{document_type}":
1708
- documents = await _async_load_documents_from_file(path, csv_delimiter)
1707
+ documents = await _async_load_documents_from_file(
1708
+ path, csv_delimiter, json_handler=self._json_handler
1709
+ )
1709
1710
  if i == 0:
1710
- all_results = [
1711
- await self.add_documents(
1712
- documents, compress=compress, serializer=serializer
1713
- )
1714
- ]
1711
+ all_results = [await self.add_documents(documents, compress=compress)]
1715
1712
  else:
1716
1713
  tasks.append(
1717
1714
  tg.create_task(
1718
- self.add_documents(
1719
- documents, primary_key, compress=compress, serializer=serializer
1720
- )
1715
+ self.add_documents(documents, primary_key, compress=compress)
1721
1716
  )
1722
1717
  )
1723
1718
 
@@ -1736,7 +1731,6 @@ class AsyncIndex(_BaseIndex):
1736
1731
  csv_delimiter: str | None = None,
1737
1732
  combine_documents: bool = True,
1738
1733
  compress: bool = False,
1739
- serializer: type[json.JSONEncoder] | None = None,
1740
1734
  ) -> list[TaskInfo]:
1741
1735
  """Load all json files from a directory and add the documents to the index in batches.
1742
1736
 
@@ -1755,8 +1749,6 @@ class AsyncIndex(_BaseIndex):
1755
1749
  combine_documents: If set to True this will combine the documents from all the files
1756
1750
  before indexing them. Defaults to True.
1757
1751
  compress: If set to True the data will be sent in gzip format. Defaults to False.
1758
- serializer: A custom JSONEncode to handle serializing fields that the build in
1759
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
1760
1752
 
1761
1753
  Returns:
1762
1754
 
@@ -1785,7 +1777,7 @@ class AsyncIndex(_BaseIndex):
1785
1777
  for path in directory.iterdir():
1786
1778
  if path.suffix == f".{document_type}":
1787
1779
  documents = await _async_load_documents_from_file(
1788
- path, csv_delimiter=csv_delimiter
1780
+ path, csv_delimiter=csv_delimiter, json_handler=self._json_handler
1789
1781
  )
1790
1782
  all_documents.append(documents)
1791
1783
 
@@ -1799,7 +1791,6 @@ class AsyncIndex(_BaseIndex):
1799
1791
  batch_size=batch_size,
1800
1792
  primary_key=primary_key,
1801
1793
  compress=compress,
1802
- serializer=serializer,
1803
1794
  )
1804
1795
 
1805
1796
  responses: list[TaskInfo] = []
@@ -1807,14 +1798,15 @@ class AsyncIndex(_BaseIndex):
1807
1798
  add_documents = []
1808
1799
  for path in directory.iterdir():
1809
1800
  if path.suffix == f".{document_type}":
1810
- documents = await _async_load_documents_from_file(path, csv_delimiter)
1801
+ documents = await _async_load_documents_from_file(
1802
+ path, csv_delimiter, json_handler=self._json_handler
1803
+ )
1811
1804
  add_documents.append(
1812
1805
  self.add_documents_in_batches(
1813
1806
  documents,
1814
1807
  batch_size=batch_size,
1815
1808
  primary_key=primary_key,
1816
1809
  compress=compress,
1817
- serializer=serializer,
1818
1810
  )
1819
1811
  )
1820
1812
 
@@ -1837,7 +1829,6 @@ class AsyncIndex(_BaseIndex):
1837
1829
  primary_key: str | None = None,
1838
1830
  *,
1839
1831
  compress: bool = False,
1840
- serializer: type[json.JSONEncoder] | None = None,
1841
1832
  ) -> TaskInfo:
1842
1833
  """Add documents to the index from a json file.
1843
1834
 
@@ -1847,8 +1838,6 @@ class AsyncIndex(_BaseIndex):
1847
1838
  primary_key: The primary key of the documents. This will be ignored if already set.
1848
1839
  Defaults to None.
1849
1840
  compress: If set to True the data will be sent in gzip format. Defaults to False.
1850
- serializer: A custom JSONEncode to handle serializing fields that the build in
1851
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
1852
1841
 
1853
1842
  Returns:
1854
1843
 
@@ -1870,12 +1859,12 @@ class AsyncIndex(_BaseIndex):
1870
1859
  >>> index = client.index("movies")
1871
1860
  >>> await index.add_documents_from_file(file_path)
1872
1861
  """
1873
- documents = await _async_load_documents_from_file(file_path)
1874
-
1875
- return await self.add_documents(
1876
- documents, primary_key=primary_key, compress=compress, serializer=serializer
1862
+ documents = await _async_load_documents_from_file(
1863
+ file_path, json_handler=self._json_handler
1877
1864
  )
1878
1865
 
1866
+ return await self.add_documents(documents, primary_key=primary_key, compress=compress)
1867
+
1879
1868
  async def add_documents_from_file_in_batches(
1880
1869
  self,
1881
1870
  file_path: Path | str,
@@ -1884,7 +1873,6 @@ class AsyncIndex(_BaseIndex):
1884
1873
  primary_key: str | None = None,
1885
1874
  csv_delimiter: str | None = None,
1886
1875
  compress: bool = False,
1887
- serializer: type[json.JSONEncoder] | None = None,
1888
1876
  ) -> list[TaskInfo]:
1889
1877
  """Adds documents form a json file in batches to reduce RAM usage with indexing.
1890
1878
 
@@ -1898,8 +1886,6 @@ class AsyncIndex(_BaseIndex):
1898
1886
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
1899
1887
  can only be used if the file is a csv file. Defaults to comma.
1900
1888
  compress: If set to True the data will be sent in gzip format. Defaults to False.
1901
- serializer: A custom JSONEncode to handle serializing fields that the build in
1902
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
1903
1889
 
1904
1890
  Returns:
1905
1891
 
@@ -1921,14 +1907,15 @@ class AsyncIndex(_BaseIndex):
1921
1907
  >>> index = client.index("movies")
1922
1908
  >>> await index.add_documents_from_file_in_batches(file_path)
1923
1909
  """
1924
- documents = await _async_load_documents_from_file(file_path, csv_delimiter)
1910
+ documents = await _async_load_documents_from_file(
1911
+ file_path, csv_delimiter, json_handler=self._json_handler
1912
+ )
1925
1913
 
1926
1914
  return await self.add_documents_in_batches(
1927
1915
  documents,
1928
1916
  batch_size=batch_size,
1929
1917
  primary_key=primary_key,
1930
1918
  compress=compress,
1931
- serializer=serializer,
1932
1919
  )
1933
1920
 
1934
1921
  async def add_documents_from_raw_file(
@@ -1938,7 +1925,6 @@ class AsyncIndex(_BaseIndex):
1938
1925
  *,
1939
1926
  csv_delimiter: str | None = None,
1940
1927
  compress: bool = False,
1941
- serializer: type[json.JSONEncoder] | None = None,
1942
1928
  ) -> TaskInfo:
1943
1929
  """Directly send csv or ndjson files to Meilisearch without pre-processing.
1944
1930
 
@@ -1954,8 +1940,6 @@ class AsyncIndex(_BaseIndex):
1954
1940
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
1955
1941
  can only be used if the file is a csv file. Defaults to comma.
1956
1942
  compress: If set to True the data will be sent in gzip format. Defaults to False.
1957
- serializer: A custom JSONEncode to handle serializing fields that the build in
1958
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
1959
1943
 
1960
1944
  Returns:
1961
1945
 
@@ -2013,7 +1997,7 @@ class AsyncIndex(_BaseIndex):
2013
1997
  data = await f.read()
2014
1998
 
2015
1999
  response = await self._http_requests.post(
2016
- url, body=data, content_type=content_type, compress=compress, serializer=serializer
2000
+ url, body=data, content_type=content_type, compress=compress
2017
2001
  )
2018
2002
 
2019
2003
  return TaskInfo(**response.json())
@@ -2024,7 +2008,6 @@ class AsyncIndex(_BaseIndex):
2024
2008
  primary_key: str | None = None,
2025
2009
  *,
2026
2010
  compress: bool = False,
2027
- serializer: type[json.JSONEncoder] | None = None,
2028
2011
  ) -> TaskInfo:
2029
2012
  """Update documents in the index.
2030
2013
 
@@ -2034,8 +2017,6 @@ class AsyncIndex(_BaseIndex):
2034
2017
  primary_key: The primary key of the documents. This will be ignored if already set.
2035
2018
  Defaults to None.
2036
2019
  compress: If set to True the data will be sent in gzip format. Defaults to False.
2037
- serializer: A custom JSONEncode to handle serializing fields that the build in
2038
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
2039
2020
 
2040
2021
  Returns:
2041
2022
 
@@ -2130,9 +2111,7 @@ class AsyncIndex(_BaseIndex):
2130
2111
  )
2131
2112
 
2132
2113
  response_coroutine = tg.create_task(
2133
- self._http_requests.put(
2134
- url, documents, compress=compress, serializer=serializer
2135
- )
2114
+ self._http_requests.put(url, documents, compress=compress)
2136
2115
  )
2137
2116
 
2138
2117
  response = await response_coroutine
@@ -2151,9 +2130,7 @@ class AsyncIndex(_BaseIndex):
2151
2130
 
2152
2131
  return result
2153
2132
 
2154
- response = await self._http_requests.put(
2155
- url, documents, compress=compress, serializer=serializer
2156
- )
2133
+ response = await self._http_requests.put(url, documents, compress=compress)
2157
2134
  result = TaskInfo(**response.json())
2158
2135
  if self._post_update_documents_plugins:
2159
2136
  post = await AsyncIndex._run_plugins(
@@ -2175,7 +2152,6 @@ class AsyncIndex(_BaseIndex):
2175
2152
  batch_size: int = 1000,
2176
2153
  primary_key: str | None = None,
2177
2154
  compress: bool = False,
2178
- serializer: type[json.JSONEncoder] | None = None,
2179
2155
  ) -> list[TaskInfo]:
2180
2156
  """Update documents in batches to reduce RAM usage with indexing.
2181
2157
 
@@ -2189,8 +2165,6 @@ class AsyncIndex(_BaseIndex):
2189
2165
  primary_key: The primary key of the documents. This will be ignored if already set.
2190
2166
  Defaults to None.
2191
2167
  compress: If set to True the data will be sent in gzip format. Defaults to False.
2192
- serializer: A custom JSONEncode to handle serializing fields that the build in
2193
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
2194
2168
 
2195
2169
  Returns:
2196
2170
 
@@ -2214,7 +2188,7 @@ class AsyncIndex(_BaseIndex):
2214
2188
  """
2215
2189
  if not use_task_groups():
2216
2190
  batches = [
2217
- self.update_documents(x, primary_key, compress=compress, serializer=serializer)
2191
+ self.update_documents(x, primary_key, compress=compress)
2218
2192
  for x in _batch(documents, batch_size)
2219
2193
  ]
2220
2194
  return await asyncio.gather(*batches)
@@ -2235,7 +2209,6 @@ class AsyncIndex(_BaseIndex):
2235
2209
  csv_delimiter: str | None = None,
2236
2210
  combine_documents: bool = True,
2237
2211
  compress: bool = False,
2238
- serializer: type[json.JSONEncoder] | None = None,
2239
2212
  ) -> list[TaskInfo]:
2240
2213
  """Load all json files from a directory and update the documents.
2241
2214
 
@@ -2252,8 +2225,6 @@ class AsyncIndex(_BaseIndex):
2252
2225
  combine_documents: If set to True this will combine the documents from all the files
2253
2226
  before indexing them. Defaults to True.
2254
2227
  compress: If set to True the data will be sent in gzip format. Defaults to False.
2255
- serializer: A custom JSONEncode to handle serializing fields that the build in
2256
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
2257
2228
 
2258
2229
  Returns:
2259
2230
 
@@ -2281,7 +2252,9 @@ class AsyncIndex(_BaseIndex):
2281
2252
  all_documents = []
2282
2253
  for path in directory.iterdir():
2283
2254
  if path.suffix == f".{document_type}":
2284
- documents = await _async_load_documents_from_file(path, csv_delimiter)
2255
+ documents = await _async_load_documents_from_file(
2256
+ path, csv_delimiter, json_handler=self._json_handler
2257
+ )
2285
2258
  all_documents.append(documents)
2286
2259
 
2287
2260
  _raise_on_no_documents(all_documents, document_type, directory_path)
@@ -2289,20 +2262,18 @@ class AsyncIndex(_BaseIndex):
2289
2262
  loop = asyncio.get_running_loop()
2290
2263
  combined = await loop.run_in_executor(None, partial(_combine_documents, all_documents))
2291
2264
 
2292
- response = await self.update_documents(
2293
- combined, primary_key, compress=compress, serializer=serializer
2294
- )
2265
+ response = await self.update_documents(combined, primary_key, compress=compress)
2295
2266
  return [response]
2296
2267
 
2297
2268
  if not use_task_groups():
2298
2269
  update_documents = []
2299
2270
  for path in directory.iterdir():
2300
2271
  if path.suffix == f".{document_type}":
2301
- documents = await _async_load_documents_from_file(path, csv_delimiter)
2272
+ documents = await _async_load_documents_from_file(
2273
+ path, csv_delimiter, json_handler=self._json_handler
2274
+ )
2302
2275
  update_documents.append(
2303
- self.update_documents(
2304
- documents, primary_key, compress=compress, serializer=serializer
2305
- )
2276
+ self.update_documents(documents, primary_key, compress=compress)
2306
2277
  )
2307
2278
 
2308
2279
  _raise_on_no_documents(update_documents, document_type, directory_path)
@@ -2323,19 +2294,17 @@ class AsyncIndex(_BaseIndex):
2323
2294
  results = []
2324
2295
  for i, path in enumerate(directory.iterdir()):
2325
2296
  if path.suffix == f".{document_type}":
2326
- documents = await _async_load_documents_from_file(path, csv_delimiter)
2297
+ documents = await _async_load_documents_from_file(
2298
+ path, csv_delimiter, json_handler=self._json_handler
2299
+ )
2327
2300
  if i == 0:
2328
2301
  results = [
2329
- await self.update_documents(
2330
- documents, primary_key, compress=compress, serializer=serializer
2331
- )
2302
+ await self.update_documents(documents, primary_key, compress=compress)
2332
2303
  ]
2333
2304
  else:
2334
2305
  tasks.append(
2335
2306
  tg.create_task(
2336
- self.update_documents(
2337
- documents, primary_key, compress=compress, serializer=serializer
2338
- )
2307
+ self.update_documents(documents, primary_key, compress=compress)
2339
2308
  )
2340
2309
  )
2341
2310
 
@@ -2353,7 +2322,6 @@ class AsyncIndex(_BaseIndex):
2353
2322
  csv_delimiter: str | None = None,
2354
2323
  combine_documents: bool = True,
2355
2324
  compress: bool = False,
2356
- serializer: type[json.JSONEncoder] | None = None,
2357
2325
  ) -> list[TaskInfo]:
2358
2326
  """Load all json files from a directory and update the documents.
2359
2327
 
@@ -2372,8 +2340,6 @@ class AsyncIndex(_BaseIndex):
2372
2340
  combine_documents: If set to True this will combine the documents from all the files
2373
2341
  before indexing them. Defaults to True.
2374
2342
  compress: If set to True the data will be sent in gzip format. Defaults to False.
2375
- serializer: A custom JSONEncode to handle serializing fields that the build in
2376
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
2377
2343
 
2378
2344
  Returns:
2379
2345
 
@@ -2401,7 +2367,9 @@ class AsyncIndex(_BaseIndex):
2401
2367
  all_documents = []
2402
2368
  for path in directory.iterdir():
2403
2369
  if path.suffix == f".{document_type}":
2404
- documents = await _async_load_documents_from_file(path, csv_delimiter)
2370
+ documents = await _async_load_documents_from_file(
2371
+ path, csv_delimiter, json_handler=self._json_handler
2372
+ )
2405
2373
  all_documents.append(documents)
2406
2374
 
2407
2375
  _raise_on_no_documents(all_documents, document_type, directory_path)
@@ -2414,7 +2382,6 @@ class AsyncIndex(_BaseIndex):
2414
2382
  batch_size=batch_size,
2415
2383
  primary_key=primary_key,
2416
2384
  compress=compress,
2417
- serializer=serializer,
2418
2385
  )
2419
2386
 
2420
2387
  if not use_task_groups():
@@ -2423,14 +2390,15 @@ class AsyncIndex(_BaseIndex):
2423
2390
  update_documents = []
2424
2391
  for path in directory.iterdir():
2425
2392
  if path.suffix == f".{document_type}":
2426
- documents = await _async_load_documents_from_file(path, csv_delimiter)
2393
+ documents = await _async_load_documents_from_file(
2394
+ path, csv_delimiter, json_handler=self._json_handler
2395
+ )
2427
2396
  update_documents.append(
2428
2397
  self.update_documents_in_batches(
2429
2398
  documents,
2430
2399
  batch_size=batch_size,
2431
2400
  primary_key=primary_key,
2432
2401
  compress=compress,
2433
- serializer=serializer,
2434
2402
  )
2435
2403
  )
2436
2404
 
@@ -2452,14 +2420,15 @@ class AsyncIndex(_BaseIndex):
2452
2420
  tasks = []
2453
2421
  for i, path in enumerate(directory.iterdir()):
2454
2422
  if path.suffix == f".{document_type}":
2455
- documents = await _async_load_documents_from_file(path, csv_delimiter)
2423
+ documents = await _async_load_documents_from_file(
2424
+ path, csv_delimiter, json_handler=self._json_handler
2425
+ )
2456
2426
  if i == 0:
2457
2427
  results = await self.update_documents_in_batches(
2458
2428
  documents,
2459
2429
  batch_size=batch_size,
2460
2430
  primary_key=primary_key,
2461
2431
  compress=compress,
2462
- serializer=serializer,
2463
2432
  )
2464
2433
  else:
2465
2434
  tasks.append(
@@ -2469,7 +2438,6 @@ class AsyncIndex(_BaseIndex):
2469
2438
  batch_size=batch_size,
2470
2439
  primary_key=primary_key,
2471
2440
  compress=compress,
2472
- serializer=serializer,
2473
2441
  )
2474
2442
  )
2475
2443
  )
@@ -2485,7 +2453,6 @@ class AsyncIndex(_BaseIndex):
2485
2453
  csv_delimiter: str | None = None,
2486
2454
  *,
2487
2455
  compress: bool = False,
2488
- serializer: type[json.JSONEncoder] | None = None,
2489
2456
  ) -> TaskInfo:
2490
2457
  """Add documents in the index from a json file.
2491
2458
 
@@ -2497,8 +2464,6 @@ class AsyncIndex(_BaseIndex):
2497
2464
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
2498
2465
  can only be used if the file is a csv file. Defaults to comma.
2499
2466
  compress: If set to True the data will be sent in gzip format. Defaults to False.
2500
- serializer: A custom JSONEncode to handle serializing fields that the build in
2501
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
2502
2467
 
2503
2468
  Returns:
2504
2469
 
@@ -2518,12 +2483,12 @@ class AsyncIndex(_BaseIndex):
2518
2483
  >>> index = client.index("movies")
2519
2484
  >>> await index.update_documents_from_file(file_path)
2520
2485
  """
2521
- documents = await _async_load_documents_from_file(file_path, csv_delimiter)
2522
-
2523
- return await self.update_documents(
2524
- documents, primary_key=primary_key, compress=compress, serializer=serializer
2486
+ documents = await _async_load_documents_from_file(
2487
+ file_path, csv_delimiter, json_handler=self._json_handler
2525
2488
  )
2526
2489
 
2490
+ return await self.update_documents(documents, primary_key=primary_key, compress=compress)
2491
+
2527
2492
  async def update_documents_from_file_in_batches(
2528
2493
  self,
2529
2494
  file_path: Path | str,
@@ -2531,7 +2496,6 @@ class AsyncIndex(_BaseIndex):
2531
2496
  batch_size: int = 1000,
2532
2497
  primary_key: str | None = None,
2533
2498
  compress: bool = False,
2534
- serializer: type[json.JSONEncoder] | None = None,
2535
2499
  ) -> list[TaskInfo]:
2536
2500
  """Updates documents form a json file in batches to reduce RAM usage with indexing.
2537
2501
 
@@ -2543,8 +2507,6 @@ class AsyncIndex(_BaseIndex):
2543
2507
  primary_key: The primary key of the documents. This will be ignored if already set.
2544
2508
  Defaults to None.
2545
2509
  compress: If set to True the data will be sent in gzip format. Defaults to False.
2546
- serializer: A custom JSONEncode to handle serializing fields that the build in
2547
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
2548
2510
 
2549
2511
  Returns:
2550
2512
 
@@ -2564,14 +2526,15 @@ class AsyncIndex(_BaseIndex):
2564
2526
  >>> index = client.index("movies")
2565
2527
  >>> await index.update_documents_from_file_in_batches(file_path)
2566
2528
  """
2567
- documents = await _async_load_documents_from_file(file_path)
2529
+ documents = await _async_load_documents_from_file(
2530
+ file_path, json_handler=self._json_handler
2531
+ )
2568
2532
 
2569
2533
  return await self.update_documents_in_batches(
2570
2534
  documents,
2571
2535
  batch_size=batch_size,
2572
2536
  primary_key=primary_key,
2573
2537
  compress=compress,
2574
- serializer=serializer,
2575
2538
  )
2576
2539
 
2577
2540
  async def update_documents_from_raw_file(
@@ -2581,7 +2544,6 @@ class AsyncIndex(_BaseIndex):
2581
2544
  csv_delimiter: str | None = None,
2582
2545
  *,
2583
2546
  compress: bool = False,
2584
- serializer: type[json.JSONEncoder] | None = None,
2585
2547
  ) -> TaskInfo:
2586
2548
  """Directly send csv or ndjson files to Meilisearch without pre-processing.
2587
2549
 
@@ -2597,8 +2559,6 @@ class AsyncIndex(_BaseIndex):
2597
2559
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
2598
2560
  can only be used if the file is a csv file. Defaults to comma.
2599
2561
  compress: If set to True the data will be sent in gzip format. Defaults to False.
2600
- serializer: A custom JSONEncode to handle serializing fields that the build in
2601
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
2602
2562
 
2603
2563
  Returns:
2604
2564
 
@@ -2656,7 +2616,7 @@ class AsyncIndex(_BaseIndex):
2656
2616
  data = await f.read()
2657
2617
 
2658
2618
  response = await self._http_requests.put(
2659
- url, body=data, content_type=content_type, compress=compress, serializer=serializer
2619
+ url, body=data, content_type=content_type, compress=compress
2660
2620
  )
2661
2621
 
2662
2622
  return TaskInfo(**response.json())
@@ -3078,16 +3038,7 @@ class AsyncIndex(_BaseIndex):
3078
3038
  >>> index = client.index("movies")
3079
3039
  >>> await index.update_settings(new_settings)
3080
3040
  """
3081
- if is_pydantic_2():
3082
- body_dict = {k: v for k, v in body.model_dump(by_alias=True).items() if v is not None} # type: ignore[attr-defined]
3083
- else: # pragma: no cover
3084
- warn(
3085
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
3086
- DeprecationWarning,
3087
- stacklevel=2,
3088
- )
3089
- body_dict = {k: v for k, v in body.dict(by_alias=True).items() if v is not None} # type: ignore[attr-defined]
3090
-
3041
+ body_dict = {k: v for k, v in body.model_dump(by_alias=True).items() if v is not None}
3091
3042
  response = await self._http_requests.patch(self._settings_url, body_dict, compress=compress)
3092
3043
 
3093
3044
  return TaskInfo(**response.json())
@@ -3812,23 +3763,11 @@ class AsyncIndex(_BaseIndex):
3812
3763
  >>> TypoTolerance(enabled=False)
3813
3764
  >>> await index.update_typo_tolerance()
3814
3765
  """
3815
- if is_pydantic_2():
3816
- response = await self._http_requests.patch(
3817
- f"{self._settings_url}/typo-tolerance",
3818
- typo_tolerance.model_dump(by_alias=True),
3819
- compress=compress,
3820
- ) # type: ignore[attr-defined]
3821
- else: # pragma: no cover
3822
- warn(
3823
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
3824
- DeprecationWarning,
3825
- stacklevel=2,
3826
- )
3827
- response = await self._http_requests.patch(
3828
- f"{self._settings_url}/typo-tolerance",
3829
- typo_tolerance.dict(by_alias=True),
3830
- compress=compress,
3831
- ) # type: ignore[attr-defined]
3766
+ response = await self._http_requests.patch(
3767
+ f"{self._settings_url}/typo-tolerance",
3768
+ typo_tolerance.model_dump(by_alias=True),
3769
+ compress=compress,
3770
+ )
3832
3771
 
3833
3772
  return TaskInfo(**response.json())
3834
3773
 
@@ -3902,21 +3841,11 @@ class AsyncIndex(_BaseIndex):
3902
3841
  >>> index = client.index("movies")
3903
3842
  >>> await index.update_faceting(faceting=Faceting(max_values_per_facet=100))
3904
3843
  """
3905
- if is_pydantic_2():
3906
- response = await self._http_requests.patch(
3907
- f"{self._settings_url}/faceting",
3908
- faceting.model_dump(by_alias=True),
3909
- compress=compress,
3910
- ) # type: ignore[attr-defined]
3911
- else: # pragma: no cover
3912
- warn(
3913
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
3914
- DeprecationWarning,
3915
- stacklevel=2,
3916
- )
3917
- response = await self._http_requests.patch(
3918
- f"{self._settings_url}/faceting", faceting.dict(by_alias=True), compress=compress
3919
- ) # type: ignore[attr-defined]
3844
+ response = await self._http_requests.patch(
3845
+ f"{self._settings_url}/faceting",
3846
+ faceting.model_dump(by_alias=True),
3847
+ compress=compress,
3848
+ )
3920
3849
 
3921
3850
  return TaskInfo(**response.json())
3922
3851
 
@@ -3991,21 +3920,11 @@ class AsyncIndex(_BaseIndex):
3991
3920
  >>> index = client.index("movies")
3992
3921
  >>> await index.update_pagination(settings=Pagination(max_total_hits=123))
3993
3922
  """
3994
- if is_pydantic_2():
3995
- response = await self._http_requests.patch(
3996
- f"{self._settings_url}/pagination",
3997
- settings.model_dump(by_alias=True),
3998
- compress=compress,
3999
- ) # type: ignore[attr-defined]
4000
- else: # pragma: no cover
4001
- warn(
4002
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
4003
- DeprecationWarning,
4004
- stacklevel=2,
4005
- )
4006
- response = await self._http_requests.patch(
4007
- f"{self._settings_url}/pagination", settings.dict(by_alias=True), compress=compress
4008
- ) # type: ignore[attr-defined]
3923
+ response = await self._http_requests.patch(
3924
+ f"{self._settings_url}/pagination",
3925
+ settings.model_dump(by_alias=True),
3926
+ compress=compress,
3927
+ )
4009
3928
 
4010
3929
  return TaskInfo(**response.json())
4011
3930
 
@@ -4479,19 +4398,9 @@ class AsyncIndex(_BaseIndex):
4479
4398
  """
4480
4399
  payload = {}
4481
4400
  for key, embedder in embedders.embedders.items():
4482
- if is_pydantic_2():
4483
- payload[key] = {
4484
- k: v for k, v in embedder.model_dump(by_alias=True).items() if v is not None
4485
- } # type: ignore[attr-defined]
4486
- else: # pragma: no cover
4487
- warn(
4488
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
4489
- DeprecationWarning,
4490
- stacklevel=2,
4491
- )
4492
- payload[key] = {
4493
- k: v for k, v in embedder.dict(by_alias=True).items() if v is not None
4494
- } # type: ignore[attr-defined]
4401
+ payload[key] = {
4402
+ k: v for k, v in embedder.model_dump(by_alias=True).items() if v is not None
4403
+ }
4495
4404
 
4496
4405
  response = await self._http_requests.patch(
4497
4406
  f"{self._settings_url}/embedders", payload, compress=compress
@@ -4606,6 +4515,7 @@ class Index(_BaseIndex):
4606
4515
  created_at: str | datetime | None = None,
4607
4516
  updated_at: str | datetime | None = None,
4608
4517
  plugins: IndexPlugins | None = None,
4518
+ json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
4609
4519
  ):
4610
4520
  """Class initializer.
4611
4521
 
@@ -4618,10 +4528,14 @@ class Index(_BaseIndex):
4618
4528
  created_at: The date and time the index was created. Defaults to None.
4619
4529
  updated_at: The date and time the index was last updated. Defaults to None.
4620
4530
  plugins: Optional plugins can be provided to extend functionality.
4531
+ json_handler: The module to use for json operations. The options are BuiltinHandler
4532
+ (uses the json module from the standard library), OrjsonHandler (uses orjson), or
4533
+ UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
4534
+ extra needs to be included. Default: BuiltinHandler.
4621
4535
  """
4622
- super().__init__(uid, primary_key, created_at, updated_at)
4536
+ super().__init__(uid, primary_key, created_at, updated_at, json_handler=json_handler)
4623
4537
  self.http_client = http_client
4624
- self._http_requests = HttpRequests(http_client)
4538
+ self._http_requests = HttpRequests(http_client, json_handler=self._json_handler)
4625
4539
  self.plugins = plugins
4626
4540
 
4627
4541
  @cached_property
@@ -5001,6 +4915,7 @@ class Index(_BaseIndex):
5001
4915
  wait: bool = True,
5002
4916
  timeout_in_ms: int | None = None,
5003
4917
  plugins: IndexPlugins | None = None,
4918
+ json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
5004
4919
  ) -> Self:
5005
4920
  """Creates a new index.
5006
4921
 
@@ -5025,6 +4940,10 @@ class Index(_BaseIndex):
5025
4940
  MeilisearchTimeoutError. `None` can also be passed to wait indefinitely. Be aware that
5026
4941
  if the `None` option is used the wait time could be very long. Defaults to None.
5027
4942
  plugins: Optional plugins can be provided to extend functionality.
4943
+ json_handler: The module to use for json operations. The options are BuiltinHandler
4944
+ (uses the json module from the standard library), OrjsonHandler (uses orjson), or
4945
+ UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
4946
+ extra needs to be included. Default: BuiltinHandler.
5028
4947
 
5029
4948
  Returns:
5030
4949
 
@@ -5047,7 +4966,8 @@ class Index(_BaseIndex):
5047
4966
  payload = {"primaryKey": primary_key, "uid": uid}
5048
4967
 
5049
4968
  url = "indexes"
5050
- http_request = HttpRequests(http_client)
4969
+ handler = json_handler if json_handler else BuiltinHandler()
4970
+ http_request = HttpRequests(http_client, handler)
5051
4971
  response = http_request.post(url, payload)
5052
4972
  wait_for_task(http_client, response.json()["taskUid"], timeout_in_ms=timeout_in_ms)
5053
4973
  index_response = http_request.get(f"{url}/{uid}")
@@ -5059,6 +4979,7 @@ class Index(_BaseIndex):
5059
4979
  created_at=index_dict["createdAt"],
5060
4980
  updated_at=index_dict["updatedAt"],
5061
4981
  plugins=plugins,
4982
+ json_handler=json_handler,
5062
4983
  )
5063
4984
 
5064
4985
  if settings:
@@ -5108,7 +5029,7 @@ class Index(_BaseIndex):
5108
5029
  highlight_pre_tag: str = "<em>",
5109
5030
  highlight_post_tag: str = "</em>",
5110
5031
  crop_marker: str = "...",
5111
- matching_strategy: Literal["all", "last", "frequency"] = "all",
5032
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
5112
5033
  hits_per_page: int | None = None,
5113
5034
  page: int | None = None,
5114
5035
  attributes_to_search_on: list[str] | None = None,
@@ -5134,13 +5055,14 @@ class Index(_BaseIndex):
5134
5055
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
5135
5056
  Defaults to None.
5136
5057
  sort: Attributes by which to sort the results. Defaults to None.
5137
- show_matches_position: Defines whether an object that contains information about the matches should be
5138
- returned or not. Defaults to False.
5058
+ show_matches_position: Defines whether an object that contains information about the
5059
+ matches should be returned or not. Defaults to False.
5139
5060
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
5140
5061
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
5141
5062
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
5142
5063
  Defaults to ...
5143
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
5064
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
5065
+ `last`.
5144
5066
  hits_per_page: Sets the number of results returned per page.
5145
5067
  page: Sets the specific results page to fetch.
5146
5068
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -5274,7 +5196,7 @@ class Index(_BaseIndex):
5274
5196
  highlight_pre_tag: str = "<em>",
5275
5197
  highlight_post_tag: str = "</em>",
5276
5198
  crop_marker: str = "...",
5277
- matching_strategy: str = "all",
5199
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
5278
5200
  hits_per_page: int | None = None,
5279
5201
  page: int | None = None,
5280
5202
  attributes_to_search_on: list[str] | None = None,
@@ -5301,13 +5223,14 @@ class Index(_BaseIndex):
5301
5223
  attributes_to_highlight: Attributes whose values will contain highlighted matching terms.
5302
5224
  Defaults to None.
5303
5225
  sort: Attributes by which to sort the results. Defaults to None.
5304
- show_matches_position: Defines whether an object that contains information about the matches should be
5305
- returned or not. Defaults to False.
5226
+ show_matches_position: Defines whether an object that contains information about the
5227
+ matches should be returned or not. Defaults to False.
5306
5228
  highlight_pre_tag: The opening tag for highlighting text. Defaults to <em>.
5307
5229
  highlight_post_tag: The closing tag for highlighting text. Defaults to </em>
5308
5230
  crop_marker: Marker to display when the number of words excedes the `crop_length`.
5309
5231
  Defaults to ...
5310
- matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to `all`.
5232
+ matching_strategy: Specifies the matching strategy Meilisearch should use. Defaults to
5233
+ `last`.
5311
5234
  hits_per_page: Sets the number of results returned per page.
5312
5235
  page: Sets the specific results page to fetch.
5313
5236
  attributes_to_search_on: List of field names. Allow search over a subset of searchable
@@ -5578,7 +5501,6 @@ class Index(_BaseIndex):
5578
5501
  primary_key: str | None = None,
5579
5502
  *,
5580
5503
  compress: bool = False,
5581
- serializer: type[json.JSONEncoder] | None = None,
5582
5504
  ) -> TaskInfo:
5583
5505
  """Add documents to the index.
5584
5506
 
@@ -5588,8 +5510,6 @@ class Index(_BaseIndex):
5588
5510
  primary_key: The primary key of the documents. This will be ignored if already set.
5589
5511
  Defaults to None.
5590
5512
  compress: If set to True the data will be sent in gzip format. Defaults to False.
5591
- serializer: A custom JSONEncode to handle serializing fields that the build in
5592
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
5593
5513
 
5594
5514
  Returns:
5595
5515
 
@@ -5626,9 +5546,7 @@ class Index(_BaseIndex):
5626
5546
  if pre.get("document_result"):
5627
5547
  documents = pre["document_result"]
5628
5548
 
5629
- response = self._http_requests.post(
5630
- url, documents, compress=compress, serializer=serializer
5631
- )
5549
+ response = self._http_requests.post(url, documents, compress=compress)
5632
5550
  result = TaskInfo(**response.json())
5633
5551
  if self._post_add_documents_plugins:
5634
5552
  post = Index._run_plugins(self._post_add_documents_plugins, Event.POST, result=result)
@@ -5644,7 +5562,6 @@ class Index(_BaseIndex):
5644
5562
  batch_size: int = 1000,
5645
5563
  primary_key: str | None = None,
5646
5564
  compress: bool = False,
5647
- serializer: type[json.JSONEncoder] | None = None,
5648
5565
  ) -> list[TaskInfo]:
5649
5566
  """Adds documents in batches to reduce RAM usage with indexing.
5650
5567
 
@@ -5656,8 +5573,6 @@ class Index(_BaseIndex):
5656
5573
  primary_key: The primary key of the documents. This will be ignored if already set.
5657
5574
  Defaults to None.
5658
5575
  compress: If set to True the data will be sent in gzip format. Defaults to False.
5659
- serializer: A custom JSONEncode to handle serializing fields that the build in
5660
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
5661
5576
 
5662
5577
  Returns:
5663
5578
 
@@ -5680,7 +5595,7 @@ class Index(_BaseIndex):
5680
5595
  >>> index.add_documents_in_batches(documents)
5681
5596
  """
5682
5597
  return [
5683
- self.add_documents(x, primary_key, compress=compress, serializer=serializer)
5598
+ self.add_documents(x, primary_key, compress=compress)
5684
5599
  for x in _batch(documents, batch_size)
5685
5600
  ]
5686
5601
 
@@ -5693,7 +5608,6 @@ class Index(_BaseIndex):
5693
5608
  csv_delimiter: str | None = None,
5694
5609
  combine_documents: bool = True,
5695
5610
  compress: bool = False,
5696
- serializer: type[json.JSONEncoder] | None = None,
5697
5611
  ) -> list[TaskInfo]:
5698
5612
  """Load all json files from a directory and add the documents to the index.
5699
5613
 
@@ -5710,8 +5624,6 @@ class Index(_BaseIndex):
5710
5624
  combine_documents: If set to True this will combine the documents from all the files
5711
5625
  before indexing them. Defaults to True.
5712
5626
  compress: If set to True the data will be sent in gzip format. Defaults to False.
5713
- serializer: A custom JSONEncode to handle serializing fields that the build in
5714
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
5715
5627
 
5716
5628
  Returns:
5717
5629
 
@@ -5739,28 +5651,26 @@ class Index(_BaseIndex):
5739
5651
  all_documents = []
5740
5652
  for path in directory.iterdir():
5741
5653
  if path.suffix == f".{document_type}":
5742
- documents = _load_documents_from_file(path, csv_delimiter)
5654
+ documents = _load_documents_from_file(
5655
+ path, csv_delimiter, json_handler=self._json_handler
5656
+ )
5743
5657
  all_documents.append(documents)
5744
5658
 
5745
5659
  _raise_on_no_documents(all_documents, document_type, directory_path)
5746
5660
 
5747
5661
  combined = _combine_documents(all_documents)
5748
5662
 
5749
- response = self.add_documents(
5750
- combined, primary_key, compress=compress, serializer=serializer
5751
- )
5663
+ response = self.add_documents(combined, primary_key, compress=compress)
5752
5664
 
5753
5665
  return [response]
5754
5666
 
5755
5667
  responses = []
5756
5668
  for path in directory.iterdir():
5757
5669
  if path.suffix == f".{document_type}":
5758
- documents = _load_documents_from_file(path, csv_delimiter)
5759
- responses.append(
5760
- self.add_documents(
5761
- documents, primary_key, compress=compress, serializer=serializer
5762
- )
5670
+ documents = _load_documents_from_file(
5671
+ path, csv_delimiter, json_handler=self._json_handler
5763
5672
  )
5673
+ responses.append(self.add_documents(documents, primary_key, compress=compress))
5764
5674
 
5765
5675
  _raise_on_no_documents(responses, document_type, directory_path)
5766
5676
 
@@ -5776,7 +5686,6 @@ class Index(_BaseIndex):
5776
5686
  csv_delimiter: str | None = None,
5777
5687
  combine_documents: bool = True,
5778
5688
  compress: bool = False,
5779
- serializer: type[json.JSONEncoder] | None = None,
5780
5689
  ) -> list[TaskInfo]:
5781
5690
  """Load all json files from a directory and add the documents to the index in batches.
5782
5691
 
@@ -5795,8 +5704,6 @@ class Index(_BaseIndex):
5795
5704
  combine_documents: If set to True this will combine the documents from all the files
5796
5705
  before indexing them. Defaults to True.
5797
5706
  compress: If set to True the data will be sent in gzip format. Defaults to False.
5798
- serializer: A custom JSONEncode to handle serializing fields that the build in
5799
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
5800
5707
 
5801
5708
  Returns:
5802
5709
 
@@ -5824,7 +5731,9 @@ class Index(_BaseIndex):
5824
5731
  all_documents = []
5825
5732
  for path in directory.iterdir():
5826
5733
  if path.suffix == f".{document_type}":
5827
- documents = _load_documents_from_file(path, csv_delimiter=csv_delimiter)
5734
+ documents = _load_documents_from_file(
5735
+ path, csv_delimiter=csv_delimiter, json_handler=self._json_handler
5736
+ )
5828
5737
  all_documents.append(documents)
5829
5738
 
5830
5739
  _raise_on_no_documents(all_documents, document_type, directory_path)
@@ -5836,20 +5745,20 @@ class Index(_BaseIndex):
5836
5745
  batch_size=batch_size,
5837
5746
  primary_key=primary_key,
5838
5747
  compress=compress,
5839
- serializer=serializer,
5840
5748
  )
5841
5749
 
5842
5750
  responses: list[TaskInfo] = []
5843
5751
  for path in directory.iterdir():
5844
5752
  if path.suffix == f".{document_type}":
5845
- documents = _load_documents_from_file(path, csv_delimiter)
5753
+ documents = _load_documents_from_file(
5754
+ path, csv_delimiter, json_handler=self._json_handler
5755
+ )
5846
5756
  responses.extend(
5847
5757
  self.add_documents_in_batches(
5848
5758
  documents,
5849
5759
  batch_size=batch_size,
5850
5760
  primary_key=primary_key,
5851
5761
  compress=compress,
5852
- serializer=serializer,
5853
5762
  )
5854
5763
  )
5855
5764
 
@@ -5863,7 +5772,6 @@ class Index(_BaseIndex):
5863
5772
  primary_key: str | None = None,
5864
5773
  *,
5865
5774
  compress: bool = False,
5866
- serializer: type[json.JSONEncoder] | None = None,
5867
5775
  ) -> TaskInfo:
5868
5776
  """Add documents to the index from a json file.
5869
5777
 
@@ -5873,8 +5781,6 @@ class Index(_BaseIndex):
5873
5781
  primary_key: The primary key of the documents. This will be ignored if already set.
5874
5782
  Defaults to None.
5875
5783
  compress: If set to True the data will be sent in gzip format. Defaults to False.
5876
- serializer: A custom JSONEncode to handle serializing fields that the build in
5877
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
5878
5784
 
5879
5785
  Returns:
5880
5786
 
@@ -5896,11 +5802,9 @@ class Index(_BaseIndex):
5896
5802
  >>> index = client.index("movies")
5897
5803
  >>> index.add_documents_from_file(file_path)
5898
5804
  """
5899
- documents = _load_documents_from_file(file_path)
5805
+ documents = _load_documents_from_file(file_path, json_handler=self._json_handler)
5900
5806
 
5901
- return self.add_documents(
5902
- documents, primary_key=primary_key, compress=compress, serializer=serializer
5903
- )
5807
+ return self.add_documents(documents, primary_key=primary_key, compress=compress)
5904
5808
 
5905
5809
  def add_documents_from_file_in_batches(
5906
5810
  self,
@@ -5910,7 +5814,6 @@ class Index(_BaseIndex):
5910
5814
  primary_key: str | None = None,
5911
5815
  csv_delimiter: str | None = None,
5912
5816
  compress: bool = False,
5913
- serializer: type[json.JSONEncoder] | None = None,
5914
5817
  ) -> list[TaskInfo]:
5915
5818
  """Adds documents form a json file in batches to reduce RAM usage with indexing.
5916
5819
 
@@ -5924,8 +5827,6 @@ class Index(_BaseIndex):
5924
5827
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
5925
5828
  can only be used if the file is a csv file. Defaults to comma.
5926
5829
  compress: If set to True the data will be sent in gzip format. Defaults to False.
5927
- serializer: A custom JSONEncode to handle serializing fields that the build in
5928
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
5929
5830
 
5930
5831
  Returns:
5931
5832
 
@@ -5947,14 +5848,15 @@ class Index(_BaseIndex):
5947
5848
  >>> index = client.index("movies")
5948
5849
  >>> index.add_documents_from_file_in_batches(file_path)
5949
5850
  """
5950
- documents = _load_documents_from_file(file_path, csv_delimiter)
5851
+ documents = _load_documents_from_file(
5852
+ file_path, csv_delimiter, json_handler=self._json_handler
5853
+ )
5951
5854
 
5952
5855
  return self.add_documents_in_batches(
5953
5856
  documents,
5954
5857
  batch_size=batch_size,
5955
5858
  primary_key=primary_key,
5956
5859
  compress=compress,
5957
- serializer=serializer,
5958
5860
  )
5959
5861
 
5960
5862
  def add_documents_from_raw_file(
@@ -5964,7 +5866,6 @@ class Index(_BaseIndex):
5964
5866
  *,
5965
5867
  csv_delimiter: str | None = None,
5966
5868
  compress: bool = False,
5967
- serializer: type[json.JSONEncoder] | None = None,
5968
5869
  ) -> TaskInfo:
5969
5870
  """Directly send csv or ndjson files to Meilisearch without pre-processing.
5970
5871
 
@@ -5980,8 +5881,6 @@ class Index(_BaseIndex):
5980
5881
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
5981
5882
  can only be used if the file is a csv file. Defaults to comma.
5982
5883
  compress: If set to True the data will be sent in gzip format. Defaults to False.
5983
- serializer: A custom JSONEncode to handle serializing fields that the build in
5984
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
5985
5884
 
5986
5885
  Returns:
5987
5886
 
@@ -6039,7 +5938,7 @@ class Index(_BaseIndex):
6039
5938
  data = f.read()
6040
5939
 
6041
5940
  response = self._http_requests.post(
6042
- url, body=data, content_type=content_type, compress=compress, serializer=serializer
5941
+ url, body=data, content_type=content_type, compress=compress
6043
5942
  )
6044
5943
 
6045
5944
  return TaskInfo(**response.json())
@@ -6050,7 +5949,6 @@ class Index(_BaseIndex):
6050
5949
  primary_key: str | None = None,
6051
5950
  *,
6052
5951
  compress: bool = False,
6053
- serializer: type[json.JSONEncoder] | None = None,
6054
5952
  ) -> TaskInfo:
6055
5953
  """Update documents in the index.
6056
5954
 
@@ -6060,8 +5958,6 @@ class Index(_BaseIndex):
6060
5958
  primary_key: The primary key of the documents. This will be ignored if already set.
6061
5959
  Defaults to None.
6062
5960
  compress: If set to True the data will be sent in gzip format. Defaults to False.
6063
- serializer: A custom JSONEncode to handle serializing fields that the build in
6064
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
6065
5961
 
6066
5962
  Returns:
6067
5963
 
@@ -6098,7 +5994,7 @@ class Index(_BaseIndex):
6098
5994
  if pre.get("document_result"):
6099
5995
  documents = pre["document_result"]
6100
5996
 
6101
- response = self._http_requests.put(url, documents, compress=compress, serializer=serializer)
5997
+ response = self._http_requests.put(url, documents, compress=compress)
6102
5998
  result = TaskInfo(**response.json())
6103
5999
  if self._post_update_documents_plugins:
6104
6000
  post = Index._run_plugins(
@@ -6116,7 +6012,6 @@ class Index(_BaseIndex):
6116
6012
  batch_size: int = 1000,
6117
6013
  primary_key: str | None = None,
6118
6014
  compress: bool = False,
6119
- serializer: type[json.JSONEncoder] | None = None,
6120
6015
  ) -> list[TaskInfo]:
6121
6016
  """Update documents in batches to reduce RAM usage with indexing.
6122
6017
 
@@ -6130,8 +6025,6 @@ class Index(_BaseIndex):
6130
6025
  primary_key: The primary key of the documents. This will be ignored if already set.
6131
6026
  Defaults to None.
6132
6027
  compress: If set to True the data will be sent in gzip format. Defaults to False.
6133
- serializer: A custom JSONEncode to handle serializing fields that the build in
6134
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
6135
6028
 
6136
6029
  Returns:
6137
6030
 
@@ -6154,7 +6047,7 @@ class Index(_BaseIndex):
6154
6047
  >>> index.update_documents_in_batches(documents)
6155
6048
  """
6156
6049
  return [
6157
- self.update_documents(x, primary_key, compress=compress, serializer=serializer)
6050
+ self.update_documents(x, primary_key, compress=compress)
6158
6051
  for x in _batch(documents, batch_size)
6159
6052
  ]
6160
6053
 
@@ -6167,7 +6060,6 @@ class Index(_BaseIndex):
6167
6060
  csv_delimiter: str | None = None,
6168
6061
  combine_documents: bool = True,
6169
6062
  compress: bool = False,
6170
- serializer: type[json.JSONEncoder] | None = None,
6171
6063
  ) -> list[TaskInfo]:
6172
6064
  """Load all json files from a directory and update the documents.
6173
6065
 
@@ -6184,8 +6076,6 @@ class Index(_BaseIndex):
6184
6076
  combine_documents: If set to True this will combine the documents from all the files
6185
6077
  before indexing them. Defaults to True.
6186
6078
  compress: If set to True the data will be sent in gzip format. Defaults to False.
6187
- serializer: A custom JSONEncode to handle serializing fields that the build in
6188
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
6189
6079
 
6190
6080
  Returns:
6191
6081
 
@@ -6213,27 +6103,25 @@ class Index(_BaseIndex):
6213
6103
  all_documents = []
6214
6104
  for path in directory.iterdir():
6215
6105
  if path.suffix == f".{document_type}":
6216
- documents = _load_documents_from_file(path, csv_delimiter)
6106
+ documents = _load_documents_from_file(
6107
+ path, csv_delimiter, json_handler=self._json_handler
6108
+ )
6217
6109
  all_documents.append(documents)
6218
6110
 
6219
6111
  _raise_on_no_documents(all_documents, document_type, directory_path)
6220
6112
 
6221
6113
  combined = _combine_documents(all_documents)
6222
6114
 
6223
- response = self.update_documents(
6224
- combined, primary_key, compress=compress, serializer=serializer
6225
- )
6115
+ response = self.update_documents(combined, primary_key, compress=compress)
6226
6116
  return [response]
6227
6117
 
6228
6118
  responses = []
6229
6119
  for path in directory.iterdir():
6230
6120
  if path.suffix == f".{document_type}":
6231
- documents = _load_documents_from_file(path, csv_delimiter)
6232
- responses.append(
6233
- self.update_documents(
6234
- documents, primary_key, compress=compress, serializer=serializer
6235
- )
6121
+ documents = _load_documents_from_file(
6122
+ path, csv_delimiter, json_handler=self._json_handler
6236
6123
  )
6124
+ responses.append(self.update_documents(documents, primary_key, compress=compress))
6237
6125
 
6238
6126
  _raise_on_no_documents(responses, document_type, directory_path)
6239
6127
 
@@ -6249,7 +6137,6 @@ class Index(_BaseIndex):
6249
6137
  csv_delimiter: str | None = None,
6250
6138
  combine_documents: bool = True,
6251
6139
  compress: bool = False,
6252
- serializer: type[json.JSONEncoder] | None = None,
6253
6140
  ) -> list[TaskInfo]:
6254
6141
  """Load all json files from a directory and update the documents.
6255
6142
 
@@ -6268,8 +6155,6 @@ class Index(_BaseIndex):
6268
6155
  combine_documents: If set to True this will combine the documents from all the files
6269
6156
  before indexing them. Defaults to True.
6270
6157
  compress: If set to True the data will be sent in gzip format. Defaults to False.
6271
- serializer: A custom JSONEncode to handle serializing fields that the build in
6272
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
6273
6158
 
6274
6159
  Returns:
6275
6160
 
@@ -6297,7 +6182,9 @@ class Index(_BaseIndex):
6297
6182
  all_documents = []
6298
6183
  for path in directory.iterdir():
6299
6184
  if path.suffix == f".{document_type}":
6300
- documents = _load_documents_from_file(path, csv_delimiter)
6185
+ documents = _load_documents_from_file(
6186
+ path, csv_delimiter, json_handler=self._json_handler
6187
+ )
6301
6188
  all_documents.append(documents)
6302
6189
 
6303
6190
  _raise_on_no_documents(all_documents, document_type, directory_path)
@@ -6309,21 +6196,21 @@ class Index(_BaseIndex):
6309
6196
  batch_size=batch_size,
6310
6197
  primary_key=primary_key,
6311
6198
  compress=compress,
6312
- serializer=serializer,
6313
6199
  )
6314
6200
 
6315
6201
  responses: list[TaskInfo] = []
6316
6202
 
6317
6203
  for path in directory.iterdir():
6318
6204
  if path.suffix == f".{document_type}":
6319
- documents = _load_documents_from_file(path, csv_delimiter)
6205
+ documents = _load_documents_from_file(
6206
+ path, csv_delimiter, json_handler=self._json_handler
6207
+ )
6320
6208
  responses.extend(
6321
6209
  self.update_documents_in_batches(
6322
6210
  documents,
6323
6211
  batch_size=batch_size,
6324
6212
  primary_key=primary_key,
6325
6213
  compress=compress,
6326
- serializer=serializer,
6327
6214
  )
6328
6215
  )
6329
6216
 
@@ -6338,7 +6225,6 @@ class Index(_BaseIndex):
6338
6225
  csv_delimiter: str | None = None,
6339
6226
  *,
6340
6227
  compress: bool = False,
6341
- serializer: type[json.JSONEncoder] | None = None,
6342
6228
  ) -> TaskInfo:
6343
6229
  """Add documents in the index from a json file.
6344
6230
 
@@ -6350,8 +6236,6 @@ class Index(_BaseIndex):
6350
6236
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
6351
6237
  can only be used if the file is a csv file. Defaults to comma.
6352
6238
  compress: If set to True the data will be sent in gzip format. Defaults to False.
6353
- serializer: A custom JSONEncode to handle serializing fields that the build in
6354
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
6355
6239
 
6356
6240
  Returns:
6357
6241
 
@@ -6371,12 +6255,12 @@ class Index(_BaseIndex):
6371
6255
  >>> index = client.index("movies")
6372
6256
  >>> index.update_documents_from_file(file_path)
6373
6257
  """
6374
- documents = _load_documents_from_file(file_path, csv_delimiter)
6375
-
6376
- return self.update_documents(
6377
- documents, primary_key=primary_key, compress=compress, serializer=serializer
6258
+ documents = _load_documents_from_file(
6259
+ file_path, csv_delimiter, json_handler=self._json_handler
6378
6260
  )
6379
6261
 
6262
+ return self.update_documents(documents, primary_key=primary_key, compress=compress)
6263
+
6380
6264
  def update_documents_from_file_in_batches(
6381
6265
  self,
6382
6266
  file_path: Path | str,
@@ -6384,7 +6268,6 @@ class Index(_BaseIndex):
6384
6268
  batch_size: int = 1000,
6385
6269
  primary_key: str | None = None,
6386
6270
  compress: bool = False,
6387
- serializer: type[json.JSONEncoder] | None = None,
6388
6271
  ) -> list[TaskInfo]:
6389
6272
  """Updates documents form a json file in batches to reduce RAM usage with indexing.
6390
6273
 
@@ -6396,8 +6279,6 @@ class Index(_BaseIndex):
6396
6279
  primary_key: The primary key of the documents. This will be ignored if already set.
6397
6280
  Defaults to None.
6398
6281
  compress: If set to True the data will be sent in gzip format. Defaults to False.
6399
- serializer: A custom JSONEncode to handle serializing fields that the build in
6400
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
6401
6282
 
6402
6283
  Returns:
6403
6284
 
@@ -6417,14 +6298,13 @@ class Index(_BaseIndex):
6417
6298
  >>> index = client.index("movies")
6418
6299
  >>> index.update_documents_from_file_in_batches(file_path)
6419
6300
  """
6420
- documents = _load_documents_from_file(file_path)
6301
+ documents = _load_documents_from_file(file_path, json_handler=self._json_handler)
6421
6302
 
6422
6303
  return self.update_documents_in_batches(
6423
6304
  documents,
6424
6305
  batch_size=batch_size,
6425
6306
  primary_key=primary_key,
6426
6307
  compress=compress,
6427
- serializer=serializer,
6428
6308
  )
6429
6309
 
6430
6310
  def update_documents_from_raw_file(
@@ -6434,7 +6314,6 @@ class Index(_BaseIndex):
6434
6314
  csv_delimiter: str | None = None,
6435
6315
  *,
6436
6316
  compress: bool = False,
6437
- serializer: type[json.JSONEncoder] | None = None,
6438
6317
  ) -> TaskInfo:
6439
6318
  """Directly send csv or ndjson files to Meilisearch without pre-processing.
6440
6319
 
@@ -6450,8 +6329,6 @@ class Index(_BaseIndex):
6450
6329
  csv_delimiter: A single ASCII character to specify the delimiter for csv files. This
6451
6330
  can only be used if the file is a csv file. Defaults to comma.
6452
6331
  compress: If set to True the data will be sent in gzip format. Defaults to False.
6453
- serializer: A custom JSONEncode to handle serializing fields that the build in
6454
- json.dumps cannot handle, for example UUID and datetime. Defaults to None.
6455
6332
 
6456
6333
  Returns:
6457
6334
 
@@ -6509,7 +6386,7 @@ class Index(_BaseIndex):
6509
6386
  data = f.read()
6510
6387
 
6511
6388
  response = self._http_requests.put(
6512
- url, body=data, content_type=content_type, compress=compress, serializer=serializer
6389
+ url, body=data, content_type=content_type, compress=compress
6513
6390
  )
6514
6391
 
6515
6392
  return TaskInfo(**response.json())
@@ -6769,16 +6646,7 @@ class Index(_BaseIndex):
6769
6646
  >>> index = client.index("movies")
6770
6647
  >>> index.update_settings(new_settings)
6771
6648
  """
6772
- if is_pydantic_2():
6773
- body_dict = {k: v for k, v in body.model_dump(by_alias=True).items() if v is not None} # type: ignore[attr-defined]
6774
- else: # pragma: no cover
6775
- warn(
6776
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
6777
- DeprecationWarning,
6778
- stacklevel=2,
6779
- )
6780
- body_dict = {k: v for k, v in body.dict(by_alias=True).items() if v is not None} # type: ignore[attr-defined]
6781
-
6649
+ body_dict = {k: v for k, v in body.model_dump(by_alias=True).items() if v is not None}
6782
6650
  response = self._http_requests.patch(self._settings_url, body_dict, compress=compress)
6783
6651
 
6784
6652
  return TaskInfo(**response.json())
@@ -7492,23 +7360,11 @@ class Index(_BaseIndex):
7492
7360
  >>> TypoTolerance(enabled=False)
7493
7361
  >>> index.update_typo_tolerance()
7494
7362
  """
7495
- if is_pydantic_2():
7496
- response = self._http_requests.patch(
7497
- f"{self._settings_url}/typo-tolerance",
7498
- typo_tolerance.model_dump(by_alias=True),
7499
- compress=compress,
7500
- ) # type: ignore[attr-defined]
7501
- else: # pragma: no cover
7502
- warn(
7503
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
7504
- DeprecationWarning,
7505
- stacklevel=2,
7506
- )
7507
- response = self._http_requests.patch(
7508
- f"{self._settings_url}/typo-tolerance",
7509
- typo_tolerance.dict(by_alias=True),
7510
- compress=compress,
7511
- ) # type: ignore[attr-defined]
7363
+ response = self._http_requests.patch(
7364
+ f"{self._settings_url}/typo-tolerance",
7365
+ typo_tolerance.model_dump(by_alias=True),
7366
+ compress=compress,
7367
+ )
7512
7368
 
7513
7369
  return TaskInfo(**response.json())
7514
7370
 
@@ -7582,21 +7438,11 @@ class Index(_BaseIndex):
7582
7438
  >>> index = client.index("movies")
7583
7439
  >>> index.update_faceting(faceting=Faceting(max_values_per_facet=100))
7584
7440
  """
7585
- if is_pydantic_2():
7586
- response = self._http_requests.patch(
7587
- f"{self._settings_url}/faceting",
7588
- faceting.model_dump(by_alias=True),
7589
- compress=compress,
7590
- ) # type: ignore[attr-defined]
7591
- else: # pragma: no cover
7592
- warn(
7593
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
7594
- DeprecationWarning,
7595
- stacklevel=2,
7596
- )
7597
- response = self._http_requests.patch(
7598
- f"{self._settings_url}/faceting", faceting.dict(by_alias=True), compress=compress
7599
- ) # type: ignore[attr-defined]
7441
+ response = self._http_requests.patch(
7442
+ f"{self._settings_url}/faceting",
7443
+ faceting.model_dump(by_alias=True),
7444
+ compress=compress,
7445
+ )
7600
7446
 
7601
7447
  return TaskInfo(**response.json())
7602
7448
 
@@ -7671,21 +7517,11 @@ class Index(_BaseIndex):
7671
7517
  >>> index = client.index("movies")
7672
7518
  >>> index.update_pagination(settings=Pagination(max_total_hits=123))
7673
7519
  """
7674
- if is_pydantic_2():
7675
- response = self._http_requests.patch(
7676
- f"{self._settings_url}/pagination",
7677
- settings.model_dump(by_alias=True),
7678
- compress=compress,
7679
- ) # type: ignore[attr-defined]
7680
- else: # pragma: no cover
7681
- warn(
7682
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
7683
- DeprecationWarning,
7684
- stacklevel=2,
7685
- )
7686
- response = self._http_requests.patch(
7687
- f"{self._settings_url}/pagination", settings.dict(by_alias=True), compress=compress
7688
- ) # type: ignore[attr-defined]
7520
+ response = self._http_requests.patch(
7521
+ f"{self._settings_url}/pagination",
7522
+ settings.model_dump(by_alias=True),
7523
+ compress=compress,
7524
+ )
7689
7525
 
7690
7526
  return TaskInfo(**response.json())
7691
7527
 
@@ -8153,19 +7989,9 @@ class Index(_BaseIndex):
8153
7989
  """
8154
7990
  payload = {}
8155
7991
  for key, embedder in embedders.embedders.items():
8156
- if is_pydantic_2():
8157
- payload[key] = {
8158
- k: v for k, v in embedder.model_dump(by_alias=True).items() if v is not None
8159
- } # type: ignore[attr-defined]
8160
- else: # pragma: no cover
8161
- warn(
8162
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
8163
- DeprecationWarning,
8164
- stacklevel=2,
8165
- )
8166
- payload[key] = {
8167
- k: v for k, v in embedder.dict(by_alias=True).items() if v is not None
8168
- } # type: ignore[attr-defined]
7992
+ payload[key] = {
7993
+ k: v for k, v in embedder.model_dump(by_alias=True).items() if v is not None
7994
+ }
8169
7995
 
8170
7996
  response = self._http_requests.patch(
8171
7997
  f"{self._settings_url}/embedders", payload, compress=compress
@@ -8241,6 +8067,8 @@ class Index(_BaseIndex):
8241
8067
  async def _async_load_documents_from_file(
8242
8068
  file_path: Path | str,
8243
8069
  csv_delimiter: str | None = None,
8070
+ *,
8071
+ json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler,
8244
8072
  ) -> list[dict[Any, Any]]:
8245
8073
  if isinstance(file_path, str):
8246
8074
  file_path = Path(file_path)
@@ -8267,11 +8095,11 @@ async def _async_load_documents_from_file(
8267
8095
 
8268
8096
  if file_path.suffix == ".ndjson":
8269
8097
  with open(file_path) as f: # noqa: ASYNC101 ASYNC230
8270
- return [await loop.run_in_executor(None, partial(json.loads, x)) for x in f]
8098
+ return [await loop.run_in_executor(None, partial(json_handler.loads, x)) for x in f]
8271
8099
 
8272
8100
  async with aiofiles.open(file_path, mode="r") as f: # type: ignore
8273
8101
  data = await f.read() # type: ignore
8274
- documents = await loop.run_in_executor(None, partial(json.loads, data))
8102
+ documents = await loop.run_in_executor(None, partial(json_handler.loads, data))
8275
8103
 
8276
8104
  if not isinstance(documents, list):
8277
8105
  raise InvalidDocumentError("Meilisearch requires documents to be in a list")
@@ -8310,6 +8138,8 @@ def _plugin_has_method(
8310
8138
  def _load_documents_from_file(
8311
8139
  file_path: Path | str,
8312
8140
  csv_delimiter: str | None = None,
8141
+ *,
8142
+ json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler,
8313
8143
  ) -> list[dict[Any, Any]]:
8314
8144
  if isinstance(file_path, str):
8315
8145
  file_path = Path(file_path)
@@ -8333,11 +8163,11 @@ def _load_documents_from_file(
8333
8163
 
8334
8164
  if file_path.suffix == ".ndjson":
8335
8165
  with open(file_path) as f:
8336
- return [json.loads(x) for x in f]
8166
+ return [json_handler.loads(x) for x in f]
8337
8167
 
8338
8168
  with open(file_path) as f:
8339
8169
  data = f.read()
8340
- documents = json.loads(data)
8170
+ documents = json_handler.loads(data)
8341
8171
 
8342
8172
  if not isinstance(documents, list):
8343
8173
  raise InvalidDocumentError("Meilisearch requires documents to be in a list")
@@ -8370,7 +8200,7 @@ def _process_search_parameters(
8370
8200
  highlight_pre_tag: str = "<em>",
8371
8201
  highlight_post_tag: str = "</em>",
8372
8202
  crop_marker: str = "...",
8373
- matching_strategy: str = "all",
8203
+ matching_strategy: Literal["all", "last", "frequency"] = "last",
8374
8204
  hits_per_page: int | None = None,
8375
8205
  page: int | None = None,
8376
8206
  attributes_to_search_on: list[str] | None = None,
@@ -8419,15 +8249,7 @@ def _process_search_parameters(
8419
8249
  body["vector"] = vector
8420
8250
 
8421
8251
  if hybrid:
8422
- if is_pydantic_2():
8423
- body["hybrid"] = hybrid.model_dump(by_alias=True) # type: ignore[attr-defined]
8424
- else: # pragma: no cover
8425
- warn(
8426
- "The use of Pydantic less than version 2 is depreciated and will be removed in a future release",
8427
- DeprecationWarning,
8428
- stacklevel=2,
8429
- )
8430
- body["hybrid"] = hybrid.dict(by_alias=True) # type: ignore[attr-defined]
8252
+ body["hybrid"] = hybrid.model_dump(by_alias=True)
8431
8253
 
8432
8254
  return body
8433
8255