Yahoo API - невозможно запросить новый токен доступа после истечения срока действия предыдущего токена доступа - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь использовать API Yahoo для фэнтези-футбола. Сначала я могу получить токен доступа и обновить токен sh, но как только этот токен доступа истек, я не могу получить другой.

Мой код выглядит следующим образом:

from requests import Request, get, post
import webbrowser
import base64

baseURL = 'https://api.login.yahoo.com/'
oauthENDPOINT = "https://api.login.yahoo.com/oauth2/request_auth"


## Generate a url using the endpoint and parameters above
params = {'client_id' : client_id,
          'redirect_uri' : "oob",
          'response_type' : 'code'}
p = Request('GET', oauthENDPOINT, params=params).prepare()

webbrowser.open(p.url)

Последняя строка отправляет меня на веб-сайт Yahoo, где я разрешаю себе доступ и получаю authCode.

encoded = base64.b64encode((client_id + ':' + client_secret).encode("utf-8"))
headers = {
    'Authorization': f'Basic {encoded.decode("utf-8")}',
    'Content-Type': 'application/x-www-form-urlencoded'
}
data = {
    'grant_type': 'authorization_code',
    'redirect_uri': 'oob',
    'code': authCode}

tokenResponse = post(baseURL + 'oauth2/get_token', headers=headers, data=data)
tokenResponseJSON = tokenResponse.json()
access_token = tokenResponseJSON['access_token']
refresh_token = tokenResponseJSON['refresh_token']

Теперь у меня есть вся информация, необходимая для проверки настроек моей лиги (например) .

fbURL = 'https://fantasysports.yahooapis.com/fantasy/v2'

leagueURL1 = f'{fbURL}/leagues;league_keys=nfl.l.{leagueID}/settings'

headers = {
    'Authorization': f'Bearer {access_token}',
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}

response2 = get(leagueURL1, headers=headers,params={'format': 'json'})

Вышеуказанное работает должным образом. Однако access_token длится 3600 секунд, и по истечении этого времени я не могу запросить новый, используя свой refresh_token. Моя попытка:

accessTokenData = {
    'grant_type': 'refresh_token',
    'redirect_uri': 'oob',
    'code': authCode,
    'refresh_token': refresh_token
}

accessTokenResponse = post(baseURL + 'oauth2/get_token', headers=headers, data=accessTokenData)
accessTokenJSON = accessTokenResponse.json()

В приведенном выше описании я надеюсь получить новый access_token, но вместо accessTokenJSON это:

{'error': {'localizedMessage': 'client request is not acceptable or not supported',
  'errorId': 'INVALID_INPUT',
  'message': 'client request is not acceptable or not supported'}}

До этого момента у меня есть выполнял эти шаги , которые до этого момента работали хорошо. Что я делаю не так? Я понимаю, что многие пользователи Python используют yahoo_oauth или rauth для аутентификации, но это предполагает сохранение client_id и client_secret в файле .json отдельно, и я хочу загрузить их динамически. Не думаю, что я очень далек от успеха, но мне просто что-то не хватает, когда дело доходит до создания нового refresh_token. Любая помощь очень ценится!

1 Ответ

1 голос
/ 08 мая 2020

Спасибо за обращение к нашему руководству.

Удалось воспроизвести вашу ошибку, и ее действительно просто решить.

Вы переопределяете переменную headers в своем запросе на URL-адрес fantasyspot.

Переменная headers должна быть такой же в вызове для запроса нового access_token с использованием refresh_token, как это было при первоначальном получении обоих токенов с использованием auth_code.

Поэтому просто определите header, прежде чем запрашивать новый access_token. Должно выглядеть примерно так:

headers = {
    'Authorization': f'Basic {encoded.decode("utf-8")}',
    'Content-Type': 'application/x-www-form-urlencoded'
}
response = post(base_url + 'oauth2/get_token', headers=headers, data=data)

Теперь должно работать.

Рекомендуется использовать разные имена переменных для headers, используемого для получения access_token, и того, что используется в фантазии спортивный URL.

...