Skip to content

Commit 34f81f7

Browse files
committed
Add key methods
1 parent e25c1de commit 34f81f7

File tree

3 files changed

+194
-4
lines changed

3 files changed

+194
-4
lines changed

meilisearch/_httprequests.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ def post(
6060
) -> Any:
6161
return self.send_request(requests.post, path, body, content_type)
6262

63+
def patch(
64+
self,
65+
path: str,
66+
body: Optional[Union[Dict[str, Any], List[Dict[str, Any]], List[str], str]] = None,
67+
content_type: Optional[str] = 'application/json',
68+
) -> Any:
69+
return self.send_request(requests.patch, path, body, content_type)
70+
6371
def put(
6472
self,
6573
path: str,

meilisearch/client.py

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,34 @@ def is_healthy(self) -> bool:
217217
return False
218218
return True
219219

220-
def get_keys(self) -> Dict[str, str]:
221-
"""Get all keys.
220+
def get_key(self, key: str) -> Dict[str, str]:
221+
"""Gets information about a specific API key.
222222
223-
Get the public and private keys.
223+
Parameters
224+
----------
225+
key:
226+
The key for which to retrieve the information.
227+
228+
Returns
229+
-------
230+
key:
231+
The API key.
232+
https://docs.meilisearch.com/reference/api/keys.html#get-key
233+
234+
Raises
235+
------
236+
MeiliSearchApiError
237+
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
238+
"""
239+
return self.http.get(f'{self.config.paths.keys}/{key}')
240+
241+
def get_keys(self) -> Dict[str, str]:
242+
"""Gets the MeiliSearch API keys.
224243
225244
Returns
226245
-------
227246
keys:
228-
Dictionary of keys and their information.
247+
API keys.
229248
https://docs.meilisearch.com/reference/api/keys.html#get-keys
230249
231250
Raises
@@ -235,6 +254,90 @@ def get_keys(self) -> Dict[str, str]:
235254
"""
236255
return self.http.get(self.config.paths.keys)
237256

257+
def create_key(
258+
self,
259+
options: Optional[Dict[str, Any]] = None
260+
) -> Dict[str, int]:
261+
"""Creates a new API key.
262+
263+
Parameters
264+
----------
265+
options:
266+
Options, the information to use in creating the key (ex: { 'actions': ['*'], 'indexes': ['movies'], 'description': 'Search Key', 'expiresAt': '22-01-01' }).
267+
An `actions`, an `indexes` and a `expiresAt` fields are mandatory,`None` should be specified for no expiration date.
268+
`actions`: A list of actions permitted for the key. ["*"] for all actions.
269+
`indexes`: A list of indexes permitted for the key. ["*"] for all indexes.
270+
Note that if an expires_at value is included it should be in UTC time.
271+
272+
Returns
273+
-------
274+
keys:
275+
The new API key.
276+
https://docs.meilisearch.com/reference/api/keys.html#get-keys
277+
278+
Raises
279+
------
280+
MeiliSearchApiError
281+
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
282+
"""
283+
if options is None:
284+
options= {}
285+
payload = {**options}
286+
return self.http.post(f'{self.config.paths.keys}', payload)
287+
288+
def udpate_key(
289+
self,
290+
key: str,
291+
options: Optional[Dict[str, Any]] = None
292+
) -> Dict[str, int]:
293+
"""Update an API key.
294+
295+
Parameters
296+
----------
297+
key:
298+
The information to use in updating the key. Note that if an expires_at value
299+
is included it should be in UTC time.
300+
options:
301+
Options, the information to use in creating the key (ex: { 'description': 'Search Key', 'expiresAt': '22-01-01' }).
302+
303+
Returns
304+
-------
305+
key:
306+
The updated API key.
307+
https://docs.meilisearch.com/reference/api/keys.html#get-keys
308+
309+
Raises
310+
------
311+
MeiliSearchApiError
312+
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
313+
"""
314+
if options is None:
315+
options= {}
316+
payload = {**options}
317+
url = f'{self.config.paths.keys}/{key}'
318+
return self.http.patch(url, payload)
319+
320+
def delete_key(self, key: str) -> Dict[str, int]:
321+
"""Deletes an API key.
322+
323+
Parameters
324+
----------
325+
key:
326+
The key to delete.
327+
328+
Returns
329+
-------
330+
keys:
331+
The Response status code. 204 signifies a successful delete.
332+
https://docs.meilisearch.com/reference/api/keys.html#get-keys
333+
334+
Raises
335+
------
336+
MeiliSearchApiError
337+
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
338+
"""
339+
return self.http.delete(f'{self.config.paths.keys}/{key}')
340+
238341
def get_version(self) -> Dict[str, str]:
239342
"""Get version MeiliSearch
240343
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import pytest
2+
from tests import common
3+
from datetime import datetime, timedelta
4+
5+
def test_get_keys_default(client):
6+
"""Tests if public and private keys have been generated and can be retrieved."""
7+
key = client.get_keys()
8+
assert isinstance(key, list)
9+
assert len(key) >= 2
10+
assert 'actions' in key[0]
11+
assert 'indexes' in key[0]
12+
assert key[0]['key'] is not None
13+
assert key[1]['key'] is not None
14+
15+
def test_get_key(client):
16+
"""Tests if a key can be retrieved."""
17+
keys = client.get_keys()
18+
key = client.get_key(keys[0]['key'])
19+
assert isinstance(key, dict)
20+
assert 'actions' in key
21+
assert 'indexes' in key
22+
assert key['createdAt'] is not None
23+
24+
def test_get_key_inexistent(client):
25+
"""Tests getting a key that does not exists."""
26+
with pytest.raises(Exception):
27+
client.get_key('No existing key')
28+
29+
def test_create_keys_default(client):
30+
"""Tests the creation of a key with no optional argument."""
31+
key = client.create_key(options={ 'actions': ['*'], 'indexes': [common.INDEX_UID], 'expiresAt': None })
32+
assert isinstance(key, dict)
33+
assert 'key' in key
34+
assert 'actions' in key
35+
assert 'indexes' in key
36+
assert key['key'] is not None
37+
assert key['expiresAt'] is None
38+
assert key['createdAt'] is not None
39+
assert key['updatedAt'] is not None
40+
assert key['key'] is not None
41+
assert key['actions'] == ['*']
42+
assert key['indexes'] == [common.INDEX_UID]
43+
44+
def test_create_keys_with_options(client):
45+
"""Tests the creation of a key with arguments."""
46+
key = client.create_key(options={ 'actions': ['*'], 'indexes': [common.INDEX_UID], 'description': 'Test key', 'expiresAt': datetime(2030, 6, 4, 21, 8, 12, 32).isoformat()[:-3]+'Z' })
47+
assert isinstance(key, dict)
48+
assert key['key'] is not None
49+
assert key['description'] == 'Test key'
50+
assert key['expiresAt'] is not None
51+
assert key['createdAt'] is not None
52+
assert key['updatedAt'] is not None
53+
assert key['actions'] == ['*']
54+
assert key['indexes'] == [common.INDEX_UID]
55+
56+
def test_create_keys_without_actions(client):
57+
"""Tests the creation of a key with missing arguments."""
58+
with pytest.raises(Exception):
59+
client.create_key(options={'indexes': [common.INDEX_UID]})
60+
61+
def test_update_keys(client):
62+
"""Tests updating a key."""
63+
key = client.create_key(options={ 'actions': ['*'], 'indexes': ['*'], 'expiresAt': None })
64+
assert key['actions'] == ['*']
65+
update_key = client.udpate_key(key=key['key'], options={ 'actions': ['search'] })
66+
assert update_key['key'] is not None
67+
assert update_key['expiresAt'] is None
68+
assert update_key['actions'] == ['search']
69+
70+
def test_delete_key(client):
71+
"""Tests deleting a key."""
72+
key = client.create_key(options={ 'actions': ['*'], 'indexes': ['*'], 'expiresAt': None })
73+
resp = client.delete_key(key['key'])
74+
assert resp.status_code == 204
75+
76+
def test_delete_key_inexisting(client):
77+
"""Tests deleting a key that does not exists."""
78+
with pytest.raises(Exception):
79+
client.delete_key('No existing key')

0 commit comments

Comments
 (0)