This exception seems to be raised from lib/canonical/launchpad/webapp/servers.py.
After bug this was filed, Launchpad started accepting unauthenticated readonly requests and it seems to me that in that case, you don't need to provide oauth data at all, only a user-agent. This, at least, does seem to work for me (tested with "curl --verbose https://api.launchpad.net/beta/").
It does look like what Max describes in comment #8 is still true, that if oauth_consumer_key is the first value in the list, it's just not seen by the server. The difference is that this now makes the request be treated as unauthenticated rather than failing.
There is some pretty dodgy code in contrib/oauth.py that seems to be assuming the 'realm' will always be first:
# util function: turn Authorization: header into parameters, has to do some unescaping
@staticmethod
def _split_header(header):
params = {}
parts = header.split(',')
for param in parts:
# ignore realm parameter
if param.find('OAuth realm') > -1: continue
# remove whitespace
param = param.strip()
# split key-value param_parts = param.split('=', 1)
# remove quotes and unescape the value params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
return params
Blaine, can you please make sure there is a bug report in <https:/ /bugs.launchpad .net/launchpadl ib> for the problem with building launchpadlib?
This exception seems to be raised from lib/canonical/ launchpad/ webapp/ servers. py.
After bug this was filed, Launchpad started accepting unauthenticated readonly requests and it seems to me that in that case, you don't need to provide oauth data at all, only a user-agent. This, at least, does seem to work for me (tested with "curl --verbose https:/ /api.launchpad. net/beta/").
It does look like what Max describes in comment #8 is still true, that if oauth_consumer_key is the first value in the list, it's just not seen by the server. The difference is that this now makes the request be treated as unauthenticated rather than failing.
There is some pretty dodgy code in contrib/oauth.py that seems to be assuming the 'realm' will always be first:
# util function: turn Authorization: header into parameters, has to do some unescaping header( header) :
continue
param_ parts = param.split('=', 1)
params[ param_parts[ 0]] = urllib. unquote( param_parts[ 1].strip( '\"'))
@staticmethod
def _split_
params = {}
parts = header.split(',')
for param in parts:
# ignore realm parameter
if param.find('OAuth realm') > -1:
# remove whitespace
param = param.strip()
# split key-value
# remove quotes and unescape the value
return params