OAuth1 with requests_oauthlib produces URL encoding error - python

I am using the requests_oauthlib module for OAuth authentication.
Unfortunately I cannot reproduce the OAuth1 workflow acoording to step one in this tutorial: http://requests-oauthlib.readthedocs.org/en/latest/oauth1_workflow.html
If I try to obtain a fetch response it throws me the followin error:
Traceback (most recent call last):
File "/home/neumannr/test.py", line 18, in <module>
fetch_response = oauth.fetch_request_token(request_token_url)
File "/usr/lib/python2.7/site-packages/requests_oauthlib/oauth1_session.py", line 195, in fetch_request_token
token = self._fetch_token(url)
File "/usr/lib/python2.7/site-packages/requests_oauthlib/oauth1_session.py", line 264, in _fetch_token
token = dict(urldecode(self.post(url).text))
File "/usr/lib/python2.7/site-packages/oauthlib/common.py", line 135, in urldecode
raise ValueError('Not a valid urlencoded string.')
ValueError: Not a valid urlencoded string.
My testing code looks as follows:
#! /usr/bin/env python
# Using OAuth1Session
from requests_oauthlib import OAuth1Session
# Using OAuth1 auth helper
import requests
from requests_oauthlib import OAuth1
client_key = 'a'
client_secret = 'b'
request_token_url = 'https://api.twitter.com/oauth/request_token'
# Using OAuth1Session
oauth = OAuth1Session(client_key, client_secret=client_secret)
fetch_response = oauth.fetch_request_token(request_token_url)
Since the URL is not being URL encoded within the tutorial either, I do not understand why this happens. If I try to URL encode the URL like this:
#! /usr/bin/env python
# Using OAuth1Session
import urllib
from requests_oauthlib import OAuth1Session
# Using OAuth1 auth helper
import requests
from requests_oauthlib import OAuth1
client_key = 'a'
client_secret = 'b'
request_token_url = urllib.quote('https://api.twitter.com/oauth/request_token')
# Using OAuth1Session
oauth = OAuth1Session(client_key, client_secret=client_secret)
fetch_response = oauth.fetch_request_token(request_token_url)
I get a missing schema error:
Traceback (most recent call last):
File "/home/neumannr/test.py", line 19, in <module>
fetch_response = oauth.fetch_request_token(request_token_url)
File "/usr/lib/python2.7/site-packages/requests_oauthlib/oauth1_session.py", line 195, in fetch_request_token
token = self._fetch_token(url)
File "/usr/lib/python2.7/site-packages/requests_oauthlib/oauth1_session.py", line 264, in _fetch_token
token = dict(urldecode(self.post(url).text))
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 377, in post
return self.request('POST', url, data=data, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 324, in request
prep = req.prepare()
File "/usr/lib/python2.7/site-packages/requests/models.py", line 222, in prepare
p.prepare_url(self.url, self.params)
File "/usr/lib/python2.7/site-packages/requests/models.py", line 291, in prepare_url
raise MissingSchema("Invalid URL %r: No schema supplied" % url)
requests.exceptions.MissingSchema: Invalid URL u'https%3A//api.twitter.com/oauth/request_token': No schema supplied
How do I use oauthlib_requests anyway?
Thanks,
Richard

The error can be a result of a failed attempt to decode the response. For more details, please see OAuthlib issue 124.

Related

Python-Youtube-Api : Missing code parameter in response

I am testing the python-youtube package, using the following code:
from pyyoutube import Api
api = Api(
client_id="yes-my-client-id-here-i-know",
client_secret="yes-my-client-secret-here-i-know")
authorization_url = api.get_authorization_url()
access_token = api.generate_access_token(authorization_response=authorization_url[0])
print('authorization_url : >>>>>> ', authorization_url)
print('access_token : >>>>>> ', access_token)
I get the following error.
Traceback (most recent call last):
File "main.py", line 10, in <module>
access_token = api.generate_access_token(authorization_response=authorization_url[0])
File "/Users/sleento/production/python-youtube-api/env/lib/python3.8/site-packages/pyyoutube/api.py", line 263, in generate_access_token
token = oauth_session.fetch_token(
File "/Users/sleento/production/python-youtube-api/env/lib/python3.8/site-packages/requests_oauthlib/oauth2_session.py", line 244, in fetch_token
self._client.parse_request_uri_response(
File "/Users/sleento/production/python-youtube-api/env/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/clients/web_application.py", line 220, in parse_request_uri_response
response = parse_authorization_code_response(uri, state=state)
File "/Users/sleento/production/python-youtube-api/env/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 284, in parse_authorization_code_response
raise MissingCodeError("Missing code parameter in response.")
oauthlib.oauth2.rfc6749.errors.MissingCodeError: (missing_code) Missing code parameter in response.
I solve that, I was using client_id instead of api_key parameter.
from pyyoutube import Api
api = Api(
api_key="yes-my-APi-key-here-i-know")
authorization_url = api.get_authorization_url()
print('authorization_url : >>>>>> ', authorization_url)

python SOAP with zeep, requests.exception: 403 client error

I'm trying to make a SOAP client in python using zeepSo far I've had zero luck in trying to get it to run. I keep getting the following error.
Traceback (most recent call last):
File "C:/Users/z905/PycharmProjects/Soap_Test/soap_test.py", line 14, in <module>
client = Client(wsdl=client_location, transport=transport_with_basic_auth)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\client.py", line 134, in __init__
self.wsdl = Document(wsdl, self.transport, strict=strict)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\wsdl\wsdl.py", line 81, in __init__
root_definitions = Definition(self, document, self.location)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\wsdl\wsdl.py", line 178, in __init__
self.parse_imports(doc)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\wsdl\wsdl.py", line 270, in parse_imports
document = self.wsdl._get_xml_document(location)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\wsdl\wsdl.py", line 140, in _get_xml_document
location, self.transport, self.location, strict=self.strict)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\loader.py", line 72, in load_external
content = transport.load(url)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\transports.py", line 110, in load
content = self._load_remote_data(url)
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\zeep\transports.py", line 126, in _load_remote_data
response.raise_for_status()
File "C:\Users\z905\PycharmProjects\Soap_Test\venv\lib\site-packages\requests\models.py", line 935, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden (Forbidden port) for url: http://url:7104
I've tried the program with and without basic authentication.
from zeep import Client
from requests import Session
from requests.auth import HTTPBasicAuth
from zeep.transports import Transport
client_location = "file://C:/<path-to-local-file>"
loc = "<url-to-wsdl>"
session = Session()
session.auth = HTTPBasicAuth('usrname', 'pass')
transport_with_basic_auth = Transport(session=session)
client = Client(wsdl=client_location, transport=transport_with_basic_auth)
And version without Basic Auth.
from zeep import Client
from zeep.wsse.username import UsernameToken
client_location = "file://C:/<path-to-local-file>"
loc = "<url-to-wsdl>"
client = Client(wsdl=loc, wsse=UsernameToken(usr, password, use_digest=True))
I was able to solve the issue by doing the following. The issue was caused by some firewall issues and the proxy not working.
import requests
session = requests.session()
session.trust_env = False
transport = Transport(session=session)
client = Client(wsdl=client_location, wsse=UsernameToken(usr, password, use_digest=True), transport=transport)

Python Google drive SDK - getting error sequence item 0: expected str instance, bytes found

Consider the code below:
#!/usr/bin/python
import httplib2
import pprint
from apiclient.discovery import build
from apiclient.http import MediaFileUpload
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.client import OAuth2Credentials
from oauth2client import GOOGLE_AUTH_URI
from oauth2client import GOOGLE_REVOKE_URI
from oauth2client import GOOGLE_TOKEN_URI
#Refresh token
REFRESH_TOKEN = ""
# Copy your credentials from the console
CLIENT_ID = ''
CLIENT_SECRET = ''
## Check https://developers.google.com/drive/scopes for all available scopes
OAUTH_SCOPE = ['https://www.googleapis.com/auth/drive','http://localhost:5001/storage/getGDriveAuth']
## Redirect URI for installed apps
REDIRECT_URI = ''
credentials = OAuth2Credentials(None, CLIENT_ID,
CLIENT_SECRET, REFRESH_TOKEN, None,
GOOGLE_TOKEN_URI, None,
revoke_uri=GOOGLE_REVOKE_URI,
id_token=None,
token_response=None)
# Create an httplib2.Http object and authorize it with our credentials
http = httplib2.Http()
http = credentials.authorize(http)
drive_service = build('drive', 'v2', http=http) #getting error here
file = drive_service.files().list().execute()
pprint.pprint(file)
exit();
I am getting following error:
Traceback (most recent call last):
File "python-quickstart/main.py", line 64, in <module>
drive_service = apiclient.discovery.build('drive', 'v2', http=http)
File "d:\xampp\htdocs\driveTest\lib\site-packages\oauth2client\util.py", line 137, in positional_wrapper
return wrapped(*args, **kwargs)
File "d:\xampp\htdocs\driveTest\lib\site-packages\googleapiclient\discovery.py", line 196, in build
resp, content = http.request(requested_url)
File "d:\xampp\htdocs\driveTest\lib\site-packages\oauth2client\util.py", line 137, in positional_wrapper
return wrapped(*args, **kwargs)
File "d:\xampp\htdocs\driveTest\lib\site-packages\oauth2client\client.py", line 551, in new_request
redirections, connection_type)
File "d:\xampp\htdocs\driveTest\lib\site-packages\httplib2\__init__.py", line 1139, in request
headers = self._normalize_headers(headers)
File "d:\xampp\htdocs\driveTest\lib\site-packages\httplib2\__init__.py", line 1107, in _normalize_headers
return _normalize_headers(headers)
File "d:\xampp\htdocs\driveTest\lib\site-packages\httplib2\__init__.py", line 195, in _normalize_headers
return dict([ (key.lower(), NORMALIZE_SPACE.sub(value, ' ').strip()) for (key, value) in headers.items()])
File "d:\xampp\htdocs\driveTest\lib\site-packages\httplib2\__init__.py", line 195, in <listcomp>
return dict([ (key.lower(), NORMALIZE_SPACE.sub(value, ' ').strip()) for (key, value) in headers.items()])
TypeError: sequence item 0: expected str instance, bytes found
Any idea why it is happening?
This error occurs because of the difference in the way Python 2 and Python 3 handle byte strings, more details about this are available here:
https://docs.python.org/3/whatsnew/3.0.html
This issue occurs because of the way that oath2client and httplib2 handled strings as bytes - the latest version of httplib2 which is newer than the current PyPI version(as of 03/25/2015) has included a work around for this issue.
Eventually the developers might decide on a different solution to the problem, however, you can use the newer version of httplib2 to resolve this problem in your code.

Python Proxy Error With Requests Library

I am trying to access the web via a proxy server in Python. I am using the requests library and I am having an issue with authenticating my proxy as the proxy I am using requires a password.
proxyDict = {
'http' : 'username:mypassword#77.75.105.165',
'https' : 'username:mypassword#77.75.105.165'
}
r = requests.get("http://www.google.com", proxies=proxyDict)
I am getting the following error:
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
r = requests.get("http://www.google.com", proxies=proxyDict)
File "C:\Python27\lib\site-packages\requests\api.py", line 78, in get
:param url: URL for the new :class:`Request` object.
File "C:\Python27\lib\site-packages\requests\api.py", line 65, in request
"""Sends a POST request. Returns :class:`Response` object.
File "C:\Python27\lib\site-packages\requests\sessions.py", line 187, in request
def head(self, url, **kwargs):
File "C:\Python27\lib\site-packages\requests\models.py", line 407, in send
"""
File "C:\Python27\lib\site-packages\requests\packages\urllib3\poolmanager.py", line 127, in proxy_from_url
File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 521, in connection_from_url
File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 497, in get_host
ValueError: invalid literal for int() with base 10: 'h6f2v6jh5dsxa#77.75.105.165'
How do I solve this?
Thanks in advance for your help.
You should remove the embedded username and password from proxyDict, and use the auth parameter instead.
import requests
from requests.auth import HTTPProxyAuth
proxyDict = {
'http' : '77.75.105.165',
'https' : '77.75.105.165'
}
auth = HTTPProxyAuth('username', 'mypassword')
r = requests.get("http://www.google.com", proxies=proxyDict, auth=auth)
I've been having a similar problem on Windows and found the only way to get requests to work was to set the proxies as environment variables before I started Python. For you this would be something like this:
set HTTP_PROXY=http://77.75.105.165
set HTTPS_PROXY=https://77.75.105.165
You might also want to check is there's a specific port required, and if so set it after the url. For example, if the port is 8443 then do:
set HTTP_PROXY=http://77.75.105.165:8443
set HTTPS_PROXY=https://77.75.105.165:8443
You can use urllib library for this.
from urllib import request
request.urlopen("your URL", proxies=request.getproxies())

OAuth Gdata Python Client throws stacktrace on RSA_KEY

Moving on from AuthSub to OAuth, I think I'm slowly beginning to understand the process.
This one threw me an error though:
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
from gdata.calendar import service
import gdata
from gdata.alt.appengine import run_on_appengine
from google.appengine.api import users
from google.appengine.ext import db
from gdata.auth import OAuthSignatureMethod, OAuthToken, OAuthInputParams
import urllib
import simplejson
import gdata.gauth
from google.appengine.runtime.apiproxy_errors import CapabilityDisabledError
SCOPES = 'https://www.google.com/calendar/feeds/' # in this case just one, but for future reference, just concatenate different scopes with a space in between
CONSUMER_KEY = 'jmm-timeline.appspot.com'
CONSUMER_SECRET = 'consumer secret key, here'
SIG_METHOD = gdata.auth.OAuthSignatureMethod.RSA_SHA1
f = open('remotekey.pem')
RSA_KEY = f.read()
f.close()
# Incomplete bibliography
# http://www.youtube.com/watch?v=bfgO-LXGpTM
# http://code.google.com/appengine/articles/python/retrieving_gdata_feeds.html
class BasePage(webapp.RequestHandler):
title = "Joshua's Construction Zone"
def write_page_header(self):
self.response.out.write(template.render('templates/header.html', {'title': self.title}))
def write_page_footer(self):
self.response.out.write(template.render('templates/footer.html', {}))
class MainHandler(BasePage):
def get(self):
self.write_page_header()
try:
client = gdata.calendar.service.CalendarService(source='jmm-timeline-v1')
run_on_appengine(client)
client.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.RSA_SHA1, consumer_key=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, rsa_key=RSA_KEY)
req_token = client.FetchOAuthRequestToken(SCOPES)
oauth_callback_url = 'http://jmm-timeline.appspot.com/handle_authorized_request_token'
oauth_authorization_url = client.GenerateOAuthAuthorizationURL(callback_url=oauth_callback_url)
self.response.out.write(template.render('templates/authorization_prompt.html', { 'authorization_url': oauth_authorization_url }))
except CapabilityDisabledError, e:
self.response.out.write(template.render('templates/content/maintenance.html'))
self.write_page_footer()
class HandleAuthorizedRequestToken(BasePage):
def get(self):
self.write_page_header()
client = gdata.calendar.service.CalendarService('jmm-timeline-2');
run_on_appengine(client)
self.write_page_footer()
def main():
application = webapp.WSGIApplication([('/', MainHandler), ('/handle_authorized_request_token', HandleAuthorizedRequestToken)], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
It appears as if gdata is trying to read my RSA_KEY string, and I get a stacktrace:
Traceback (most recent call last):
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\webapp\__init__.py", line 515, in __call__
handler.get(*groups)
File "C:\Users\Joshua\appengineapps\jmm-timeline\main.py", line 52, in get
req_token = client.FetchOAuthRequestToken(SCOPES)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\service.py", line 415, in FetchOAuthRequestToken
extra_parameters=extra_parameters)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\auth.py", line 217, in GenerateOAuthRequestTokenUrl
oauth_input_params.GetConsumer(), None)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\oauth\__init__.py", line 171, in sign_request
self.set_parameter('oauth_signature', self.build_signature(signature_method, consumer, token))
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\oauth\__init__.py", line 175, in build_signature
return signature_method.build_signature(self, consumer, token)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\oauth\rsa.py", line 55, in build_signature
privatekey = keyfactory.parsePrivateKey(cert)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\keyfactory.py", line 203, in parsePrivateKey
return parseXMLKey(s, private=True)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\keyfactory.py", line 79, in parseXMLKey
key = Python_RSAKey.parseXML(s)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\Python_RSAKey.py", line 137, in parseXML
element = xmltools.parseAndStripWhitespace(s)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\xmltools.py", line 30, in parseAndStripWhitespace
raise SyntaxError(str(e))
SyntaxError: syntax error: line 1, column 0
tlslite has two keyformats: PEM and XML. It first tries PEM (see parsePrivateKey), and then falls back to XML. Apparently, there is an error in your PEM file, so PEM parsing fails (but should have succeeded). Parsing XML then clearly must fail.
My guess is that you messed up line endings somehow, but perhaps there is something even more fundamentally wrong with the PEM file.

Categories

Resources