Skip to content

Commit 3164af8

Browse files
committed
refactor structure + document model
1 parent 352d2b7 commit 3164af8

File tree

9 files changed

+61
-34
lines changed

9 files changed

+61
-34
lines changed

meilisearch/index.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
from meilisearch._httprequests import HttpRequests
66
from meilisearch.config import Config
77
from meilisearch.task import get_task, get_tasks, wait_for_task
8-
from meilisearch.models import DocumentsResults, Task, TaskInfo, TaskResults, IndexStats
8+
9+
from meilisearch.models.index import IndexStats
10+
from meilisearch.models.document import Document, DocumentsResults
11+
from meilisearch.models.task import Task, TaskInfo, TaskResults
912

1013
# pylint: disable=too-many-public-methods
1114
class Index():
@@ -255,7 +258,7 @@ def search(self, query: str, opt_params: Optional[Dict[str, Any]] = None) -> Dic
255258
body=body
256259
)
257260

258-
def get_document(self, document_id: str, parameters: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
261+
def get_document(self, document_id: str, parameters: Optional[Dict[str, Any]] = None) -> Document:
259262
"""Get one document with given document identifier.
260263
261264
Parameters
@@ -279,9 +282,11 @@ def get_document(self, document_id: str, parameters: Optional[Dict[str, Any]] =
279282
parameters = {}
280283
elif 'fields' in parameters and isinstance(parameters['fields'], list):
281284
parameters['fields'] = ",".join(parameters['fields'])
282-
return self.http.get(
285+
286+
document = self.http.get(
283287
f'{self.config.paths.index}/{self.uid}/{self.config.paths.document}/{document_id}?{parse.urlencode(parameters)}'
284288
)
289+
return Document(document)
285290

286291
def get_documents(self, parameters: Optional[Dict[str, Any]] = None) -> DocumentsResults:
287292
"""Get a set of documents from the index.
@@ -309,7 +314,7 @@ def get_documents(self, parameters: Optional[Dict[str, Any]] = None) -> Document
309314
response = self.http.get(
310315
f'{self.config.paths.index}/{self.uid}/{self.config.paths.document}?{parse.urlencode(parameters)}'
311316
)
312-
return DocumentsResults(**response)
317+
return DocumentsResults(response)
313318

314319
def add_documents(
315320
self,
@@ -337,8 +342,8 @@ def add_documents(
337342
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://docs.meilisearch.com/errors/#meilisearch-errors
338343
"""
339344
url = self._build_url(primary_key)
340-
response = self.http.post(url, documents)
341-
return TaskInfo(**response)
345+
add_document_task = self.http.post(url, documents)
346+
return TaskInfo(**add_document_task)
342347

343348
def add_documents_in_batches(
344349
self,

meilisearch/models/__init__.py

Whitespace-only changes.

meilisearch/models/document.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from typing import Any, Iterator, List, Dict
2+
3+
class Document:
4+
__doc: dict
5+
6+
def __init__(self, doc: Dict[str, Any]) -> None:
7+
self.__doc = doc
8+
for key in doc:
9+
setattr(self, key, doc[key])
10+
11+
def __getattr__(self, attr: str) -> str:
12+
if attr in self.__doc.keys():
13+
return attr
14+
raise AttributeError(f"{self.__class__.__name__} object has no attribute {attr}")
15+
16+
def __iter__(self) -> Iterator:
17+
return iter(self.__dict__.items()) # type: ignore
18+
19+
class DocumentsResults:
20+
def __init__(self, resp: Dict[str, Any]) -> None:
21+
self.results: List[Document] = [Document(doc) for doc in resp['results']]
22+
self.offset: int = resp['offset']
23+
self.limit: int = resp['limit']
24+
self.total: int = resp['total']

meilisearch/models/index.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from typing import Any, Dict
2+
from camel_converter.pydantic_base import CamelBase
3+
4+
class IndexStats(CamelBase):
5+
number_of_documents: int
6+
is_indexing: bool
7+
field_distribution: Dict[str, Any]

meilisearch/models.py renamed to meilisearch/models/task.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
from typing import Any, List, Dict, Optional
22
from camel_converter.pydantic_base import CamelBase
33

4-
class DocumentsResults(CamelBase):
5-
results: List[Dict[str, Any]]
6-
offset: int
7-
limit: int
8-
total: int
9-
104
class Task(CamelBase):
115
uid: str
126
index_uid: str
@@ -35,8 +29,3 @@ def __init__(self, resp: Dict[str, Any]) -> None:
3529
self.limit: int = resp['limit']
3630
self.from_: int = resp['from']
3731
self.next_: int = resp['next']
38-
39-
class IndexStats(CamelBase):
40-
number_of_documents: int
41-
is_indexing: bool
42-
field_distribution: Dict[str, Any]

tests/index/test_index_document_meilisearch.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
from math import ceil
44
from meilisearch.client import Client
5-
from meilisearch.models import TaskInfo
5+
from meilisearch.models.document import Document
6+
from meilisearch.models.task import TaskInfo
67

78
import pytest
89

@@ -47,17 +48,18 @@ def test_add_documents_in_batches(
4748
def test_get_document(index_with_documents):
4849
"""Tests getting one document from a populated index."""
4950
response = index_with_documents().get_document('500682')
50-
assert isinstance(response, dict)
51-
assert 'title' in response
52-
assert response['title'] == 'The Highwaymen'
51+
assert isinstance(response, Document)
52+
assert hasattr(response, 'title')
53+
assert response.title == 'The Highwaymen'
5354

5455
def test_get_document_with_fields(index_with_documents):
5556
"""Tests getting one document from a populated index."""
5657
response = index_with_documents().get_document('500682', {'fields' : ['id', 'title']})
57-
assert isinstance(response, dict)
58-
assert 'title' in response
59-
assert 'poster' not in response
60-
assert response['title'] == 'The Highwaymen'
58+
assert isinstance(response, Document)
59+
assert hasattr(response, 'title')
60+
assert not hasattr(response, 'poster')
61+
# assert 'poster' not in response
62+
assert response.title == 'The Highwaymen'
6163

6264
def test_get_document_inexistent(empty_index):
6365
"""Tests getting one inexistent document from a populated index."""
@@ -82,24 +84,24 @@ def test_get_documents_offset_optional_params(index_with_documents):
8284
'fields': 'title'
8385
})
8486
assert len(response_offset_limit.results) == 3
85-
assert 'title' in response_offset_limit.results[0]
86-
assert response_offset_limit.results[0]['title'] == response.results[1]['title']
87+
assert hasattr(response_offset_limit.results[0], 'title')
88+
assert response_offset_limit.results[0].title == response.results[1].title
8789

8890
def test_update_documents(index_with_documents, small_movies):
8991
"""Tests updating a single document and a set of documents."""
9092
index = index_with_documents()
9193
response = index.get_documents()
92-
response.results[0]['title'] = 'Some title'
93-
update = index.update_documents([response.results[0]])
94+
response.results[0].title = 'Some title'
95+
update = index.update_documents([dict(response.results[0])])
9496
assert isinstance(update, TaskInfo)
9597
assert update.task_uid != None
9698
index.wait_for_task(update.task_uid)
9799
response = index.get_documents()
98-
assert response.results[0]['title'] == 'Some title'
100+
assert response.results[0].title == 'Some title'
99101
update = index.update_documents(small_movies)
100102
index.wait_for_task(update.task_uid)
101103
response = index.get_documents()
102-
assert response.results[0]['title'] != 'Some title'
104+
assert response.results[0].title != 'Some title'
103105

104106
@pytest.mark.parametrize('batch_size', [2, 3, 1000])
105107
@pytest.mark.parametrize(

tests/index/test_index_stats_meilisearch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from meilisearch.models import IndexStats
1+
from meilisearch.models.index import IndexStats
22

33
def test_get_stats(empty_index):
44
"""Tests getting stats of an index."""

tests/index/test_index_task_meilisearch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import pytest
44
from tests import common
5-
from meilisearch.models import Task, TaskResults
5+
from meilisearch.models.task import Task, TaskResults
66

77
def test_get_tasks_default(index_with_documents):
88
"""Tests getting the tasks list of an empty index."""

tests/index/test_index_wait_for_task.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from datetime import datetime
44
import pytest
55
from meilisearch.errors import MeiliSearchTimeoutError
6-
from meilisearch.models import Task
6+
from meilisearch.models.task import Task
77

88
def test_wait_for_task_default(index_with_documents):
99
"""Tests waiting for an update with default parameters."""

0 commit comments

Comments
 (0)