Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

401 Unauthorized on Python 3.3 #1

Open
jaraco opened this issue Mar 28, 2014 · 5 comments
Open

401 Unauthorized on Python 3.3 #1

jaraco opened this issue Mar 28, 2014 · 5 comments

Comments

@jaraco
Copy link

jaraco commented Mar 28, 2014

I tested the library on Python 3.4, and it seems to be working. I then deployed it on a system running Python 3.3 and I get 401 Unauthorized errors. Consider this test script:

import sys
short_ver = '{vi[0]}.{vi[1]}'.format(vi=sys.version_info)

sys.path.insert(0, './wordnik_py3-2.1.2-py{vi}.egg'.format(vi=short_ver))

import wordnik.WordApi
import wordnik.swagger

key = 'elided'
client = wordnik.swagger.ApiClient(key, 'http://api.wordnik.com/v4')
words = wordnik.WordApi.WordApi(client)
words.getDefinitions('dachshund', limit=1)

If I have the wordnik-py3 2.1.2 eggs for Python 3.3 and Python 3.4 in the current directory, I can then run the above script for each. On Python 3.4, it passes without error. On Python 3.3, I get this traceback:

Traceback (most recent call last):
  File ".\test-wn.py", line 12, in <module>
    words.getDefinitions('dachshund', limit=1)
  File "./wordnik_py3-2.1.2-py3.3.egg\wordnik\WordApi.py", line 182, in getDefinitions
    postData, headerParams)
  File "./wordnik_py3-2.1.2-py3.3.egg\wordnik\swagger.py", line 73, in callAPI
    request = urllib.request.urlopen(requestParams)
  File "C:\Program Files\Python33\lib\urllib\request.py", line 156, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Program Files\Python33\lib\urllib\request.py", line 475, in open
    response = meth(req, response)
  File "C:\Program Files\Python33\lib\urllib\request.py", line 587, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Program Files\Python33\lib\urllib\request.py", line 513, in error
    return self._call_chain(*args)
  File "C:\Program Files\Python33\lib\urllib\request.py", line 447, in _call_chain
    result = func(*args)
  File "C:\Program Files\Python33\lib\urllib\request.py", line 595, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: Unauthorized

I'm using the exact same script, so the difference appears to be in how WordNik assembles the HTTP request on Python 3.3, somehow triggering the 401.

@jaraco
Copy link
Author

jaraco commented Mar 28, 2014

In case it wasn't clear, I'm supplying a valid API key in line 9.

@jaraco
Copy link
Author

jaraco commented Jul 2, 2014

The issue lies with wordnik.swagger in the MethodRequest class. Only on Python 3.3, for any request where the method isn't specified, get_method returns the empty string. This was a defect I identified in Python 3.3 and which I patched for Python 3.4.

@jaraco
Copy link
Author

jaraco commented Jul 2, 2014

In jaraco.net, I've developed a more robust MethodRequest that works on multiple Python versions, including 3.3:

class MethodRequest(urllib.request.Request):
    method = None

    def __init__(self, *args, **kwargs):
        """
        Construct a MethodRequest. Usage is the same as for
        `urllib.request.Request` except it also takes an optional `method`
        keyword argument. If supplied, `method` will be used instead of
        the default.
        """
        method = kwargs.pop('method', self.method)
        urllib.request.Request.__init__(self, *args, **kwargs)
        # write the method after __init__ as Python 3.3 overrides the value
        self.method = method

    def get_method(self):
        return getattr(self, 'method') or urllib.request.Request.get_method(self)

Consider using that technique in Wordnik.

@jaraco
Copy link
Author

jaraco commented Jul 2, 2014

Even that implementation has problems in some cases on some Pythons. I've put together a backports library: backports.method_request which is tested on Python 2.6+. Consider using that library or copying that code into Wordnik3.

@jaraco
Copy link
Author

jaraco commented May 13, 2021

At this point, I'd just recommend dropping support for Python 3.3 and earlier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant