wordnik / wordnik-python3

wordnik python3 library
74 stars 13 forks source link

swagger imports urllib2 #10

Closed jjon closed 1 year ago

jjon commented 1 year ago

Following the basic setup in the readme, running python3.9 on MacOS 11.6 the response to from wordnik import * is this:

    from wordnik import *
  File "/opt/homebrew/lib/python3.9/site-packages/wordnik/swagger.py", line 11, in <module>
    import urllib2
ModuleNotFoundError: No module named 'urllib2'

I don't have urllib2 and it's no longer practical to get it because, as the urllib2 docs say:

The urllib2 module has been split across several modules in Python 3 named urllib.request and urllib.error. The 2to3 tool will automatically adapt imports when converting your sources to Python 3.

So, am I missing something obvious? If so, apologies for the noise. -j

jjon commented 1 year ago

Again, apologies for fumbling about in my ignorance, but wordnik py3 shows me some odd behavior: I tried the standard setup using my conda install of py3.8 and got further than I did with py3.9 described above.

after importing sys, urllib, and from wordnik import *:

apiUrl = 'http://api.wordnik.com/v4'
apiKey = my api key
client = swagger.ApiClient(apiKey, apiUrl)
wordApi = WordApi.WordApi(client)

so far so good, but now wordApi.getWord('pride') gets me an HTTP error 422:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/My/Path/opt/anaconda3/lib/python3.8/site-packages/wordnik/WordApi.py", line 122, in getWord
    response = self.apiClient.callAPI(resourcePath, method, queryParams,
  File "/My/Path/opt/anaconda3/lib/python3.8/site-packages/wordnik/swagger.py", line 73, in callAPI
    request = urllib.request.urlopen(requestParams)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 640, in http_response
    response = self.parent.error(
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 563, in error
    result = self._call_chain(*args)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 755, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 640, in http_response
    response = self.parent.error(
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/My/Path/opt/anaconda3/lib/python3.8/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 422:

but on the other hand wordApi.getDefinitions() gets me a coherent response:

>>> [x.text for x in wordApi.getDefinitions('irony')]
[None, 'The use of words to express something different from and often opposite to their literal meaning.', 'An expression ... etc ...]

Is this just a neophyte being obtuse, or is there a problem here?

-- jon

hugovk commented 1 year ago

Following the basic setup in the readme, running python3.9 on MacOS 11.6 the response to from wordnik import * is this:

    from wordnik import *
  File "/opt/homebrew/lib/python3.9/site-packages/wordnik/swagger.py", line 11, in <module>
    import urllib2
ModuleNotFoundError: No module named 'urllib2'

You have the Python 2 library installed, it has urllib2 at line 11:

https://github.com/wordnik/wordnik-python/blob/fd487d016852ce33cc651b94a1f5c5231f9be7a9/wordnik/swagger.py#L11

Whilst the Python 3 one does not: https://github.com/wordnik/wordnik-python3/blob/a0068acb0645e15b38f71d1a1cf15a2a84882110/wordnik/swagger.py#L11

Make sure to uninstall both copies first, then install just this Python 3 one.

jjon commented 1 year ago

Thanks @hugovk for your very helpful comment. I've now got the right module loaded wordnik-py3. (too many python installations!)

>>> wordnik
<module 'wordnik' from '/opt/homebrew/lib/python3.9/site-packages/wordnik/__init__.py'>

Now some stuff works, but I'm still getting 422 error from the method wordApi.getWord(). Each of the other methods of wordApi returns the expected data. I tried each in turn:

>>> type(wordApi.getDefinitions('irony'))
<class 'list'>
>>> type(wordApi.getAudio('irony'))
<class 'list'>
>>> type(wordApi.getEtymologies('irony'))
<class 'list'>
>>> type(wordApi.getExamples('irony'))
<class 'wordnik.models.ExampleSearchResults.ExampleSearchResults'>
>>> type(wordApi.getHyphenation('irony'))
<class 'list'>
>>> type(wordApi.getPhrases('irony'))
<class 'list'>
>>> type(wordApi.getRelatedWords('irony'))
<class 'list'>
>>> type(wordApi.getScrabbleScore('irony'))
<class 'wordnik.models.ScrabbleScoreResult.ScrabbleScoreResult'>
>>> type(wordApi.getTextPronunciations('irony'))
<class 'list'>
>>> type(wordApi.getTopExample('irony'))
<class 'wordnik.models.Example.Example'>
>>> type(wordApi.getWordFrequency('irony'))
<class 'wordnik.models.FrequencySummary.FrequencySummary'>

but wordApi.getWord('irony') always returns the 422 error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/lib/python3.9/site-packages/wordnik/WordApi.py", line 122, in getWord
    response = self.apiClient.callAPI(resourcePath, method, queryParams,
  File "/opt/homebrew/lib/python3.9/site-packages/wordnik/swagger.py", line 73, in callAPI
    request = urllib.request.urlopen(requestParams)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 555, in error
    result = self._call_chain(*args)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 747, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/opt/homebrew/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 422:

Something obvious I'm not getting, I'm sure. If so, again, apologies for the noise.

--Jon

hugovk commented 1 year ago

Looks like the API endpoint is no longer available on Wordnik, and this library needs updating.

In this library, getWord calls '/word.{format}/{word}' where format can be json:

https://github.com/wordnik/wordnik-python3/blob/a0068acb0645e15b38f71d1a1cf15a2a84882110/wordnik/WordApi.py#L105

For example, this also has a 422 error in the console:

https://api.wordnik.com/v4/word.json/hat?useCanonical=false&api_key=YOURAPIKEY

Compare with a working example:

https://api.wordnik.com/v4/word.json/hat/topExample?useCanonical=false&api_key=YOURAPIKEY

Ping @emckean

jjon commented 1 year ago

Further tyronic fooling around leads me to Hugo's conclusion as well ( @hugovk ): This python library is dramatically out of date. My untutored impression is that the wordnik API (v4) has been dramatically changed. The only documentation I've been able to find makes no mention at all of many of the methods described in the wordnik-python3.py, and, this "docs" page hardly qualifies as "documentation" at all, but rather a sort of automatically generated form that offers nothing in the way of context, usage, examples, best practices, use cases. If there are other sources of documentation that I've not discovered, I'd love to hear about them.

This is a pity. I was a fan of wordnik a few years ago, but upon returning to it, I find it moribund.

import urllib
import time
from wordnik import *

apiUrl = 'http://api.wordnik.com/v4'
apiKey = 'myapikey'
client = swagger.ApiClient(apiKey, apiUrl)

It's possible to get instances of all these classes, but a great many of the methods for these classes fail.

wordApi = WordApi.WordApi(client)
acctApi = AccountApi.AccountApi(client)
WLApi = WordListApi.WordListApi(client)
wllapi = WordListsApi.WordListsApi(client)
wdsApi = WordsApi.WordsApi(client)

The WordApi is discussed in my comment above. Its methods succeed, save for wordApi.getWord

AccountApi

acctApi.getApiTokenStatus() # fails with `HTTP Error 410: Gone`
acctApi.getWordListsForLoggedInUser(apiKey) # fails with `HTTP Error 422:`
acctApi.authenticate('myusername','mypassword') # should return an auth token, but fails with `HTTP Error 422:`
acctApi.getLoggedInUser(apiKey) # fails with `HTTP Error 422:`

The wordnik "Docs" have no mention of any of these account functions. Indeed, a host of stuff in the python library seems to call upon wordnik API 'endpoints' that I can find no documentation for.

WordListApi

cromulent = 'https://www.wordnik.com/lists/cromulent-words--1'
WLApi.addWordsToWordList(cromulent, apiKey) # fails with `HTTP Error 422:`
WLApi.getWordListByPermalink(cromulent, apiKey) # fails with `HTTP Error 422:`
WLApi.getWordListWords(cromulent, apiKey) # fails with `HTTP Error 422:`

the help() text for these methods all call for an auth_token:

"auth_token, str: The auth token of the logged-in user, obtained by calling /account.{format}/authenticate/{username} (described above) (required)"

But that 'endpoint' does not seem to exist and the apiKey does not work in its stead.

WordListsApi

wllapi.createWordList(apiKey) # fails with `HTTP Error 422:`

WordsApi wdsApi.getRandomWord() # succeeds

Ping @emckean

emckean commented 1 year ago

Hi, sorry for taking so long to reply to this issue. Yes, the /words and /lists endpoints have been deprecated, that's why they're returning 422 errors. Since auth_token was only needed to access the lists, that endpoint has also been deprecated. Since we're now a tiny 501c3 nonprofit, unfortunately we don't have the resources to maintain this library; volunteers are welcome!

For advance notice of changes to the Wordnik API, please subscribe our beta-testers list: http://eepurl.com/bPCg0D