KartikTalwar / Duolingo

Unofficial Duolingo API Written in Python
MIT License
826 stars 128 forks source link

Translations stopped working today #125

Open allenweiss opened 2 years ago

allenweiss commented 2 years ago

For the past several months, this worked fine but now I'm getting this when I call this

lingo.get_translations(word to translate, source=sr, target=tg)

duolingo.DuolingoException: Could not get translations

Anybody run into this problem?

Otto-AA commented 2 years ago

The same happens to me.

My code looks like this:

lingo = duolingo.Duolingo(username, password)
translations = lingo.get_translations(['da'], source='ro', target='en')

which makes a request to this url: https://d2.duolingo.com/api/1/dictionary/hints/ro/en?tokens=%5B%22da%22%5D

with the following 404 response:


<html>
 <head>
  <title>404 Not Found</title>
 </head>
 <body>
  <h1>404 Not Found</h1>
  The resource could not be found.<br/><br/>
/api/1/dictionary/hints/ro/en

 </body>
</html>
JASchilz commented 1 year ago

Another library user here. Following @Otto-AA 's link, now results in:

This site can’t be reached d2.duolingo.com’s server IP address could not be found.

I'm guessing that this particular endpoint is not coming back. :)

I've been casually searching but haven't yet found any other projects in other languages that identify an alternative for this endpoint. If anyone does, could you post it here?

allenweiss commented 1 year ago

I just switched to googletrans It does everything I need in translations.

mbrookes commented 1 year ago

I'm using https://github.com/ssut/py-googletrans. Translations for single words can be problematic when the word has more than one meaning or part of speech, but it's good enough for my purposes.

## Returns a list of all vocabulary seen by user, arranged by parts of speech

import duolingo
import inspect
import googletrans

# Fix for broken password support - use JWT inst
source = inspect.eadgetsource(duolingo)
new_source = source.replace('jwt=None', 'jwt')
new_source = source.replace('self.jwt = None', ' ')
exec(new_source, duolingo.__dict__)

lingo  = duolingo.Duolingo('username', jwt='your_jwt_here')
translator = googletrans.Translator()

allwords = []
vocab = lingo.get_vocabulary(language_abbr='pt')

for element in vocab['vocab_overview']:
    if element['pos'] == "Verb":
        word = {'word': element['infinitive'], 'pos': element['pos']}
    else:
        word = {'word': element['word_string'], 'pos': element['pos']}

    if word not in allwords:
        allwords.append(word)

# Vocabulary is returned most recently practiced first, so reverse it
allwords.reverse()

parts = [
    'Noun',
    'Verb',
    'Pronoun',
    'Adjective',
    'Adverb',
    'Preposition',
    'Determiner',
    'Conjunction',
    'Interjection',
    'Numeral'
]

print('\nVocabulary:')

for pos in parts:
    print('\n\n{pos}s:\n'.format(pos=pos))
    for element in allwords:
        if element["pos"] == pos:
            print('{word} - {trans}'.format(
                word=element["word"],
                trans=translator.translate(element["word"], src='pt', dest='en').text)
            )

Worth noting that you can pass an array and have it translate words in bulk, but one at a time was easier here, and I haven't hit any rate limits yet.