Skip to content
This repository was archived by the owner on Sep 28, 2023. It is now read-only.

Commit db0f1e4

Browse files
author
Andy Harris
committed
move resources to separate file
1 parent 8a51a1f commit db0f1e4

File tree

6 files changed

+314
-254
lines changed

6 files changed

+314
-254
lines changed

optimizely/__init__.py

Lines changed: 12 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -1,199 +1,16 @@
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
78
api_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)

optimizely/api_requester.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import requests
2+
3+
from optimizely.error import BadRequestError, UnauthorizedError
4+
5+
6+
class APIRequester(object):
7+
8+
@classmethod
9+
def request(cls, method, url, headers=None, data=''):
10+
# get up-to-date key and base
11+
from optimizely import api_key, api_base
12+
if api_key is None:
13+
raise UnauthorizedError('API key is not set.')
14+
15+
# add request token header
16+
headers = headers or {}
17+
headers.update({'Token': api_key})
18+
19+
# make request
20+
if str(method).upper() == 'GET':
21+
if data:
22+
return requests.get(api_base + url, headers=headers, data=data)
23+
else:
24+
return requests.get(api_base + url, headers=headers)
25+
elif str(method).upper() == 'POST':
26+
if data:
27+
return requests.post(api_base + url, headers=headers, data=data)
28+
else:
29+
return requests.post(api_base + url, headers=headers)
30+
elif str(method).upper() == 'PUT':
31+
if data:
32+
return requests.put(api_base + url, headers=headers, data=data)
33+
else:
34+
return requests.put(api_base + url, headers=headers)
35+
elif str(method).upper() == 'DELETE':
36+
if data:
37+
return requests.delete(api_base + url, headers=headers, data=data)
38+
else:
39+
return requests.delete(api_base + url, headers=headers)
40+
else:
41+
raise BadRequestError('%s is not a valid request type.' % method)

0 commit comments

Comments
 (0)