Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

moved urlencoding logic out as its own library

  • Loading branch information...
commit 9c9c22d633f1ff85db373546b4372b64bfa69bb5 1 parent 455cde2
Naitik Shah authored
View
2  README
@@ -1,3 +1,3 @@
Generated documentation is available at http://code.daaku.org/python-oauth/.
-pip install -e 'git+git://github.com/nshah/python-oauth.git#egg=oauth'
+pip install -r http://code.daaku.org/python-oauth/reqs
View
13 docs/index.rst
@@ -16,7 +16,7 @@ Requires Python 2.5 or newer.
Can be installed using `pip <http://pip.openplans.org/>`_::
- pip install -e 'git+git://github.com/nshah/python-oauth.git#egg=oauth'
+ pip install -r http://code.daaku.org/python-oauth/reqs
.. toctree::
@@ -53,17 +53,6 @@ requests.
:members:
.. autoclass:: oauth.signature_method.plaintext.OAuthSignatureMethod_PLAINTEXT
-*****************
-Utility Functions
-*****************
-
-Helper functions that deal with query strings & OAuth compliant parameter
-escaping.
-
-.. autofunction:: oauth.escape
-.. autofunction:: oauth.parse_qs
-.. autofunction:: oauth.compose_qs(params, sort=False)
-
*****
Error
*****
View
110 oauth/__init__.py
@@ -1,12 +1,10 @@
# coding: utf-8
-import cgi
import collections
-import copy
-import logging
import random
import time
import urllib
import urlparse
+from urlencoding import escape, parse_qs, compose_qs
OAUTH_VERSION = '1.0'
@@ -20,112 +18,6 @@ class OAuthError(RuntimeError):
"""
pass
-def escape(value):
- """
- Escape the string according to:
-
- http://oauth.net/core/1.0/#encoding_parameters
-
- Arguments:
-
- `value`
- The string to escape.
-
- >>> oauth.escape('a b & c')
- 'a%20b%20%26%20c'
- >>> oauth.escape('abc123-._~')
- 'abc123-._~'
-
- """
- return urllib.quote(value, safe='~')
-
-def is_nonstring_iterable(i):
- return type(i) not in [str, unicode] and isinstance(i, collections.Iterable)
-
-def parse_qs(query):
- """
- Parse a query string into a dict. Values my be strings or arrays.
-
- Arguments:
-
- `query`
- The query string or form encoded body to parse.
-
- >>> oauth.parse_qs('a=1&b=%20c+d')
- {'a': '1', 'b': ' c d'}
- >>> oauth.parse_qs('a=2&a=1')
- {'a': ['2', '1']}
-
- """
- d = {}
- for k, v in cgi.parse_qs(query, keep_blank_values=False).iteritems():
- if len(v) == 1:
- d[k] = v[0]
- else:
- d[k] = v
- return d
-
-ENCODED_OPEN_BRACKET = escape('[')
-ENCODED_CLOSE_BRACKET = escape(']')
-def compose_qs(params, sort=False, pattern='%s=%s', join='&', wrap=None):
- """
- Compose a single string using OAuth specified escaping using
- `oauth.escape`_ for keys and values.
-
- Arguments:
-
- `params`
- The dict of parameters to encode into a query string.
-
- `sort`
- Boolean indicating if the key/values should be sorted.
-
- >>> oauth.compose_qs({'a': '1', 'b': ' c d'})
- 'a=1&b=%20c%20d'
- >>> oauth.compose_qs({'a': ['2', '1']})
- 'a=2&a=1'
- >>> oauth.compose_qs({'a': ['2', '1', '3']}, sort=True)
- 'a=1&a=2&a=3'
- >>> oauth.compose_qs({'a': '1', 'b': {'c': 2, 'd': 3}}, sort=True)
- 'a=1&b%5Bc%5D=2&b%5Bd%5D=3'
-
- """
-
- if sort:
- params = SortedDict(params)
-
- pieces = []
- for key, value in params.iteritems():
- escaped_key = escape(str(key))
- if wrap:
- escaped_key = wrap + ENCODED_OPEN_BRACKET + escaped_key + ENCODED_CLOSE_BRACKET
-
- if isinstance(value, collections.Mapping):
- p = compose_qs(value, sort, pattern, join, escaped_key)
- elif is_nonstring_iterable(value):
- p = join.join([pattern % (escaped_key, escape(str(v))) for v in value])
- else:
- p = pattern % (escaped_key, escape(str(value)))
- pieces.append(p)
- return join.join(pieces)
-
-class SortedDict(dict):
- def iteritems(self):
- """
- Iterates in a sorted fashion. Values are sorted before being yielded if
- they can be. It should result in sorted by key, then value semantics.
-
- http://oauth.net/core/1.0/#rfc.section.9.1.1
-
- """
- for key in sorted(self):
- value = self[key]
- if isinstance(value, collections.Mapping):
- value = SortedDict(value)
- elif is_nonstring_iterable(value):
- value = sorted(value)
- yield key, value
-
class OAuthRequest(object):
"""
Represents outgoing or incoming requests. Provides the ability to sign
View
5 setup.py
@@ -17,5 +17,8 @@
],
include_package_data=True,
zip_safe=False,
- install_requires=['setuptools', 'setuptools_git'],
+ install_requires=['setuptools', 'setuptools_git', 'urlencoding'],
+ extras_require = {
+ 'RSA': ['tlslite'],
+ },
)
View
61 tests/urlencoding.py
@@ -1,61 +0,0 @@
-# coding: utf-8
-
-import unittest
-import oauth
-
-
-class TestEscape(unittest.TestCase):
- def test_no_escaping(self):
- self.assertEqual(oauth.escape('abcd'), 'abcd')
-
- def test_space(self):
- self.assertEqual(oauth.escape(' '), '%20')
-
- def test_alphanumeric(self):
- alpha_num = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
- self.assertEqual(oauth.escape(alpha_num), alpha_num)
-
- def test_oauth_mentioned_specials(self):
- mentioned = '-._~'
- self.assertEqual(oauth.escape(mentioned), mentioned)
-
-class TestParseQS(unittest.TestCase):
- def test_simple(self):
- self.assertEqual(oauth.parse_qs('a=1'), {'a': '1'})
-
- def test_multi(self):
- self.assertEqual(oauth.parse_qs('a=1&b=2'), {'a': '1', 'b': '2'})
-
- def test_space(self):
- self.assertEqual(
- oauth.parse_qs('a=1&b=2&c=%20d'),
- {'a': '1', 'b': '2', 'c': ' d'}
- )
-
- def test_square_index(self):
- self.assertEqual(
- oauth.parse_qs('a%5Bb%5D=1&a%5Bc%5D=2'),
- {'a[b]': '1', 'a[c]': '2'}
- )
-
- def test_array_value(self):
- self.assertEqual(
- oauth.parse_qs('a=1&a=2'),
- {'a': ['1', '2']}
- )
-
-class TestComposeQS(unittest.TestCase):
- def test_simple(self):
- self.assertEqual(oauth.compose_qs({'a': '1'}), 'a=1')
-
- def test_array(self):
- self.assertEqual(oauth.compose_qs({'a': ['2', '1']}), 'a=2&a=1')
-
- def test_sorted_array(self):
- self.assertEqual(oauth.compose_qs({'a': ['2', '1']}, sort=True), 'a=1&a=2')
-
- def test_sorted_dict(self):
- self.assertEqual(oauth.compose_qs({'a': {'b': '1', 'c': '2'}}, sort=True), 'a%5Bb%5D=1&a%5Bc%5D=2')
-
-if __name__ == '__main__':
- unittest.main()
Please sign in to comment.
Something went wrong with that request. Please try again.