Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 4 additions & 24 deletions docs/json_handler.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# JSON Handler

For json loads and dumps you have the option to use the `json` module from the standard library,
orjson, or ujson. This done by setting the `json_handler` when creating the `AsyncClient` or
`Client`. By default the standard library `json` module will be used. The examples below use
`Client`, and the same options are available for `AsyncClient`.
For json loads and dumps you have the option to use the `json` module from the standard library, or
orjson. This done by setting the `json_handler` when creating the `AsyncClient` or `Client`. By
default the standard library `json` module will be used. The examples below use `Client`, and the
same options are available for `AsyncClient`.

## Standard Library `json` Module

Expand Down Expand Up @@ -61,23 +61,3 @@ with Client("http://127.0.0.1:7700", json_handler=OrjsonHandler()) as client:
index = client.index("movies", primary_key="id")
index.add_documents(documents)
```

## ujson

### Example

```py
from uuid import uuid4

from meilisearch_python_sdk import Client
from meilisearch_python_sdk.json_handler import UjsonHandler


documents = [
{"id": uuid4(), "title": "test 1"},
{"id": uuid4(), "title": "Test 2"},
]
with Client("http://127.0.0.1:7700", json_handler=UjsonHandler()) as client:
index = client.index("movies", primary_key="id")
index.add_documents(documents)
```
8 changes: 0 additions & 8 deletions examples/tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from examples.orjson_example import add_documents as orjson_add_documents
from examples.search_tracker import SearchTrackerPlugin, search
from examples.search_tracker import add_documents as search_tracker_add_documents
from examples.ujson_example import add_documents as ujson_add_documents
from examples.update_settings import add_documents as update_settings_add_documents
from examples.update_settings import update_settings
from meilisearch_python_sdk.plugins import IndexPlugins
Expand Down Expand Up @@ -38,10 +37,3 @@ def test_update_settings(small_movies_path, empty_index, client):
client.wait_for_task(task.task_uid)
result = client.get_task(task.task_uid)
assert result.status == "succeeded"


def test_ujson_example(small_movies_path, client):
task = ujson_add_documents(small_movies_path)
client.wait_for_task(task.task_uid)
result = client.get_task(task.task_uid)
assert result.status == "succeeded"
23 changes: 0 additions & 23 deletions examples/ujson_example.py

This file was deleted.

22 changes: 11 additions & 11 deletions meilisearch_python_sdk/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from meilisearch_python_sdk._http_requests import AsyncHttpRequests, HttpRequests
from meilisearch_python_sdk.errors import InvalidRestriction, MeilisearchApiError
from meilisearch_python_sdk.index import AsyncIndex, Index
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler
from meilisearch_python_sdk.models.client import (
ClientStats,
Key,
Expand Down Expand Up @@ -59,7 +59,7 @@ def __init__(
self,
api_key: str | None = None,
custom_headers: dict[str, str] | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
) -> None:
self.json_handler = json_handler if json_handler else BuiltinHandler()
self._headers: dict[str, str] | None = None
Expand Down Expand Up @@ -153,7 +153,7 @@ def __init__(
timeout: int | None = None,
verify: bool | SSLContext = True,
custom_headers: dict[str, str] | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
http2: bool = False,
) -> None:
"""Class initializer.
Expand All @@ -169,9 +169,9 @@ def __init__(
custom_headers: Custom headers to add when sending data to Meilisearch. Defaults to
None.
json_handler: The module to use for json operations. The options are BuiltinHandler
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
extra needs to be included. Default: BuiltinHandler.
(uses the json module from the standard library), or OrjsonHandler (uses orjson).
Note that in order use orjson the corresponding extra needs to be included.
Default: BuiltinHandler.
http2: Whether or not to use HTTP/2. Defaults to False.
"""
super().__init__(api_key, custom_headers, json_handler)
Expand Down Expand Up @@ -1316,7 +1316,7 @@ def __init__(
timeout: int | None = None,
verify: bool | SSLContext = True,
custom_headers: dict[str, str] | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
http2: bool = False,
) -> None:
"""Class initializer.
Expand All @@ -1332,9 +1332,9 @@ def __init__(
custom_headers: Custom headers to add when sending data to Meilisearch. Defaults to
None.
json_handler: The module to use for json operations. The options are BuiltinHandler
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
extra needs to be included. Default: BuiltinHandler.
(uses the json module from the standard library), or OrjsonHandler (uses orjson).
Note that in order use orjson the corresponding extra needs to be included.
Default: BuiltinHandler.
http2: If set to True, the client will use HTTP/2. Defaults to False.
"""
super().__init__(api_key, custom_headers, json_handler)
Expand Down Expand Up @@ -2467,7 +2467,7 @@ def _build_offset_limit_url(base: str, offset: int | None, limit: int | None) ->


def _build_update_key_payload(
key: KeyUpdate, json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler
key: KeyUpdate, json_handler: BuiltinHandler | OrjsonHandler
) -> JsonDict:
# The json_handler.loads(key.json()) is because Pydantic can't serialize a date in a Python dict,
# but can when converting to a json string.
Expand Down
8 changes: 3 additions & 5 deletions meilisearch_python_sdk/_http_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
MeilisearchCommunicationError,
MeilisearchError,
)
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler


class AsyncHttpRequests:
def __init__(
self, http_client: AsyncClient, json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler
self, http_client: AsyncClient, json_handler: BuiltinHandler | OrjsonHandler
) -> None:
self.http_client = http_client
self.json_handler = json_handler
Expand Down Expand Up @@ -118,9 +118,7 @@ async def delete(self, path: str, body: dict | None = None) -> Response:


class HttpRequests:
def __init__(
self, http_client: Client, json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler
) -> None:
def __init__(self, http_client: Client, json_handler: BuiltinHandler | OrjsonHandler) -> None:
self.http_client = http_client
self.json_handler = json_handler

Expand Down
4 changes: 2 additions & 2 deletions meilisearch_python_sdk/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from httpx import AsyncClient as HttpxAsyncClient
from httpx import Client as HttpxClient

from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler

if TYPE_CHECKING:
from meilisearch_python_sdk._client import AsyncClient, Client # pragma: no cover
Expand All @@ -34,7 +34,7 @@ def get_client(

def get_json_handler(
client: AsyncClient | Client | HttpxAsyncClient | HttpxClient,
) -> BuiltinHandler | OrjsonHandler | UjsonHandler:
) -> BuiltinHandler | OrjsonHandler:
if isinstance(client, (HttpxAsyncClient, HttpxClient)):
return BuiltinHandler()

Expand Down
4 changes: 2 additions & 2 deletions meilisearch_python_sdk/index/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from meilisearch_python_sdk._utils import iso_to_date_time
from meilisearch_python_sdk.errors import MeilisearchError
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler
from meilisearch_python_sdk.models.search import (
Hybrid,
)
Expand Down Expand Up @@ -50,7 +50,7 @@ def __init__(
primary_key: str | None = None,
created_at: str | datetime | None = None,
updated_at: str | datetime | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
hits_type: Any = JsonDict,
):
self.uid = uid
Expand Down
20 changes: 10 additions & 10 deletions meilisearch_python_sdk/index/async_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
validate_ranking_score_threshold,
)
from meilisearch_python_sdk.index._common import combine_documents as combine_documents_
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler
from meilisearch_python_sdk.models.documents import DocumentsInfo
from meilisearch_python_sdk.models.index import IndexStats
from meilisearch_python_sdk.models.search import (
Expand Down Expand Up @@ -84,7 +84,7 @@ def __init__(
created_at: str | datetime | None = None,
updated_at: str | datetime | None = None,
plugins: AsyncIndexPlugins | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
*,
hits_type: Any = JsonDict,
):
Expand All @@ -99,9 +99,9 @@ def __init__(
updated_at: The date and time the index was last updated. Defaults to None.
plugins: Optional plugins can be provided to extend functionality.
json_handler: The module to use for json operations. The options are BuiltinHandler
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
extra needs to be included. Default: BuiltinHandler.
(uses the json module from the standard library), or OrjsonHandler (uses orjson).
Note that in order use orjson the corresponding extra needs to be included.
Default: BuiltinHandler.
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
JsonDict
"""
Expand Down Expand Up @@ -581,7 +581,7 @@ async def create(
wait: bool = True,
timeout_in_ms: int | None = None,
plugins: AsyncIndexPlugins | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
hits_type: Any = JsonDict,
) -> Self:
"""Creates a new index.
Expand All @@ -607,9 +607,9 @@ async def create(
if the `None` option is used the wait time could be very long. Defaults to None.
plugins: Optional plugins can be provided to extend functionality.
json_handler: The module to use for json operations. The options are BuiltinHandler
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
extra needs to be included. Default: BuiltinHandler.
(uses the json module from the standard library), or OrjsonHandler (uses orjson).
Note that in order use orjson the corresponding extra needs to be included.
Default: BuiltinHandler.
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
JsonDict

Expand Down Expand Up @@ -4888,7 +4888,7 @@ async def _async_load_documents_from_file(
file_path: Path | str,
csv_delimiter: str | None = None,
*,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler,
json_handler: BuiltinHandler | OrjsonHandler,
) -> list[dict[Any, Any]]:
if isinstance(file_path, str):
file_path = Path(file_path)
Expand Down
20 changes: 10 additions & 10 deletions meilisearch_python_sdk/index/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
validate_ranking_score_threshold,
)
from meilisearch_python_sdk.index._common import combine_documents as combine_documents_
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler, UjsonHandler
from meilisearch_python_sdk.json_handler import BuiltinHandler, OrjsonHandler
from meilisearch_python_sdk.models.documents import DocumentsInfo
from meilisearch_python_sdk.models.index import IndexStats
from meilisearch_python_sdk.models.search import (
Expand Down Expand Up @@ -81,7 +81,7 @@ def __init__(
created_at: str | datetime | None = None,
updated_at: str | datetime | None = None,
plugins: IndexPlugins | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
*,
hits_type: Any = JsonDict,
):
Expand All @@ -96,9 +96,9 @@ def __init__(
updated_at: The date and time the index was last updated. Defaults to None.
plugins: Optional plugins can be provided to extend functionality.
json_handler: The module to use for json operations. The options are BuiltinHandler
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
extra needs to be included. Default: BuiltinHandler.
(uses the json module from the standard library), or OrjsonHandler (uses orjson).
Note that in order use orjson the corresponding extra needs to be included.
Default: BuiltinHandler.
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
JsonDict
"""
Expand Down Expand Up @@ -460,7 +460,7 @@ def create(
wait: bool = True,
timeout_in_ms: int | None = None,
plugins: IndexPlugins | None = None,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
json_handler: BuiltinHandler | OrjsonHandler | None = None,
hits_type: Any = JsonDict,
) -> Self:
"""Creates a new index.
Expand All @@ -486,9 +486,9 @@ def create(
if the `None` option is used the wait time could be very long. Defaults to None.
plugins: Optional plugins can be provided to extend functionality.
json_handler: The module to use for json operations. The options are BuiltinHandler
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
extra needs to be included. Default: BuiltinHandler.
(uses the json module from the standard library), or OrjsonHandler (uses orjson).
Note that in order use orjson the corresponding extra needs to be included.
Default: BuiltinHandler.
hits_type: Allows for a custom type to be passed to use for hits. Defaults to
JsonDict

Expand Down Expand Up @@ -3855,7 +3855,7 @@ def _load_documents_from_file(
file_path: Path | str,
csv_delimiter: str | None = None,
*,
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler,
json_handler: BuiltinHandler | OrjsonHandler,
) -> list[dict[Any, Any]]:
if isinstance(file_path, str):
file_path = Path(file_path)
Expand Down
23 changes: 0 additions & 23 deletions meilisearch_python_sdk/json_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
except ImportError: # pragma: no cover
orjson = None # type: ignore

try:
import ujson
except ImportError: # pragma: no cover
ujson = None # type: ignore


class _JsonHandler(ABC):
@staticmethod
Expand Down Expand Up @@ -70,21 +65,3 @@ def dump_bytes(obj: Any) -> bytes:
@staticmethod
def loads(json_string: str | bytes | bytearray) -> Any:
return orjson.loads(json_string)


class UjsonHandler(_JsonHandler):
def __init__(self) -> None:
if ujson is None: # pragma: no cover
raise ValueError("ujson must be installed to use the UjsonHandler")

@staticmethod
def dumps(obj: Any) -> str:
return ujson.dumps(obj)

@staticmethod
def dump_bytes(obj: Any) -> bytes:
return ujson.dumps(obj).encode("utf-8")

@staticmethod
def loads(json_string: str | bytes | bytearray) -> Any:
return ujson.loads(json_string)
4 changes: 1 addition & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ dependencies = [

[project.optional-dependencies]
orjson = ["orjson>=3.10.6"]
ujson = ["ujson>=5.10.0"]
all = ["orjson", "ujson"]
all = ["orjson"]

[dependency-groups]
dev = [
Expand All @@ -50,7 +49,6 @@ dev = [
"ruff==0.14.10",
"types-aiofiles==25.1.0.20251011",
"typing-extensions==4.15.0",
"types-ujson==5.10.0.20250822",
]

[tool.hatch.version]
Expand Down
Loading