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

Commit c8f90e3

Browse files
author
Andy Harris
committed
refactor for review
1 parent 09996e9 commit c8f90e3

10 files changed

Lines changed: 66 additions & 742 deletions

File tree

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,17 @@ Usage
1010
Set your API key and you're ready to go!
1111
```python
1212
>>> import optimizely
13-
>>> optimizely.api_key = 'abcdefghijklmnopqrstuvwxyz:123456'
13+
>>> client = optimizely.Client('abcdefghijklmnopqrstuvwxyz:123456')
1414

15-
>>> projects = optimizely.Project.list()
15+
>>> projects = client.Projects.get()
1616
>>> projects
17-
[<Project object with ID: 12345>]
17+
# [<optimizely.resource.Project object at 0x000000000>, <optimizely.resource.Project object at 0x000000010>]
1818

1919
>>> my_project = projects[0]
2020
>>> my_project.project_name
21-
u'My Project'
21+
# 'My Project'
2222

23-
>>> my_project = optimizely.Project.update(12345, {'project_name': 'My Project (Updated)'})
24-
>>> my_project.project_name
25-
u'My Project (Updated)'
23+
>>> my_project.project_name = 'My Project (Updated)'
24+
>>> my_project.save()
2625

2726
```

optimizely/__init__.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
# Andy Harris <andy.harris@optimizely.com>
55

66
# Client
7-
from optimizely.client import Client
7+
from optimizely.client import *
88

99
# Resources
10-
from optimizely.resource import Project, Experiment, Result, Variation, Goal, Audience
10+
from optimizely.resource import *
1111

1212
# Errors
13-
from optimizely.error import (
14-
OptimizelyError, BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, TooManyRequestsError,
15-
ServiceUnavailableError, InvalidIDError)
13+
from optimizely.error import *

optimizely/client.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,54 @@
1+
__all__ = ['Client']
2+
13
import urlparse
24
import requests
35

46
from optimizely import error
57
from optimizely import resource
68

7-
base = 'https://www.optimizelyapis.com/experiment/v1/'
9+
BASE_URL = 'https://www.optimizelyapis.com/experiment/v1/'
810

911

1012
class Client(object):
1113
ALLOWED_REQUESTS = ['get', 'post', 'put', 'delete']
1214

13-
def __init__(self, api_key, api_base=base):
15+
def __init__(self, api_key, api_base=BASE_URL):
16+
# set API information
1417
self.api_key = api_key
1518
self.api_base = api_base
1619

17-
self.Project = resource.ResourceGenerator(client=self, resource=resource.Project)
18-
self.Experiment = resource.ResourceGenerator(client=self, resource=resource.Experiment)
19-
self.Variation = resource.ResourceGenerator(client=self, resource=resource.Variation)
20-
self.Goal = resource.ResourceGenerator(client=self, resource=resource.Goal)
21-
self.Audience = resource.ResourceGenerator(client=self, resource=resource.Audience)
22-
23-
def request(self, method, url_parts, headers=None, data=''):
20+
# instantiate resource generators for the relevant API resources
21+
self.Projects = resource.ResourceGenerator(client=self, resource=resource.Project)
22+
self.Experiments = resource.ResourceGenerator(client=self, resource=resource.Experiment)
23+
self.Variations = resource.ResourceGenerator(client=self, resource=resource.Variation)
24+
self.Goals = resource.ResourceGenerator(client=self, resource=resource.Goal)
25+
self.Audiences = resource.ResourceGenerator(client=self, resource=resource.Audience)
26+
self.Dimensions = resource.ResourceGenerator(client=self, resource=resource.Dimension)
27+
self.Schedules = resource.ResourceGenerator(client=self, resource=resource.Schedule)
2428

29+
def request(self, method, url_parts, headers=None, data=None):
30+
""" Method for making requests to the Optimizely API
31+
"""
2532
if method in self.ALLOWED_REQUESTS:
2633
# add request token header
2734
headers = headers or {}
2835
headers.update({'Token': self.api_key})
2936

3037
# make request and return parsed response
31-
return self.parse_response(getattr(requests, method)(urlparse.urljoin(
32-
self.api_base, '/'.join([str(url_part) for url_part in url_parts])), headers=headers, data=data))
38+
url = urlparse.urljoin(self.api_base, '/'.join([str(url_part) for url_part in url_parts]))
39+
return self.parse_response(getattr(requests, method)(url, headers=headers, data=data))
3340
else:
34-
raise BadRequestError('%s is not a valid request type.' % method)
41+
raise error.BadRequestError('%s is not a valid request type.' % method)
3542

3643
@staticmethod
3744
def parse_response(resp):
45+
""" Method to parse response from the Optimizely API and return results as JSON. Errors are thrown for various
46+
errors that the API can throw.
47+
"""
3848
if resp.status_code in [200, 201, 202]:
3949
return resp.json()
4050
elif resp.status_code == 204:
41-
return
51+
return None
4252
elif resp.status_code == 400:
4353
raise error.BadRequestError(resp.json().get('message'))
4454
elif resp.status_code == 401:

optimizely/error.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
__all__ = [
2+
'OptimizelyError', 'BadRequestError', 'UnauthorizedError', 'ForbiddenError', 'NotFoundError',
3+
'TooManyRequestsError', 'ServiceUnavailableError', 'InvalidIDError']
4+
5+
16
class OptimizelyError(Exception):
27
""" General exception for all Optimizely Experiments API related issues."""
38
pass

optimizely/resource.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
__all__ = ['Project', 'Experiment', 'Result', 'Variation', 'Goal', 'Audience']
2+
13
import json
24
import urllib
35

@@ -26,7 +28,7 @@ def get(self, optimizely_ids=None):
2628
return response_list
2729

2830
def create(self, data):
29-
return self.resource.create(data, client=self.client)
31+
return self.resource.create(data, self.client)
3032

3133
def update(self, rid, data):
3234
return self.resource.update(rid, data, self.client)
@@ -112,7 +114,7 @@ class UpdatableObject(APIObject):
112114
editable_fields = []
113115

114116
def save(self):
115-
return self._refresh_from(self.update(self.id, self.__dict__, self.client).__dict__)
117+
self._refresh_from(self.update(self.id, self.__dict__, self.client).__dict__)
116118

117119
@classmethod
118120
def update(cls, rid, data, client):
@@ -130,7 +132,7 @@ def update(cls, rid, data, client):
130132
class DeletableObject(APIObject):
131133

132134
def delete(self):
133-
return self.client.request('delete', [self.class_url(), self.id])
135+
self.client.request('delete', [self.class_url(), self.id])
134136

135137

136138
class Project(ListableObject, CreatableObject, UpdatableObject):
@@ -146,6 +148,12 @@ def experiments(self):
146148
def goals(self):
147149
return self.get_child_objects(Goal)
148150

151+
def audiences(self):
152+
return self.get_child_objects(Audience)
153+
154+
def dimensions(self):
155+
return self.get_child_objects(Dimension)
156+
149157

150158
class Experiment(CreatableChildObject, UpdatableObject, DeletableObject):
151159

@@ -166,8 +174,8 @@ def results(self):
166174
def variations(self):
167175
return self.get_child_objects(Variation)
168176

169-
def audiences(self):
170-
return self.get_child_objects(Audience)
177+
def schedules(self):
178+
return self.get_child_objects(Schedule)
171179

172180
def add_goal(self, gid):
173181
goal = Goal(self.client, gid)
@@ -220,3 +228,18 @@ class Audience(CreatableChildObject, UpdatableObject):
220228
'description',
221229
'conditions',
222230
'segmentation']
231+
232+
233+
class Dimension(CreatableChildObject, UpdatableObject, DeletableObject):
234+
235+
parent_resource = Project
236+
editable_fields = ['name',
237+
'client_api_name',
238+
'description']
239+
240+
241+
class Schedule(CreatableChildObject, UpdatableObject, DeletableObject):
242+
243+
parent_resource = Experiment
244+
editable_fields = ['start_time',
245+
'stop_time']

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
optimizely
2+
mock
23
requests>2.4.1

tests/README.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

tests/__init__.py

Whitespace-only changes.

tests/api_mock.py

Lines changed: 0 additions & 160 deletions
This file was deleted.

0 commit comments

Comments
 (0)