Skip to content

Commit 742596e

Browse files
authored
Merge pull request #21 from flaker/API-3187_assorted_fixes
API 3187 updates to the Python API client
2 parents ec8c8ae + 95862bb commit 742596e

File tree

4 files changed

+67
-100
lines changed

4 files changed

+67
-100
lines changed

History.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Replaced: urllib2 with requests package
44
* Replaced: oauth2 with requests_oauthlib package
55
* Added: optional timeout parameter
6+
* Removed: support for Python 2.4/2.5
67

78
0.4.0 / 2013-07-23
89
==================

README.md

+5-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
A small class to help connect to the OpenX Enterprise API. As of version 0.5.0 it uses
44
[requests_oauthlib](https://github.com/requests/requests-oauthlib) instead of oauth2.
55

6-
It currently supports Python 2.4 - 2.7, with 3.x support coming in the future.
6+
It currently supports Python 2.6 - 2.7, with 3.x support coming in the future.
77

88
As of version 0.4.0, ox3apiclient supports API v2. If your instance is v2,
99
set the api_path option to "/ox/4.0".
@@ -33,7 +33,7 @@ order = {
3333
'status': 'Active',
3434
'name': 'OX3APIClient Object Creation Test',
3535
'account_uid': accounts['objects'][0]['account_uid'],
36-
'start_date': '2015-06-01 00:00:00'}
36+
'start_date': '2016-06-01 00:00:00'}
3737

3838
new_order = ox.post('/order', data=order)
3939

@@ -50,17 +50,12 @@ ox3apiclient is currently unavailable at [PyPi](http://pypi.python.org/pypi) so
5050
````
5151
$ git clone https://github.com/openx/OX3-Python-API-Client.git
5252
````
53-
Install requests and requests_oauthlib from [PyPi](http://pypi.python.org/pypi) with [pip](http://www.pip-installer.org/en/latest/index.html)
54-
````
55-
$ pip install requests requests_oauthlib
56-
````
5753

58-
Note that Python 2.4 and 2.5 support requires simplejson. You will need
59-
simplejson 2.1.0 specifically for Python 2.4. You can install this version with:
54+
Install the downloaded library:
6055
````
61-
$ pip install simplejson==2.1.0
56+
python setup.py install
6257
````
63-
58+
this will install the current dependencies.
6459

6560
## Authentication
6661

ox3apiclient/__init__.py

+36-65
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,12 @@
66
import mimetypes
77
from pprint import pformat
88
import random
9-
10-
# json module is not supported in versions of Python < 2.6 so try to load the
11-
# simplejson module instead. Note that as of simplejson v2.1.1, Python 2.4
12-
# support was dropped. You will need to look for v2.1.0 specifically for
13-
# Python 2.4 support.
14-
import sys
15-
major_py_version = sys.version_info[0]
16-
minor_py_version = sys.version_info[1]
17-
if major_py_version == 2 and minor_py_version < 6:
18-
import simplejson as json
19-
else:
20-
import json
9+
import json
10+
from urlparse import parse_qs, urlparse
2111

2212
import requests
2313
from requests_oauthlib import OAuth1
2414

25-
# parse_qs is in the urlparse module as of 2.6, but in cgi in earlier versions.
26-
if major_py_version == 2 and minor_py_version > 5:
27-
from urlparse import parse_qs
28-
else:
29-
from cgi import parse_qs
30-
31-
from urlparse import urlparse
32-
3315
__version__ = '0.5.0'
3416

3517
REQUEST_TOKEN_URL = 'https://sso.openx.com/api/index/initiate'
@@ -62,20 +44,19 @@ class Client(object):
6244
6345
"""
6446

65-
6647
def __init__(self, domain, realm, consumer_key, consumer_secret,
67-
callback_url='oob',
68-
scheme='http',
69-
request_token_url=REQUEST_TOKEN_URL,
70-
access_token_url=ACCESS_TOKEN_URL,
71-
authorization_url=AUTHORIZATION_URL,
72-
api_path=API_PATH_V1,
73-
email=None,
74-
password=None,
75-
http_proxy=None,
76-
https_proxy=None,
77-
headers=None,
78-
timeout=None):
48+
callback_url='oob',
49+
scheme='http',
50+
request_token_url=REQUEST_TOKEN_URL,
51+
access_token_url=ACCESS_TOKEN_URL,
52+
authorization_url=AUTHORIZATION_URL,
53+
api_path=API_PATH_V1,
54+
email=None,
55+
password=None,
56+
http_proxy=None,
57+
https_proxy=None,
58+
headers=None,
59+
timeout=None):
7960
"""
8061
8162
domain -- Your UI domain. The API is accessed off this domain.
@@ -97,7 +78,7 @@ def __init__(self, domain, realm, consumer_key, consumer_secret,
9778
self.consumer_key = consumer_key
9879
self.consumer_secret = consumer_secret
9980
self.callback_url = callback_url
100-
self.scheme=scheme
81+
self.scheme = scheme
10182
self.request_token_url = request_token_url
10283
self.access_token_url = access_token_url
10384
self.authorization_url = authorization_url
@@ -129,7 +110,6 @@ def __init__(self, domain, realm, consumer_key, consumer_secret,
129110

130111
self.logger = logging.getLogger(__name__)
131112

132-
133113
def log_request(self, response):
134114
self.logger.debug('====={0:=<45}'.format('OX3 api call started'))
135115
self.logger.debug("%s %s" % (response.request.method, response.request.url))
@@ -144,11 +124,10 @@ def log_request(self, response):
144124
self.logger.debug('====={0:=<45}'.format('OX3 api call response body'))
145125
try:
146126
self.logger.debug(pformat(json.loads(response.content)))
147-
except:
127+
except ValueError:
148128
self.logger.debug("%s" % response.content)
149129
self.logger.debug('====={0:=<45}'.format('OX3 api call finished'))
150130

151-
152131
def request(self, url, method='GET', headers=None, data=None, sign=False,
153132
send_json=False):
154133
"""Helper method to make a (optionally OAuth signed) HTTP request."""
@@ -264,7 +243,6 @@ def validate_session(self):
264243
rest={})
265244
self._session.cookies.set_cookie(cookie)
266245

267-
268246
# v2 doesn't need this extra step, just the cookie:
269247
if self.api_path == API_PATH_V1:
270248
response = self._session.put(url=self._resolve_url('/a/session/validate'), timeout=self.timeout)
@@ -321,24 +299,31 @@ def _resolve_url(self, url):
321299

322300
# If there is no scheme specified we create a fully qualified URL.
323301
if not parse_res[0]:
324-
url ='%s://%s%s%s' % (self.scheme, self.domain, self.api_path,
325-
parse_res[2])
302+
url = '%s://%s%s%s' % (self.scheme, self.domain, self.api_path,
303+
parse_res[2])
326304
if parse_res[4]:
327305
url = url + '?' + parse_res[4]
328306

329307
return url
330308

309+
def _response_value(self, response):
310+
""" Utility method. Returns decoded json. If the response content cannot be decoded, then
311+
the content is returned.
312+
313+
"""
314+
try:
315+
return response.json()
316+
except ValueError:
317+
return response.content
318+
331319
def get(self, url):
332320
"""Issue a GET request to the given URL or API shorthand
333321
334322
"""
335323
response = self._session.get(self._resolve_url(url), timeout=self.timeout)
336324
self.log_request(response)
337325
response.raise_for_status()
338-
try:
339-
return response.json()
340-
except:
341-
return response.content
326+
return self._response_value(response)
342327

343328
def options(self, url):
344329
"""Send a request with HTTP method OPTIONS to the given
@@ -350,10 +335,7 @@ def options(self, url):
350335
response = self._session.options(self._resolve_url(url), timeout=self.timeout)
351336
self.log_request(response)
352337
response.raise_for_status()
353-
try:
354-
return response.json()
355-
except:
356-
return response.content
338+
return self._response_value(response)
357339

358340
def put(self, url, data=None):
359341
"""Issue a PUT request to url (either a full URL or API
@@ -366,10 +348,7 @@ def put(self, url, data=None):
366348
response = self._session.put(self._resolve_url(url), data=data, timeout=self.timeout)
367349
self.log_request(response)
368350
response.raise_for_status()
369-
try:
370-
return response.json()
371-
except:
372-
return response.content
351+
return self._response_value(response)
373352

374353
def post(self, url, data=None):
375354
"""Issue a POST request to url (either a full URL or API
@@ -382,10 +361,7 @@ def post(self, url, data=None):
382361
response = self._session.post(self._resolve_url(url), data=data, timeout=self.timeout)
383362
self.log_request(response)
384363
response.raise_for_status()
385-
try:
386-
return response.json()
387-
except:
388-
return response.content
364+
return self._response_value(response)
389365

390366
def delete(self, url):
391367
"""Issue a DELETE request to the URL or API shorthand."""
@@ -395,10 +371,7 @@ def delete(self, url):
395371
# Catch no content responses from some delete actions.
396372
if response.status_code == 204:
397373
return []
398-
try:
399-
return response.json()
400-
except:
401-
return response.content
374+
return self._response_value(response)
402375

403376
def upload_creative(self, account_id, file_path):
404377
"""Upload a media creative to the account with ID
@@ -441,10 +414,8 @@ def upload_creative(self, account_id, file_path):
441414
response = self._session.get(url, headers=headers, data=body, timeout=self.timeout)
442415
self.log_request(response)
443416
response.raise_for_status()
444-
try:
445-
return response.json()
446-
except:
447-
return response.content
417+
return self._response_value(response)
418+
448419

449420
def client_from_file(file_path='.ox3rc', env=None):
450421
"""Return an instance of ox3apiclient.Client with data from file_path.
@@ -513,4 +484,4 @@ def client_from_file(file_path='.ox3rc', env=None):
513484

514485
# The exposed API has moved to using Client instead of OX3APIClient, but create
515486
# a temporary alias for backwards compatibility.
516-
OX3APIClient = Client
487+
OX3APIClient = Client

setup.py

+25-25
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
3-
4-
from distutils.core import setup
3+
try:
4+
from setuptools import setup
5+
except ImportError:
6+
from distutils.core import setup
57
from os.path import dirname, join
68
import re
79

810
file_path = join(dirname(__file__), 'ox3apiclient', '__init__.py')
911
version = re.search("__version__\s*=\s*['\"](.+)['\"]",
10-
open(file_path, 'r').read()).groups()[0]
12+
open(file_path, 'r').read()).groups()[0]
1113

1214
setup(name='ox3apiclient',
13-
version=version,
14-
author='Tony Edwards',
15-
author_email='[email protected]',
16-
url='https://github.com/tnydwrds/OX3-Python-API-Client',
17-
description='Client to connect to OpenX Enterprise API.',
18-
long_description='Client to connect to OpenX Enterprise API.',
19-
packages=['ox3apiclient'],
20-
install_requires=['oauth2'],
21-
classifiers=[
22-
'Environment :: Console',
23-
'Environment :: Web Environment',
24-
'Intended Audience :: Developers',
25-
'Operating System :: OS Independent',
26-
'Programming Language :: Python',
27-
'Programming Language :: Python :: 2.4',
28-
'Programming Language :: Python :: 2.5',
29-
'Programming Language :: Python :: 2.6',
30-
'Programming Language :: Python :: 2.7',
31-
'Programming Language :: Python :: Implementation :: CPython',
32-
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
33-
'Topic :: Software Development :: Libraries',
34-
'Topic :: Software Development :: Libraries :: Python Modules'])
15+
version=version,
16+
author='OpenX API Team',
17+
author_email='[email protected]',
18+
url='https://github.com/openx/OX3-Python-API-Client',
19+
description='Client to connect to OpenX Enterprise API.',
20+
long_description='Client to connect to OpenX Enterprise API.',
21+
packages=['ox3apiclient'],
22+
install_requires=['requests_oauthlib'],
23+
classifiers=[
24+
'Environment :: Console',
25+
'Environment :: Web Environment',
26+
'Intended Audience :: Developers',
27+
'Operating System :: OS Independent',
28+
'Programming Language :: Python',
29+
'Programming Language :: Python :: 2.6',
30+
'Programming Language :: Python :: 2.7',
31+
'Programming Language :: Python :: Implementation :: CPython',
32+
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
33+
'Topic :: Software Development :: Libraries',
34+
'Topic :: Software Development :: Libraries :: Python Modules'])

0 commit comments

Comments
 (0)