Skip to content

Commit c898c82

Browse files
Merge pull request #302 from algolia/feat/MCMEndpoints
Feat/mcm endpoints
2 parents 63853df + 5dd4401 commit c898c82

File tree

4 files changed

+244
-1
lines changed

4 files changed

+244
-1
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
CHANGELOG
22

3+
2017-10-29 1.14.0
4+
* Add per-request parameters
5+
* Add multi-cluster support
6+
37
2017-01-31 1.13.0
48
* Add rules endpoints
59

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=''):

algoliasearch/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = "1.13.0"
1+
VERSION = "1.14.0"

tests/test_MCM.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
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,PY2
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+
if PY2:
42+
cls.strType = unicode
43+
else:
44+
cls.strType = str
45+
46+
def test_1_list_clusters(self):
47+
answer = self.client.list_clusters()
48+
49+
self.assertTrue(isinstance(answer, dict))
50+
self.assertTrue(isinstance(answer['clusters'], list))
51+
self.assertTrue(len(answer['clusters']) > 0)
52+
self.assertTrue(isinstance(answer['clusters'][0]['clusterName'], self.strType))
53+
self.assertTrue(isinstance(answer['clusters'][0]['nbRecords'], int))
54+
self.assertTrue(isinstance(answer['clusters'][0]['nbUserIDs'], int))
55+
self.assertTrue(isinstance(answer['clusters'][0]['dataSize'], int))
56+
57+
def test_2_assign_user_id(self):
58+
clusterName = self.client.list_clusters()['clusters'][0]['clusterName']
59+
answer = self.client.assign_user_id(self.uniq_user_id('python-client'), clusterName)
60+
61+
self.assertTrue(isinstance(answer, dict))
62+
self.assertTrue(isinstance(answer['createdAt'], self.strType))
63+
time.sleep(2) # Sleep to let the cluster publish the change
64+
65+
def test_3_list_user_ids(self):
66+
answer = self.client.list_user_ids()
67+
68+
69+
self.assertTrue(isinstance(answer, dict))
70+
self.assertTrue(isinstance(answer['userIDs'], list))
71+
self.assertTrue(len(answer['userIDs']) > 0)
72+
self.assertTrue(isinstance(answer['userIDs'][0]['userID'], self.strType))
73+
self.assertTrue(isinstance(answer['userIDs'][0]['clusterName'], self.strType))
74+
self.assertTrue(isinstance(answer['userIDs'][0]['nbRecords'], int))
75+
self.assertTrue(isinstance(answer['userIDs'][0]['dataSize'], int))
76+
77+
def test_4_get_top_user_id(self):
78+
clusterName = self.client.list_clusters()['clusters'][0]['clusterName']
79+
answer = self.client.get_top_user_id()
80+
81+
self.assertTrue(isinstance(answer, dict))
82+
self.assertTrue(isinstance(answer['topUsers'], dict))
83+
self.assertTrue(len(answer['topUsers']) > 0)
84+
self.assertTrue(isinstance(answer['topUsers'][clusterName], list))
85+
self.assertTrue(isinstance(answer['topUsers'][clusterName][0]['userID'], self.strType))
86+
self.assertTrue(isinstance(answer['topUsers'][clusterName][0]['nbRecords'], int))
87+
self.assertTrue(isinstance(answer['topUsers'][clusterName][0]['dataSize'], int))
88+
89+
def test_5_get_user_id(self):
90+
answer = self.client.get_user_id(self.uniq_user_id('python-client'))
91+
92+
self.assertTrue(isinstance(answer, dict))
93+
self.assertTrue(isinstance(answer['userID'], self.strType))
94+
self.assertTrue(isinstance(answer['clusterName'], self.strType))
95+
self.assertTrue(isinstance(answer['nbRecords'], int))
96+
self.assertTrue(isinstance(answer['dataSize'], int))
97+
98+
def test_6_search_user_ids(self):
99+
clusterName = self.client.list_clusters()['clusters'][0]['clusterName']
100+
answer = self.client.search_user_ids(self.uniq_user_id('python-client'), clusterName, 0, 1000)
101+
102+
103+
self.assertTrue(isinstance(answer, dict))
104+
self.assertTrue(isinstance(answer['nbHits'], int))
105+
self.assertTrue(isinstance(answer['page'], int))
106+
self.assertTrue(isinstance(answer['hitsPerPage'], int))
107+
self.assertTrue(isinstance(answer['hits'], list))
108+
self.assertTrue(len(answer['hits']) > 0)
109+
self.assertTrue(isinstance(answer['hits'][0]['userID'], self.strType))
110+
self.assertTrue(isinstance(answer['hits'][0]['clusterName'], self.strType))
111+
self.assertTrue(isinstance(answer['hits'][0]['nbRecords'], int))
112+
self.assertTrue(isinstance(answer['hits'][0]['dataSize'], int))
113+
114+
def test_7_remove_user_id(self):
115+
answer = self.client.remove_user_id(self.uniq_user_id('python-client'))
116+
117+
print(answer)
118+
self.assertTrue(isinstance(answer, dict))
119+
self.assertTrue(isinstance(answer['deletedAt'], self.strType))
120+
121+
122+
123+

0 commit comments

Comments
 (0)