Merge lp:~barry/piston-mini-client/lp1077083 into lp:piston-mini-client

Proposed by Barry Warsaw
Status: Merged
Merged at revision: 65
Proposed branch: lp:~barry/piston-mini-client/lp1077083
Merge into: lp:piston-mini-client
Diff against target: 165 lines (+44/-27)
6 files modified
README (+1/-2)
doc/index.rst (+2/-2)
piston_mini_client/auth.py (+28/-16)
piston_mini_client/tests/test_auth.py (+0/-5)
piston_mini_client/tests/test_serializers.py (+12/-1)
setup.py (+1/-1)
To merge this branch: bzr merge lp:~barry/piston-mini-client/lp1077083
Reviewer Review Type Date Requested Status
Michael Vogt Approve
Review via email: mp+135449@code.launchpad.net

Description of the change

Switches from the long abandoned and not-Python-3-compatible python-oauth library to the well-supported-upstream and Python 3 compatible python-oauthlib library. Fixes a bogus dictionary order dependency which breaks Python 3.3. Re-enables a Python 3 test.

To post a comment you must log in.
Revision history for this message
Barry Warsaw (barry) wrote :

Note that you will have some trouble testing this on today's Raring. The problem is that tox is not yet in Raring (it will soon land in Debian and then be synced to Raring), and the python-virtualenv version that is currently in Raring is not compatible with Python 3.3. This should be fixed upstream today and will make it into Ubuntu shortly thereafter.

To test this on Raring, your best bet is to install virtualenv from upstream git (where the Python 3.3 bug is fixed), create a Python 2.7 and separate Python 3.3 virtualenvs, install the dependencies into them (via pip), and then run nosetests into the virtualenv.

Hopefully by next week you'll be able to just run `tox -e py27,py33` in Raring.

Revision history for this message
Michael Vogt (mvo) wrote :

Thanks for this branch. Looks good to me, +1

review: Approve
Revision history for this message
Anthony Lenton (elachuni) wrote :

Thanks Barry!!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README'
--- README 2012-07-31 16:33:45 +0000
+++ README 2012-11-21 15:46:35 +0000
@@ -29,8 +29,7 @@
29 tox29 tox
3030
31This will ensure the tests run on Python 2.6, 2.7 and 3.2, and the docs build31This will ensure the tests run on Python 2.6, 2.7 and 3.2, and the docs build
32correctly. Tests pass against Python 3, but oauth tests are skipped as the32correctly.
33oauth module still doesn't have Python 3 support.
3433
35Building the docs locally34Building the docs locally
36=========================35=========================
3736
=== modified file 'doc/index.rst'
--- doc/index.rst 2012-04-02 18:21:11 +0000
+++ doc/index.rst 2012-11-21 15:46:35 +0000
@@ -33,8 +33,8 @@
3333
34* It should have a small set of dependencies. We depend on httplib2 mainly34* It should have a small set of dependencies. We depend on httplib2 mainly
35 because it provides caching, but you should not need to install a pile of35 because it provides caching, but you should not need to install a pile of
36 packages just to use a rest client. Other dependencies like ``oauth`` and36 packages just to use a rest client. Other dependencies like ``oauthlib``
37 ``socks`` are only imported if you need to use oauth authentication or37 and ``socks`` are only imported if you need to use oauth authentication or
38 support proxies, respectively.38 support proxies, respectively.
3939
40* Errors should be informative. Backtraces should point you in the right40* Errors should be informative. Backtraces should point you in the right
4141
=== modified file 'piston_mini_client/auth.py'
--- piston_mini_client/auth.py 2012-07-30 17:09:26 +0000
+++ piston_mini_client/auth.py 2012-11-21 15:46:35 +0000
@@ -8,11 +8,15 @@
8instantiate a ``PistonAPI`` object.8instantiate a ``PistonAPI`` object.
9"""9"""
1010
11from functools import wraps
12
13import base6411import base64
1412
1513
14def _unicodeify(s):
15 if isinstance(s, bytes):
16 return s.decode('utf-8')
17 return s
18
19
16class OAuthAuthorizer(object):20class OAuthAuthorizer(object):
17 """Authenticate to OAuth protected APIs."""21 """Authenticate to OAuth protected APIs."""
18 def __init__(self, token_key, token_secret, consumer_key, consumer_secret,22 def __init__(self, token_key, token_secret, consumer_key, consumer_secret,
@@ -23,25 +27,33 @@
23 ``consumer_secret`` are required for signing OAuth requests. The27 ``consumer_secret`` are required for signing OAuth requests. The
24 ``oauth_realm`` to use is optional.28 ``oauth_realm`` to use is optional.
25 """29 """
26 self.token_key = token_key30 # 2012-11-19 BAW: python-oauthlib requires unicodes for its tokens and
27 self.token_secret = token_secret31 # secrets. Assume utf-8 values.
28 self.consumer_key = consumer_key32 # https://github.com/idan/oauthlib/issues/68
29 self.consumer_secret = consumer_secret33 self.token_key = _unicodeify(token_key)
34 self.token_secret = _unicodeify(token_secret)
35 self.consumer_key = _unicodeify(consumer_key)
36 self.consumer_secret = _unicodeify(consumer_secret)
30 self.oauth_realm = oauth_realm37 self.oauth_realm = oauth_realm
3138
32 def sign_request(self, url, method, body, headers):39 def sign_request(self, url, method, body, headers):
33 """Sign a request with OAuth credentials."""40 """Sign a request with OAuth credentials."""
34 # Import oauth here so that you don't need it if you're not going41 # 2012-11-19 BAW: In order to preserve API backward compatibility,
42 # convert empty string body to None. The old python-oauth library
43 # would treat the empty string as "no body", but python-oauthlib
44 # requires None.
45 if not body:
46 body = None
47 # Import oauthlib here so that you don't need it if you're not going
35 # to use it. Plan B: move this out into a separate oauth module.48 # to use it. Plan B: move this out into a separate oauth module.
36 from oauth.oauth import (OAuthRequest, OAuthConsumer, OAuthToken,49 from oauthlib.oauth1 import Client, SIGNATURE_PLAINTEXT
37 OAuthSignatureMethod_PLAINTEXT)50 oauth_client = Client(self.consumer_key, self.consumer_secret,
38 consumer = OAuthConsumer(self.consumer_key, self.consumer_secret)51 self.token_key, self.token_secret,
39 token = OAuthToken(self.token_key, self.token_secret)52 signature_method=SIGNATURE_PLAINTEXT,
40 oauth_request = OAuthRequest.from_consumer_and_token(53 realm=self.oauth_realm)
41 consumer, token, http_url=url)54 uri, signed_headers, body = oauth_client.sign(
42 oauth_request.sign_request(OAuthSignatureMethod_PLAINTEXT(),55 url, method, body, headers)
43 consumer, token)56 headers.update(signed_headers)
44 headers.update(oauth_request.to_header(self.oauth_realm))
4557
4658
47class BasicAuthorizer(object):59class BasicAuthorizer(object):
4860
=== modified file 'piston_mini_client/tests/test_auth.py'
--- piston_mini_client/tests/test_auth.py 2012-07-30 17:09:26 +0000
+++ piston_mini_client/tests/test_auth.py 2012-11-21 15:46:35 +0000
@@ -2,7 +2,6 @@
2# Copyright 2010-2012 Canonical Ltd. This software is licensed under the2# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
3# GNU Lesser General Public License version 3 (see the file LICENSE).3# GNU Lesser General Public License version 3 (see the file LICENSE).
44
5import sys
6from piston_mini_client.auth import OAuthAuthorizer, BasicAuthorizer5from piston_mini_client.auth import OAuthAuthorizer, BasicAuthorizer
7from unittest import TestCase6from unittest import TestCase
87
@@ -20,10 +19,6 @@
2019
21class OAuthAuthorizerTestCase(TestCase):20class OAuthAuthorizerTestCase(TestCase):
22 def test_sign_request(self):21 def test_sign_request(self):
23 if sys.version_info[0] == 3:
24 # Skip on Python 3 as oauth is still broken there.
25 # don't use skipIf as it's missing on python2.6
26 return
27 auth = OAuthAuthorizer('tkey', 'tsecret', 'ckey', 'csecret')22 auth = OAuthAuthorizer('tkey', 'tsecret', 'ckey', 'csecret')
28 url = 'http://example.com/api'23 url = 'http://example.com/api'
29 headers = {}24 headers = {}
3025
=== modified file 'piston_mini_client/tests/test_serializers.py'
--- piston_mini_client/tests/test_serializers.py 2012-07-30 17:09:26 +0000
+++ piston_mini_client/tests/test_serializers.py 2012-11-21 15:46:35 +0000
@@ -7,6 +7,13 @@
7from piston_mini_client.serializers import JSONSerializer, FormSerializer7from piston_mini_client.serializers import JSONSerializer, FormSerializer
8from piston_mini_client import PistonSerializable8from piston_mini_client import PistonSerializable
99
10try:
11 # Python 3.
12 from urllib.parse import parse_qs
13except ImportError:
14 # Python 2.
15 from urlparse import parse_qs
16
1017
11class JSONSerializerTestCase(TestCase):18class JSONSerializerTestCase(TestCase):
12 def test_simple_serialize(self):19 def test_simple_serialize(self):
@@ -38,7 +45,11 @@
3845
39 myarg = MySerializable(foo='baz', bar=42)46 myarg = MySerializable(foo='baz', bar=42)
40 serializer = FormSerializer()47 serializer = FormSerializer()
41 self.assertEqual('foo=baz&bar=42', serializer.serialize(myarg))48 # Argument order is undefined, so parse these into dictionaries which
49 # can be compared.
50 want = parse_qs('foo=baz&bar=42')
51 got = parse_qs(serializer.serialize(myarg))
52 self.assertEqual(want, got)
4253
43 def test_serialize_nested(self):54 def test_serialize_nested(self):
44 # Maybe we should flatly refuse to serialize nested structures?55 # Maybe we should flatly refuse to serialize nested structures?
4556
=== modified file 'setup.py'
--- setup.py 2012-09-24 13:22:12 +0000
+++ setup.py 2012-11-21 15:46:35 +0000
@@ -11,7 +11,7 @@
11 packages=['piston_mini_client'],11 packages=['piston_mini_client'],
12 license='LGPLv3',12 license='LGPLv3',
13 install_requires=[13 install_requires=[
14 'oauth',14 'oauthlib',
15 'httplib2',15 'httplib2',
16 ],16 ],
17)17)

Subscribers

People subscribed via source and target branches