Skip to content

Commit d723d01

Browse files
committed
Adding raw index methods
1 parent 6300a01 commit d723d01

File tree

4 files changed

+111
-2
lines changed

4 files changed

+111
-2
lines changed

meilisearch/client.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,32 @@ def create_index(self, uid, options=None):
5252
def get_indexes(self):
5353
"""Get all indexes.
5454
55+
Returns
56+
-------
57+
indexes: list
58+
List of Index instances.
59+
60+
Raises
61+
------
62+
MeiliSearchApiError
63+
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
64+
"""
65+
response = self.http.get(self.config.paths.index)
66+
67+
return [
68+
Index(
69+
self.config,
70+
x["uid"],
71+
x["primaryKey"],
72+
x["createdAt"],
73+
x["updatedAt"],
74+
)
75+
for x in response
76+
]
77+
78+
def get_raw_indexes(self):
79+
"""Get all indexes in dictionary format.
80+
5581
Returns
5682
-------
5783
indexes: list
@@ -85,6 +111,27 @@ def get_index(self, uid):
85111
"""
86112
return Index(self.config, uid).fetch_info()
87113

114+
def get_raw_index(self, uid):
115+
"""Get the index as a dictionary.
116+
This index should already exist.
117+
118+
Parameters
119+
----------
120+
uid: str
121+
UID of the index.
122+
123+
Returns
124+
-------
125+
index : dict
126+
An index in dictionary format. (e.g { 'uid': 'movies' 'primaryKey': 'objectID' })
127+
128+
Raises
129+
------
130+
MeiliSearchApiError
131+
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
132+
"""
133+
return self.http.get(f'{self.config.paths.index}/{uid}')
134+
88135
def index(self, uid):
89136
"""Create a local reference to an index identified by UID, without doing an HTTP call.
90137
Calling this method doesn't create an index in the MeiliSearch instance, but grants access to all the other methods in the Index class.

meilisearch/index.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Index():
1818
uid = None
1919
primary_key = None
2020

21-
def __init__(self, config, uid, primary_key=None):
21+
def __init__(self, config, uid, primary_key=None, created_at=None, updated_at=None):
2222
"""
2323
Parameters
2424
----------
@@ -33,6 +33,8 @@ def __init__(self, config, uid, primary_key=None):
3333
self.http = HttpRequests(config)
3434
self.uid = uid
3535
self.primary_key = primary_key
36+
self.created_at = self._iso_to_date_time(created_at)
37+
self.updated_at = self._iso_to_date_time(updated_at)
3638

3739
def delete(self):
3840
"""Delete the index.
@@ -69,6 +71,8 @@ def update(self, **body):
6971
payload['primaryKey'] = primary_key
7072
response = self.http.put(f'{self.config.paths.index}/{self.uid}', payload)
7173
self.primary_key = response['primaryKey']
74+
self.created_at = self._iso_to_date_time(response['createdAt'])
75+
self.updated_at = self._iso_to_date_time(response['updatedAt'])
7276
return self
7377

7478
def fetch_info(self):
@@ -86,6 +90,8 @@ def fetch_info(self):
8690
"""
8791
index_dict = self.http.get(f'{self.config.paths.index}/{self.uid}')
8892
self.primary_key = index_dict['primaryKey']
93+
self.created_at = self._iso_to_date_time(index_dict['createdAt'])
94+
self.updated_at = self._iso_to_date_time(index_dict['updatedAt'])
8995
return self
9096

9197
def get_primary_key(self):
@@ -935,5 +941,29 @@ def reset_attributes_for_faceting(self):
935941
self.__settings_url_for(self.config.paths.attributes_for_faceting),
936942
)
937943

944+
@staticmethod
945+
def _iso_to_date_time(iso_date):
946+
"""
947+
MeiliSearch returns the date time information in iso format. Python's implementation of
948+
datetime can only handle up to 6 digits in microseconds, however MeiliSearch sometimes
949+
returns more digits than this in the micosecond sections so when that happens this method
950+
reduces the number of microseconds so Python can handle it. If the value passed is either
951+
None or already in datetime format the original value is returned.
952+
"""
953+
if not iso_date:
954+
return None
955+
956+
if isinstance(iso_date, datetime):
957+
return iso_date
958+
959+
try:
960+
return datetime.strptime(iso_date, "%Y-%m-%dT%H:%M:%S.%fZ")
961+
except ValueError:
962+
split = iso_date.split(".")
963+
reduce = len(split[1]) - 6
964+
reduced = f"{split[0]}.{split[1][:-reduce]}Z"
965+
return datetime.strptime(reduced, "%Y-%m-%dT%H:%M:%S.%fZ")
966+
967+
938968
def __settings_url_for(self, sub_route):
939969
return f'{self.config.paths.index}/{self.uid}/{self.config.paths.setting}/{sub_route}'

meilisearch/tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def clear_indexes(client):
2020
# Deletes all the indexes in the MeiliSearch instance.
2121
indexes = client.get_indexes()
2222
for index in indexes:
23-
client.index(index['uid']).delete()
23+
client.index(index.uid).delete()
2424

2525
@fixture(scope='function')
2626
def indexes_sample(client):

meilisearch/tests/index/test_index.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# pylint: disable=invalid-name
22

3+
from datetime import datetime
4+
35
import pytest
46
from meilisearch.index import Index
57
from meilisearch.tests import common
@@ -32,6 +34,16 @@ def test_create_index_with_uid_in_options(client):
3234
def test_get_indexes(client):
3335
"""Tests getting all indexes."""
3436
response = client.get_indexes()
37+
uids = [index.uid for index in response]
38+
assert isinstance(response, list)
39+
assert common.INDEX_UID in uids
40+
assert common.INDEX_UID2 in uids
41+
assert common.INDEX_UID3 in uids
42+
assert len(response) == 3
43+
44+
@pytest.mark.usefixtures("indexes_sample")
45+
def test_get_raw_indexes(client):
46+
response = client.get_raw_indexes()
3547
uids = [index['uid'] for index in response]
3648
assert isinstance(response, list)
3749
assert common.INDEX_UID in uids
@@ -44,6 +56,8 @@ def test_index_with_any_uid(client):
4456
assert isinstance(index, Index)
4557
assert index.uid == 'anyUID'
4658
assert index.primary_key is None
59+
assert index.created_at is None
60+
assert index.updated_at is None
4761
assert index.config is not None
4862
assert index.http is not None
4963

@@ -57,6 +71,8 @@ def test_get_index_with_valid_uid(client):
5771
response = client.get_index(uid=common.INDEX_UID)
5872
assert isinstance(response, Index)
5973
assert response.uid == common.INDEX_UID
74+
assert isinstance(response.created_at, datetime)
75+
assert isinstance(response.updated_at, datetime)
6076

6177
def test_get_index_with_none_uid(client):
6278
"""Test raising an exception if the index UID is None."""
@@ -68,6 +84,20 @@ def test_get_index_with_wrong_uid(client):
6884
with pytest.raises(Exception):
6985
client.get_index(uid='wrongUID')
7086

87+
@pytest.mark.usefixtures("indexes_sample")
88+
def test_get_raw_index_with_valid_uid(client):
89+
response = client.get_raw_index(uid=common.INDEX_UID)
90+
assert isinstance(response, dict)
91+
assert response["uid"] == common.INDEX_UID
92+
93+
def test_get_raw_index_with_none_uid(client):
94+
with pytest.raises(Exception):
95+
client.get_raw_index(uid=None)
96+
97+
def test_get_raw_index_with_wrong_uid(client):
98+
with pytest.raises(Exception):
99+
client.get_raw_index(uid='wrongUID')
100+
71101
def test_get_or_create_index(client):
72102
"""Test get_or_create_index method."""
73103
index_1 = client.get_or_create_index(common.INDEX_UID4)
@@ -135,6 +165,8 @@ def test_update_index(client):
135165
assert isinstance(response, Index)
136166
assert index.primary_key == 'objectID'
137167
assert index.get_primary_key() == 'objectID'
168+
assert isinstance(index.created_at, datetime)
169+
assert isinstance(index.updated_at, datetime)
138170

139171
@pytest.mark.usefixtures("indexes_sample")
140172
def test_delete_index(client):

0 commit comments

Comments
 (0)