Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor task model and params #1066

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions meilisearch/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def get_stats(self) -> IndexStats:
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors
"""
stats = self.http.get(f"{self.config.paths.index}/{self.uid}/{self.config.paths.stat}")
return IndexStats(stats)
return IndexStats(**stats)

@version_error_hint_message
def search(self, query: str, opt_params: Optional[Mapping[str, Any]] = None) -> Dict[str, Any]:
Expand Down Expand Up @@ -364,7 +364,7 @@ def get_document(
"""
if parameters is None:
parameters = {}
elif "fields" in parameters and isinstance(parameters["fields"], list):
elif "fields" in parameters and isinstance(parameters["fields"], (list, tuple)):
parameters["fields"] = ",".join(parameters["fields"])

document = self.http.get(
Expand Down
34 changes: 23 additions & 11 deletions meilisearch/models/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,19 @@
from enum import Enum
from typing import Any, Dict, Iterator, List, Optional, Union

from camel_converter import to_snake
from camel_converter.pydantic_base import CamelBase
from pydantic import ConfigDict, field_validator


class IndexStats:
class FieldDistribution:
__dict: Dict

def __init__(self, doc: Dict[str, Any]) -> None:
self.__dict = doc
for key, val in doc.items():
key = to_snake(key)
if isinstance(val, dict):
setattr(self, key, IndexStats(val))
else:
setattr(self, key, val)
def __init__(self, dist: Dict[str, int]) -> None:
self.__dict = dist
for key in dist:
setattr(self, key, dist[key])

def __getattr__(self, attr: str) -> Any:
def __getattr__(self, attr: str) -> str:
if attr in self.__dict.keys():
return attr
raise AttributeError(f"{self.__class__.__name__} object has no attribute {attr}")
Expand All @@ -28,6 +24,22 @@ def __iter__(self) -> Iterator:
return iter(self.__dict__.items())


class IndexStats(CamelBase):
model_config = ConfigDict(arbitrary_types_allowed=True)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm understanding the documentation correctly, this is necessary.


number_of_documents: int
is_indexing: bool
field_distribution: FieldDistribution

@field_validator("field_distribution", mode="before")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that there was an Annotated pattern and a functional pattern.

The functional pattern made more sense to me, it looked more descriptive and everything was gonna stay in class anyway.

@classmethod
def build_field_distribution(cls, v: Any) -> FieldDistribution:
if not isinstance(v, dict):
raise TypeError('"field_distribution" in IndexStats must be a dict')
Comment on lines +37 to +38
Copy link
Contributor Author

@ellnix ellnix Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a test to see what happens if field_distribution was an int and without this line you get the mysterious:

FAILED tests/index/test_index_stats_meilisearch.py::test_make_trouble - TypeError: '
int' object is not iterable

versus the new

FAILED tests/index/test_index_stats_meilisearch.py::test_make_trouble - TypeError: "
field_distribution" in IndexStats must be a dict


return FieldDistribution(v)


class Faceting(CamelBase):
max_values_per_facet: int
sort_facet_values_by: Optional[Dict[str, str]] = None
Expand Down
13 changes: 6 additions & 7 deletions meilisearch/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,12 @@ def validate_enqueued_at(cls, v: str) -> datetime: # pylint: disable=invalid-na
return converted


class TaskResults:
def __init__(self, resp: Dict[str, Any]) -> None:
self.results: List[Task] = [Task(**task) for task in resp["results"]]
self.limit: int = resp["limit"]
self.total: int = resp["total"]
self.from_: int = resp["from"]
self.next_: int = resp["next"]
class TaskResults(CamelBase):
results: List[Task]
limit: int
total: int
from_: int
next_: Optional[int]


class Batch(CamelBase):
Expand Down
8 changes: 4 additions & 4 deletions meilisearch/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ def get_tasks(self, parameters: Optional[MutableMapping[str, Any]] = None) -> Ta
if parameters is None:
parameters = {}
for param in parameters:
if isinstance(parameters[param], list):
if isinstance(parameters[param], (list, tuple)):
parameters[param] = ",".join(parameters[param])
tasks = self.http.get(f"{self.config.paths.task}?{parse.urlencode(parameters)}")
return TaskResults(tasks)
return TaskResults(**tasks)

def get_task(self, uid: int) -> Task:
"""Get one task.
Expand Down Expand Up @@ -142,7 +142,7 @@ def cancel_tasks(self, parameters: MutableMapping[str, Any]) -> TaskInfo:
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors
"""
for param in parameters:
if isinstance(parameters[param], list):
if isinstance(parameters[param], (list, tuple)):
parameters[param] = ",".join(parameters[param])
response = self.http.post(f"{self.config.paths.task}/cancel?{parse.urlencode(parameters)}")
return TaskInfo(**response)
Expand All @@ -166,7 +166,7 @@ def delete_tasks(self, parameters: MutableMapping[str, Any]) -> TaskInfo:
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors
"""
for param in parameters:
if isinstance(parameters[param], list):
if isinstance(parameters[param], (list, tuple)):
parameters[param] = ",".join(parameters[param])
response = self.http.delete(f"{self.config.paths.task}?{parse.urlencode(parameters)}")
return TaskInfo(**response)
Expand Down
27 changes: 0 additions & 27 deletions tests/models/test_index.py

This file was deleted.

Loading