1- import json
2- import requests
1+ # Optimizely Python bindings
2+ # API docs at http://developers.optimizely.com/
3+ # Authors:
4+ # Andy Harris <andy.harris@optimizely.com>
35
4- from errors import *
5-
6- api_key = ''
6+ # configuration variables
7+ api_key = None
78api_base = 'https://www.optimizelyapis.com/experiment/v1/'
89
10+ # Resources
11+ from optimizely .resource import Project , Experiment , Result , Variation , Goal , Audience
912
10- class APIResource (object ):
11- endpoint = ''
12-
13- def __init__ (self , param ):
14- if type (param ) == int :
15- self .__init__ (self .get (param ).__dict__ )
16- elif type (param ) == dict :
17- for (k , v ) in param .iteritems ():
18- self .__setattr__ (k , v )
19- else :
20- raise ValueError ('%s can only be initiated with a dict.' % self .__class__ .__name__ )
21-
22- def __repr__ (self ):
23- if hasattr (self , 'id' ):
24- return '<%s object with ID: %s>' % (self .__class__ .__name__ , self .id )
25- else :
26- return '<%s object without ID>' % self .__class__ .__name__
27-
28-
29- @classmethod
30- def from_api_response (cls , r ):
31- if r .status_code in [200 , 201 , 202 ]:
32- if type (r .json ()) == list :
33- return [cls (resource ) for resource in r .json ()]
34- else :
35- return cls (r .json ())
36- elif r .status_code == 204 :
37- return
38- elif r .status_code == 400 :
39- raise BadRequestError (r .json ().get ('message' ))
40- elif r .status_code == 401 :
41- raise UnauthorizedError (r .json ().get ('message' ))
42- elif r .status_code == 403 :
43- raise ForbiddenError (r .json ().get ('message' ))
44- elif r .status_code == 404 :
45- raise NotFoundError (r .json ().get ('message' ))
46- elif r .status_code == 429 :
47- raise TooManyRequestsError (r .json ().get ('message' ))
48- elif r .status_code == 503 :
49- raise ServiceUnavailableError (r .json ().get ('message' ))
50- else :
51- raise OptimizelyError (r .text )
52-
53- @classmethod
54- def list (cls ):
55- return cls .from_api_response (requests .get (api_base + cls .endpoint , headers = {'Token' : api_key }))
56-
57- @classmethod
58- def get (cls , pid ):
59- return cls .from_api_response (requests .get (api_base + cls .endpoint + str (pid ), headers = {'Token' : api_key }))
60-
61- @classmethod
62- def create (cls , data ):
63- return cls .from_api_response (requests .post (api_base + cls .endpoint , data = json .dumps (data ),
64- headers = {'Token' : api_key , 'Content-Type' : 'application/json' }))
65-
66- @classmethod
67- def update (cls , rid , data ):
68- return cls .from_api_response (requests .put (api_base + cls .endpoint + str (rid ), data = json .dumps (data ),
69- headers = {'Token' : api_key , 'Content-Type' : 'application/json' }))
70-
71- @classmethod
72- def delete (cls , pid ):
73- return cls .from_api_response (requests .delete (api_base + cls .endpoint + str (pid ), headers = {'Token' : api_key }))
74-
75-
76- class Project (APIResource ):
77- endpoint = 'projects/'
78-
79- @classmethod
80- def delete (cls , pid ):
81- raise NotImplementedError ('Projects may not be deleted through the API.' )
82-
83- def experiments (self ):
84- if not hasattr (self , 'id' ):
85- raise InvalidIDError ('Project is missing its ID.' )
86- return Experiment .from_api_response (requests .get (api_base + self .endpoint + str (self .id ) + '/experiments' ,
87- headers = {'Token' : api_key }))
88-
89- def audiences (self ):
90- if not hasattr (self , 'id' ):
91- raise InvalidIDError ('Project is missing its ID.' )
92- return Audience .from_api_response (requests .get (api_base + self .endpoint + str (self .id ) + '/audiences' ,
93- headers = {'Token' : api_key }))
94-
95-
96- class Experiment (APIResource ):
97- endpoint = 'experiments/'
98-
99- @classmethod
100- def list (cls ):
101- raise NotImplementedError ('There is no method to list all experiments. '
102- 'Try using Project.experiments() instead.' )
103-
104- @classmethod
105- def create (cls , data ):
106- return cls .from_api_response (requests .post (api_base + 'projects/' + str (data ['project_id' ]) + '/' +
107- cls .endpoint , data = json .dumps (data ),
108- headers = {'Token' : api_key , 'Content-Type' : 'application/json' }))
109-
110- def results (self ):
111- return Result .from_api_response (requests .get (api_base + self .endpoint + str (self .id ) + '/results' ,
112- headers = {'Token' : api_key }))
113-
114- def variations (self ):
115- return Variation .from_api_response (requests .get (api_base + self .endpoint + str (self .id ) + '/variations' ,
116- headers = {'Token' : api_key }))
117-
118- def add_goal (self , gid ):
119- goal = Goal .get (gid )
120- experiment_ids = set (goal .experiment_ids )
121- experiment_ids .add (self .id )
122- return Goal .update (goal .id , {'experiment_ids' : list (experiment_ids )})
123-
124- def remove_goal (self , gid ):
125- goal = Goal .get (gid )
126- experiment_ids = set (goal .experiment_ids )
127- experiment_ids .remove (self .id )
128- return Goal .update (goal .id , {'experiment_ids' : list (experiment_ids )})
129-
130-
131- class Result (APIResource ):
132- def __repr__ (self ):
133- return '<%s object>' % self .__class__ .__name__
134-
135- @classmethod
136- def list (cls ):
137- raise NotImplementedError ('There is no method to list all results. Try using Experiment.results() instead.' )
138-
139- @classmethod
140- def get (cls , pid ):
141- raise NotImplementedError ('There is no method to get a single result.' )
142-
143- @classmethod
144- def create (cls , data ):
145- raise NotImplementedError ('There is no method to create a result.' )
146-
147- @classmethod
148- def update (cls , pid , data ):
149- raise NotImplementedError ('There is no method to update a result.' )
150-
151- @classmethod
152- def delete (cls , pid ):
153- raise NotImplementedError ('There is no method to delete a result.' )
154-
155-
156- class Variation (APIResource ):
157- endpoint = 'variations/'
158-
159- @classmethod
160- def list (cls ):
161- raise NotImplementedError ('There is no method to list all results. Try using Experiment.variations() instead.' )
162-
163- @classmethod
164- def create (cls , data ):
165- return cls .from_api_response (requests .post (api_base + 'experiments/' + str (data ['experiment_id' ]) + '/' +
166- cls .endpoint , data = json .dumps (data ),
167- headers = {'Token' : api_key , 'Content-Type' : 'application/json' }))
168-
169-
170- class Goal (APIResource ):
171- endpoint = 'goals/'
172-
173- @classmethod
174- def list (cls ):
175- raise NotImplementedError ('There is no method to list all goals.' )
176-
177- @classmethod
178- def create (cls , data ):
179- return cls .from_api_response (requests .post (api_base + 'projects/' + str (data ['project_id' ]) + '/' +
180- cls .endpoint , data = json .dumps (data ),
181- headers = {'Token' : api_key , 'Content-Type' : 'application/json' }))
182-
183-
184- class Audience (APIResource ):
185- endpoint = 'audiences/'
186-
187- @classmethod
188- def list (cls ):
189- raise NotImplementedError ('There is no method to list all results. Try using Experiment.variations() instead.' )
190-
191- @classmethod
192- def create (cls , data ):
193- return cls .from_api_response (requests .post (api_base + 'projects/' + str (data ['project_id' ]) + '/' +
194- cls .endpoint , data = json .dumps (data ),
195- headers = {'Token' : api_key , 'Content-Type' : 'application/json' }))
196-
197- @classmethod
198- def delete (cls , pid ):
199- raise NotImplementedError ('Audiences may not be deleted through the API.' )
13+ # Errors
14+ from optimizely .error import (
15+ OptimizelyError , BadRequestError , UnauthorizedError , ForbiddenError , NotFoundError , TooManyRequestsError ,
16+ ServiceUnavailableError , InvalidIDError )
0 commit comments