'Sign a request
Signs an HTTP request with the specified parts.
Returns a 3-tuple of the signed request\'s URI, headers, and body.
Note that http_method is not returned as it is unaffected by the OAuth
signing process.
The body argument may be a dict, a list of 2-tuples, or a formencoded
string. The Content-Type header must be \'application/x-www-form-urlencoded\'
if it is present.
If the body argument is not one of the above, it will be returned
verbatim as it is unaffected by the OAuth signing process. Attempting to
sign a request with non-formencoded data using the OAuth body signature
type is invalid and will raise an exception.
If the body does contain parameters, it will be returned as a properly-
formatted formencoded string.
All string data MUST be unicode. This includes strings inside body
dicts, for example.'

def sign(self, uri, http_method=u'GET', body=None, headers=None):

    request = Request(uri, http_method, body, headers)
    content_type = request.headers.get('Content-Type', None)
    multipart = (content_type and content_type.startswith('multipart/'))
    should_have_params = (content_type == CONTENT_TYPE_FORM_URLENCODED)
    has_params = (request.decoded_body is not None)
    if (multipart and has_params):
        raise ValueError('Headers    indicate    a    multipart    body    but    body    contains    parameters.')
    elif (should_have_params and (not has_params)):
        raise ValueError('Headers    indicate    a    formencoded    body    but    body    was    not    decodable.')
    elif ((not should_have_params) and has_params):
        raise ValueError('Body    contains    parameters    but    Content-Type    header    was    not    set.')
    elif ((self.signature_type == SIGNATURE_TYPE_BODY) and (not (should_have_params and has_params and (not multipart)))):
        raise ValueError('Body    signatures    may    only    be    used    with    form-urlencoded    content')
    request.oauth_params = self.get_oauth_params()
    request.oauth_params.append((u'oauth_signature', self.get_oauth_signature(request)))
    return self._render(request, formencode=True)
