Skip to content

Commit 085bbec

Browse files
bors[bot]meili-botcurquizaalallema
authored
Merge #472
472: Changes related to the next Meilisearch release (v0.28.0) r=alallema a=meili-bot Related to this issue: meilisearch/integration-guides#205 This PR: - gathers the changes related to the next Meilisearch release (v0.28.0) so that this package is ready when the official release is out. - should pass the tests against the [latest pre-release of Meilisearch](https://github.com/meilisearch/meilisearch/releases). - might eventually contain test failures until the Meilisearch v0.28.0 is out. ⚠️ This PR should NOT be merged until the next release of Meilisearch (v0.28.0) is out. _This PR is auto-generated for the [pre-release week](https://github.com/meilisearch/integration-guides/blob/master/guides/pre-release-week.md) purpose._ Done: - #474 - #475 - #476 - #477 - #478 - #479 - #481 - #484 - #489 Co-authored-by: meili-bot <[email protected]> Co-authored-by: Clémentine Urquizar <[email protected]> Co-authored-by: Amélie <[email protected]> Co-authored-by: alallema <[email protected]>
2 parents bdeb59b + 7557aee commit 085bbec

27 files changed

+418
-351
lines changed

.code-samples.meilisearch.yaml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ search_parameter_guide_highlight_tag_1: |-
282282
})
283283
search_parameter_guide_matches_1: |-
284284
client.index('movies').search('winter feast', {
285-
'matches': 'true'
285+
'showMatchesPosition': 'true'
286286
})
287287
settings_guide_synonyms_1: |-
288288
client.index('tops').update_settings({
@@ -491,16 +491,14 @@ faceted_search_filter_1: |-
491491
})
492492
faceted_search_facets_distribution_1: |-
493493
client.index('movies').search('Batman', {
494-
'facetsDistribution': ['genres']
494+
'facets': ['genres']
495495
})
496496
faceted_search_walkthrough_filter_1: |-
497497
client.index('movies').search('thriller', {
498498
'filter': [['genres = Horror', 'genres = Mystery'], 'director = "Jordan Peele"']
499499
})
500500
post_dump_1: |-
501501
client.create_dump()
502-
get_dump_status_1: |-
503-
client.get_dump_status('20201101-110357260')
504502
phrase_search_1: |-
505503
client.index('movies').search('"african american" horror')
506504
sorting_guide_update_sortable_attributes_1: |-
@@ -591,14 +589,15 @@ authorization_header_1: |-
591589
client = Client('http://127.0.0.1:7700', 'masterKey')
592590
client.get_keys()
593591
tenant_token_guide_generate_sdk_1: |-
592+
uid = '85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76';
594593
api_key = 'B5KdX2MY2jV6EXfUs6scSfmC...'
595594
expires_at = datetime(2025, 12, 20)
596595
search_rules = {
597596
'patient_medical_records': {
598597
'filter': 'user_id = 1'
599598
}
600599
}
601-
token = client.generate_tenant_token(search_rules=search_rules, api_key=api_key, expires_at=expires_at)
600+
token = client.generate_tenant_token(api_key_uid=uid, search_rules=search_rules, api_key=api_key, expires_at=expires_at)
602601
tenant_token_guide_search_sdk_1: |-
603602
front_end_client = Client('http://127.0.0.1:7700', token)
604603
front_end_client.index('patient_medical_records').search('blood test')

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,15 @@ index.search(
189189
],
190190
"offset": 0,
191191
"limit": 20,
192-
"nbHits": 1,
192+
"estimatedTotalHits": 1,
193193
"processingTimeMs": 0,
194194
"query": "wonder"
195195
}
196196
```
197197

198198
## 🤖 Compatibility with Meilisearch
199199

200-
This package only guarantees the compatibility with the [version v0.27.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.27.0).
200+
This package only guarantees the compatibility with the [version v0.28.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.28.0).
201201

202202
## 💡 Learn More
203203

meilisearch/client.py

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import re
12
import base64
23
import hashlib
34
import hmac
45
import json
56
import datetime
7+
from urllib import parse
68
from typing import Any, Dict, List, Optional, Union
79
from meilisearch.index import Index
810
from meilisearch.config import Config
@@ -78,46 +80,64 @@ def delete_index(self, uid: str) -> Dict[str, Any]:
7880

7981
return self.http.delete(f'{self.config.paths.index}/{uid}')
8082

81-
def get_indexes(self) -> List[Index]:
83+
def get_indexes(self, parameters: Optional[Dict[str, Any]] = None) -> Dict[str, List[Index]]:
8284
"""Get all indexes.
8385
86+
Parameters
87+
----------
88+
parameters (optional):
89+
parameters accepted by the get indexes route: https://docs.meilisearch.com/reference/api/indexes.html#list-all-indexes
90+
8491
Returns
8592
-------
8693
indexes:
87-
List of Index instances.
94+
Dictionary with limit, offset, total and results a list of Index instances.
8895
8996
Raises
9097
------
9198
MeiliSearchApiError
9299
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
93100
"""
94-
response = self.http.get(self.config.paths.index)
95-
96-
return [
97-
Index(
98-
self.config,
99-
index["uid"],
100-
index["primaryKey"],
101-
index["createdAt"],
102-
index["updatedAt"],
103-
)
104-
for index in response
105-
]
106-
107-
def get_raw_indexes(self) -> List[Dict[str, Any]]:
101+
if parameters is None:
102+
parameters = {}
103+
response = self.http.get(
104+
f'{self.config.paths.index}?{parse.urlencode(parameters)}'
105+
)
106+
response['results'] = [
107+
Index(
108+
self.config,
109+
index["uid"],
110+
index["primaryKey"],
111+
index["createdAt"],
112+
index["updatedAt"],
113+
)
114+
for index in response['results']
115+
]
116+
return response
117+
118+
def get_raw_indexes(self, parameters: Optional[Dict[str, Any]] = None) -> List[Dict[str, Any]]:
108119
"""Get all indexes in dictionary format.
109120
121+
Parameters
122+
----------
123+
parameters (optional):
124+
parameters accepted by the get indexes route: https://docs.meilisearch.com/reference/api/indexes.html#list-all-indexes
125+
110126
Returns
111127
-------
112128
indexes:
113-
List of indexes in dictionary format. (e.g [{ 'uid': 'movies' 'primaryKey': 'objectID' }])
129+
Dictionary with limit, offset, total and results a list of indexes in dictionary format. (e.g [{ 'uid': 'movies' 'primaryKey': 'objectID' }])
114130
115131
Raises
116132
------
117133
MeiliSearchApiError
118134
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
119135
"""
120-
return self.http.get(self.config.paths.index)
136+
if parameters is None:
137+
parameters = {}
138+
return self.http.get(
139+
f'{self.config.paths.index}?{parse.urlencode(parameters)}'
140+
)
121141

122142
def get_index(self, uid: str) -> Index:
123143
"""Get the index.
@@ -221,13 +241,13 @@ def is_healthy(self) -> bool:
221241
return False
222242
return True
223243

224-
def get_key(self, key: str) -> Dict[str, Any]:
244+
def get_key(self, key_or_uid: str) -> Dict[str, Any]:
225245
"""Gets information about a specific API key.
226246
227247
Parameters
228248
----------
229-
key:
230-
The key for which to retrieve the information.
249+
key_or_uid:
250+
The key or the uid for which to retrieve the information.
231251
232252
Returns
233253
-------
@@ -240,23 +260,32 @@ def get_key(self, key: str) -> Dict[str, Any]:
240260
MeiliSearchApiError
241261
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
242262
"""
243-
return self.http.get(f'{self.config.paths.keys}/{key}')
263+
return self.http.get(f'{self.config.paths.keys}/{key_or_uid}')
244264

245-
def get_keys(self) -> Dict[str, Any]:
265+
def get_keys(self, parameters: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
246266
"""Gets the Meilisearch API keys.
247267
268+
Parameters
269+
----------
270+
parameters (optional):
271+
parameters accepted by the get keys route: https://docs.meilisearch.com/reference/api/keys.html#get-all-keys
272+
248273
Returns
249274
-------
250275
keys:
251-
API keys.
276+
Dictionary with limit, offset, total and results a list of dictionaries containing the key information.
252277
https://docs.meilisearch.com/reference/api/keys.html#get-keys
253278
254279
Raises
255280
------
256281
MeiliSearchApiError
257282
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
258283
"""
259-
return self.http.get(self.config.paths.keys)
284+
if parameters is None:
285+
parameters = {}
286+
return self.http.get(
287+
f'{self.config.paths.keys}?{parse.urlencode(parameters)}'
288+
)
260289

261290
def create_key(
262291
self,
@@ -288,7 +317,7 @@ def create_key(
288317

289318
def update_key(
290319
self,
291-
key: str,
320+
key_or_uid: str,
292321
options: Dict[str, Any]
293322
) -> Dict[str, Any]:
294323
"""Update an API key.
@@ -297,7 +326,7 @@ def update_key(
297326
298327
----------
299328
key:
300-
The key for which to update the information.
329+
The key or the uid of the key for which to update the information.
301330
options:
302331
The information to use in creating the key (ex: { 'description': 'Search Key', 'expiresAt': '22-01-01' }). Note that if an
303332
expires_at value is included it should be in UTC time.
@@ -313,16 +342,16 @@ def update_key(
313342
MeiliSearchApiError
314343
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
315344
"""
316-
url = f'{self.config.paths.keys}/{key}'
345+
url = f'{self.config.paths.keys}/{key_or_uid}'
317346
return self.http.patch(url, options)
318347

319-
def delete_key(self, key: str) -> Dict[str, int]:
348+
def delete_key(self, key_or_uid: str) -> Dict[str, int]:
320349
"""Deletes an API key.
321350
322351
Parameters
323352
----------
324353
key:
325-
The key to delete.
354+
The key or the uid of the key to delete.
326355
327356
Returns
328357
-------
@@ -335,7 +364,7 @@ def delete_key(self, key: str) -> Dict[str, int]:
335364
MeiliSearchApiError
336365
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
337366
"""
338-
return self.http.delete(f'{self.config.paths.keys}/{key}')
367+
return self.http.delete(f'{self.config.paths.keys}/{key_or_uid}')
339368

340369
def get_version(self) -> Dict[str, str]:
341370
"""Get version Meilisearch
@@ -383,43 +412,26 @@ def create_dump(self) -> Dict[str, str]:
383412
"""
384413
return self.http.post(self.config.paths.dumps)
385414

386-
def get_dump_status(self, uid: str) -> Dict[str, str]:
387-
"""Retrieve the status of a Meilisearch dump creation.
415+
def get_tasks(self, parameters: Optional[Dict[str, Any]] = None) -> Dict[str, List[Dict[str, Any]]]:
416+
"""Get all tasks.
388417
389418
Parameters
390419
----------
391-
uid:
392-
UID of the dump.
393-
394-
Returns
395-
-------
396-
Dump status:
397-
Information about the dump status.
398-
https://docs.meilisearch.com/reference/api/dump.html#get-dump-status
399-
400-
Raises
401-
------
402-
MeiliSearchApiError
403-
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
404-
"""
405-
return self.http.get(
406-
self.config.paths.dumps + '/' + str(uid) + '/status'
407-
)
408-
409-
def get_tasks(self) -> Dict[str, List[Dict[str, Any]]]:
410-
"""Get all tasks.
420+
parameters (optional):
421+
parameters accepted by the get tasks route: https://docs.meilisearch.com/reference/api/tasks.html#get-all-tasks.
422+
`indexUid` should be set as a List.
411423
412424
Returns
413425
-------
414426
task:
415-
Dictionary containing a list of all enqueued, processing, succeeded or failed tasks.
427+
Dictionary with limit, from, next and results containing a list of all enqueued, processing, succeeded or failed tasks.
416428
417429
Raises
418430
------
419431
MeiliSearchApiError
420432
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
421433
"""
422-
return get_tasks(self.config)
434+
return get_tasks(self.config, parameters=parameters)
423435

424436
def get_task(self, uid: int) -> Dict[str, Any]:
425437
"""Get one task.
@@ -471,6 +483,7 @@ def wait_for_task(
471483

472484
def generate_tenant_token(
473485
self,
486+
api_key_uid: str,
474487
search_rules: Union[Dict[str, Any], List[str]],
475488
*,
476489
expires_at: Optional[datetime.datetime] = None,
@@ -480,6 +493,8 @@ def generate_tenant_token(
480493
481494
Parameters
482495
----------
496+
api_key_uid:
497+
The uid of the API key used as issuer of the token.
483498
search_rules:
484499
A Dictionary or list of string which contains the rules to be enforced at search time for all or specific
485500
accessible indexes for the signing API Key.
@@ -499,6 +514,8 @@ def generate_tenant_token(
499514
# Validate all fields
500515
if api_key == '' or api_key is None and self.config.api_key is None:
501516
raise Exception('An api key is required in the client or should be passed as an argument.')
517+
if api_key_uid == '' or api_key_uid is None or self._valid_uuid(api_key_uid) is False:
518+
raise Exception('An uid is required and must comply to the uuid4 format.')
502519
if not search_rules or search_rules == ['']:
503520
raise Exception('The search_rules field is mandatory and should be defined.')
504521
if expires_at and expires_at < datetime.datetime.utcnow():
@@ -514,7 +531,7 @@ def generate_tenant_token(
514531

515532
# Add the required fields to the payload
516533
payload = {
517-
'apiKeyPrefix': api_key[0:8],
534+
'apiKeyUid': api_key_uid,
518535
'searchRules': search_rules,
519536
'exp': int(datetime.datetime.timestamp(expires_at)) if expires_at is not None else None
520537
}
@@ -540,3 +557,11 @@ def _base64url_encode(
540557
data: bytes
541558
) -> str:
542559
return base64.urlsafe_b64encode(data).decode('utf-8').replace('=','')
560+
561+
@staticmethod
562+
def _valid_uuid(
563+
uuid: str
564+
) -> bool:
565+
uuid4hex = re.compile(r'^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}', re.I)
566+
match = uuid4hex.match(uuid)
567+
return bool(match)

0 commit comments

Comments
 (0)