Skip to content

Commit 30c0f98

Browse files
author
Xavier Grand
committed
feat(MCM): implement MCM endpoints
1 parent dcfb1e7 commit 30c0f98

File tree

2 files changed

+235
-0
lines changed

2 files changed

+235
-0
lines changed

algoliasearch/client.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,122 @@ def update_api_key(self, key, obj,
522522
path = '/1/keys/%s' % key
523523
return self._req(False, path, 'PUT', request_options, data=obj)
524524

525+
526+
def assign_user_id(self, user_id, cluster, request_options=None):
527+
"""
528+
Assign a userID to a cluster
529+
Return an object of the form:
530+
{'updatedAt': 'XXXX'}
531+
"""
532+
if request_options is None:
533+
request_options = RequestOptions({})
534+
request_options.headers['X-Algolia-User-ID'] = user_id
535+
body = {'cluster': cluster}
536+
537+
return self._req(False, '/1/clusters/mapping', 'POST', request_options, data=body)
538+
539+
def remove_user_id(self, user_id, request_options=None):
540+
"""
541+
Remove a userID from the mapping
542+
Return an object of the form:
543+
{'deleteAt': 'XXXX'}
544+
"""
545+
if request_options is None:
546+
request_options = RequestOptions({})
547+
request_options.headers['X-Algolia-User-ID'] = user_id
548+
549+
return self._req(False, '/1/clusters/mapping', 'DELETE', request_options)
550+
551+
def list_clusters(self, request_options=None):
552+
"""
553+
List available cluster in the mapping
554+
Return an object of the form:
555+
{'clusters': [{
556+
"clusterName": "XXXX",
557+
"nbRecords": 0,
558+
"nbUserIDs": 0,
559+
"dataSize": 0
560+
}]}
561+
"""
562+
563+
return self._req(True, '/1/clusters', 'GET', request_options)
564+
565+
def get_user_id(self, user_id, request_options=None):
566+
"""
567+
Get one userID in the mapping
568+
Return an object in the form:
569+
{
570+
"userID": "XXXX",
571+
"clusterName": "XXXX",
572+
"nbRecords": 0,
573+
"dataSize": 0
574+
}
575+
"""
576+
return self._req(True, '/1/clusters/mapping/%s' % safe(user_id), 'GET', request_options)
577+
578+
def list_user_ids(self, page = 0, hits_per_page = 20, request_options=None):
579+
"""
580+
List userIDs in the mapping
581+
Return an object in the form:
582+
{
583+
"userIDs": [{
584+
"userID": "userName",
585+
"clusterName": "name",
586+
"nbRecords": 0,
587+
"dataSize": 0
588+
}],
589+
"page": 0,
590+
"hitsPerPage": 20
591+
}
592+
"""
593+
return self._req(True, '/1/clusters/mapping/', 'GET', request_options)
594+
595+
def get_top_user_id(self, request_options=None):
596+
"""
597+
Get top userID in the mapping
598+
Return an object in the form:
599+
{
600+
"topUsers": {
601+
"XXXX": [{
602+
"userID": "userName",
603+
"nbRecords": 0,
604+
"dataSize": 0
605+
}]
606+
},
607+
"page": 0,
608+
"hitsPerPage": 20
609+
}
610+
"""
611+
return self._req(True, '/1/clusters/mapping/top', 'GET', request_options)
612+
613+
def search_user_ids(self, query, cluster=None, page=None, hits_per_page=None, request_options=None):
614+
"""
615+
Search userIDs in the mapping
616+
Return an object in the form:
617+
{
618+
"hits": [{
619+
"userID": "userName",
620+
"clusterName": "name",
621+
"nbRecords": 0,
622+
"dataSize": 0
623+
}],
624+
"nbHits":0,
625+
"page": 0,
626+
"hitsPerPage": 20
627+
}
628+
"""
629+
body={}
630+
if query is not None:
631+
body["query"] = query
632+
if cluster is not None:
633+
body["cluster"] = cluster
634+
if page is not None:
635+
body["page"] = page
636+
if hits_per_page is not None:
637+
body["hitsPerPage"] = hits_per_page
638+
639+
return self._req(True, '/1/clusters/mapping/search', 'POST', request_options, data=body)
640+
525641
@deprecated
526642
def generateSecuredApiKey(self, private_api_key, tag_filters,
527643
user_token=''):

tests/test_MCM.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from __future__ import unicode_literals
4+
5+
from random import randint
6+
import time
7+
import os
8+
9+
try:
10+
import unittest2 as unittest # py26
11+
except ImportError:
12+
import unittest
13+
14+
from algoliasearch.client import Client, MAX_API_KEY_LENGTH, RequestOptions
15+
from algoliasearch.helpers import AlgoliaException
16+
17+
from .helpers import safe_index_name
18+
from .helpers import get_api_client
19+
from .helpers import FakeData, FakeSession
20+
21+
22+
class MCMTest(unittest.TestCase):
23+
"""Abstract class for all client tests."""
24+
25+
def uniq_user_id(self, name):
26+
if 'TRAVIS' not in os.environ:
27+
return name
28+
job = os.environ['TRAVIS_JOB_NUMBER']
29+
return '{0}-travis-{1}'.format(name, job)
30+
31+
@classmethod
32+
def setUpClass(cls):
33+
unittest.TestLoader().sortTestMethodsUsing = None
34+
if 'APPENGINE_RUNTIME' in os.environ:
35+
from google.appengine.api import apiproxy_stub_map
36+
from google.appengine.api import urlfetch_stub
37+
apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
38+
apiproxy_stub_map.apiproxy.RegisterStub('urlfetch', urlfetch_stub.URLFetchServiceStub())
39+
cls.client = Client(os.environ['ALGOLIA_APPLICATION_ID_MCM'],
40+
os.environ['ALGOLIA_API_KEY_MCM'])
41+
42+
def test_1_list_clusters(self):
43+
answer = self.client.list_clusters()
44+
45+
self.assertTrue(isinstance(answer, dict))
46+
self.assertTrue(isinstance(answer['clusters'], list))
47+
self.assertTrue(len(answer['clusters']) > 0)
48+
self.assertTrue(isinstance(answer['clusters'][0]['clusterName'], str))
49+
self.assertTrue(isinstance(answer['clusters'][0]['nbRecords'], int))
50+
self.assertTrue(isinstance(answer['clusters'][0]['nbUserIDs'], int))
51+
self.assertTrue(isinstance(answer['clusters'][0]['dataSize'], int))
52+
53+
def test_2_assign_user_id(self):
54+
clusterName = self.client.list_clusters()['clusters'][0]['clusterName']
55+
answer = self.client.assign_user_id(self.uniq_user_id('python-client'), clusterName)
56+
57+
self.assertTrue(isinstance(answer, dict))
58+
self.assertTrue(isinstance(answer['createdAt'], str))
59+
time.sleep(2) # Sleep to let the cluster publish the change
60+
61+
def test_3_list_user_ids(self):
62+
answer = self.client.list_user_ids()
63+
64+
65+
self.assertTrue(isinstance(answer, dict))
66+
self.assertTrue(isinstance(answer['userIDs'], list))
67+
self.assertTrue(len(answer['userIDs']) > 0)
68+
self.assertTrue(isinstance(answer['userIDs'][0]['userID'], str))
69+
self.assertTrue(isinstance(answer['userIDs'][0]['clusterName'], str))
70+
self.assertTrue(isinstance(answer['userIDs'][0]['nbRecords'], int))
71+
self.assertTrue(isinstance(answer['userIDs'][0]['dataSize'], int))
72+
73+
def test_4_get_top_user_id(self):
74+
clusterName = self.client.list_clusters()['clusters'][0]['clusterName']
75+
answer = self.client.get_top_user_id()
76+
77+
self.assertTrue(isinstance(answer, dict))
78+
self.assertTrue(isinstance(answer['topUsers'], dict))
79+
self.assertTrue(len(answer['topUsers']) > 0)
80+
self.assertTrue(isinstance(answer['topUsers'][clusterName], list))
81+
self.assertTrue(isinstance(answer['topUsers'][clusterName][0]['userID'], str))
82+
self.assertTrue(isinstance(answer['topUsers'][clusterName][0]['nbRecords'], int))
83+
self.assertTrue(isinstance(answer['topUsers'][clusterName][0]['dataSize'], int))
84+
85+
def test_5_get_user_id(self):
86+
answer = self.client.get_user_id(self.uniq_user_id('python-client'))
87+
88+
self.assertTrue(isinstance(answer, dict))
89+
self.assertTrue(isinstance(answer['userID'], str))
90+
self.assertTrue(isinstance(answer['clusterName'], str))
91+
self.assertTrue(isinstance(answer['nbRecords'], int))
92+
self.assertTrue(isinstance(answer['dataSize'], int))
93+
94+
def test_6_search_user_ids(self):
95+
clusterName = self.client.list_clusters()['clusters'][0]['clusterName']
96+
answer = self.client.search_user_ids(self.uniq_user_id('python-client'), clusterName, 0, 1000)
97+
98+
99+
self.assertTrue(isinstance(answer, dict))
100+
self.assertTrue(isinstance(answer['nbHits'], int))
101+
self.assertTrue(isinstance(answer['page'], int))
102+
self.assertTrue(isinstance(answer['hitsPerPage'], int))
103+
self.assertTrue(isinstance(answer['hits'], list))
104+
self.assertTrue(len(answer['hits']) > 0)
105+
self.assertTrue(isinstance(answer['hits'][0]['userID'], str))
106+
self.assertTrue(isinstance(answer['hits'][0]['clusterName'], str))
107+
self.assertTrue(isinstance(answer['hits'][0]['nbRecords'], int))
108+
self.assertTrue(isinstance(answer['hits'][0]['dataSize'], int))
109+
110+
def test_7_remove_user_id(self):
111+
answer = self.client.remove_user_id(self.uniq_user_id('python-client'))
112+
113+
print(answer)
114+
self.assertTrue(isinstance(answer, dict))
115+
self.assertTrue(isinstance(answer['deletedAt'], str))
116+
117+
118+
119+

0 commit comments

Comments
 (0)