1import re 2import collections 3try: 4 from urllib import quote_plus 5except ImportError: 6 from urllib.parse import quote_plus 7 8import six 9 10 11def to_params(hash): 12 normalized = [normalize_param(k, v) for (k, v) in six.iteritems(hash)] 13 return dict((k, v) for d in normalized for (k, v) in d.items()) 14 15 16def normalize_param(key, value): 17 """Convert a set of key, value parameters into a dictionary suitable for 18 passing into requests. This will convert lists into the syntax required 19 by SoundCloud. Heavily lifted from HTTParty. 20 21 >>> normalize_param('playlist', { 22 ... 'title': 'foo', 23 ... 'sharing': 'private', 24 ... 'tracks': [ 25 ... {id: 1234}, {id: 4567} 26 ... ]}) == { 27 ... u'playlist[tracks][][<built-in function id>]': [1234, 4567], 28 ... u'playlist[sharing]': 'private', 29 ... u'playlist[title]': 'foo'} # doctest:+ELLIPSIS 30 True 31 32 >>> normalize_param('oauth_token', 'foo') 33 {'oauth_token': 'foo'} 34 35 >>> normalize_param('playlist[tracks]', [1234, 4567]) == { 36 ... u'playlist[tracks][]': [1234, 4567]} 37 True 38 """ 39 params = {} 40 stack = [] 41 if isinstance(value, list): 42 normalized = [normalize_param(u"{0[key]}[]".format(dict(key=key)), e) for e in value] 43 keys = [item for sublist in tuple(h.keys() for h in normalized) for item in sublist] 44 45 lists = {} 46 if len(keys) != len(set(keys)): 47 duplicates = [x for x, y in collections.Counter(keys).items() if y > 1] 48 for dup in duplicates: 49 lists[dup] = [h[dup] for h in normalized] 50 for h in normalized: 51 del h[dup] 52 53 params.update(dict((k, v) for d in normalized for (k, v) in d.items())) 54 params.update(lists) 55 elif isinstance(value, dict): 56 stack.append([key, value]) 57 else: 58 params.update({key: value}) 59 60 for (parent, hash) in stack: 61 for (key, value) in six.iteritems(hash): 62 if isinstance(value, dict): 63 stack.append([u"{0[parent]}[{0[key]}]".format(dict(parent=parent, key=key)), value]) 64 else: 65 params.update(normalize_param(u"{0[parent]}[{0[key]}]".format(dict(parent=parent, key=key)), value)) 66 67 return params 68