Как программным образом подать данные в приглашение python 'input ()'? - PullRequest
0 голосов
/ 02 марта 2019

Я использую оболочку Python для API Spotify.

https://spotipy.readthedocs.io/en/latest/#installation

В рамках процесса авторизации API Spotify имеет логин пользователя для входа в Spotify в веб-интерфейсе по умолчанию.браузер, а затем отправляет их в предопределенный (при регистрации приложения в Spotify) REDIRECT_URI.Этот REDIRECT_URI в настоящее время установлен на localhost: 6969.Как только вы входите в систему, он порождает input () (Input of Death), чтобы вы скопировали и вставили URI, на который вы были перенаправлены, в командную строку.

Я действительно не хочу продавать случайных людей при использованииКомандная строка.

Цель состоит в том, чтобы открыть флеш-сервер на локальном хосте: 6969 (подать в суд), а затем дважды нажать на его / страницу авторизации (отправить в oauth2, затем ввести код)

http://flask.pocoo.org/docs/1.0/

Итак -

Я держу свою флягу и снайперскую ловушку в jflask.py:

from flask import Flask, request, redirect, session
from requests_oauth2 import OAuth2
from spotipy import Spotify
import spotipy.util as util
import requests
import datetime

app = Flask(__name__)

spotify_auth = OAuth2(
  client_id='e33c6fa0d6a249ccafa232a9cf62a616',
  client_secret='a43b0b6a4de14b97b4e468459e0f7824',
  redirect_uri="http://localhost:6969/authorize",
  site="https://accounts.spotify.com",
  authorization_url="/authorize",
  token_url="/api/token",
  scope_sep=" "
)

# and then use this url as a link within a public login view
print(spotify_auth.authorize_url(
  scope=["user-read-recently-played", "user-top-read"],
  response_type="code"
  )
)
# and have an authorize route that can direct you to Spotify or handle you 
#being redirected back here from Spotify
@app .route('/authorize')
def authorize():

  print('triggered')

  error = request.args.get("error")
  if error:
    abort(404)

  code = request.args.get("code")
  if code:
    data = spotify_auth.get_token(
      code=code,
      grant_type="authorization_code",
    )
    access_token = data["access_token"]
    refresh_token = data["refresh_token"]
    scopes = data["scope"].split()
    self.sp = spotipy.Spotify(auth=access_token)
    print(access_token)
    return self.sp
  else:
    print('code aint defined hoe')
    return redirect(spotify_auth.authorize_url(
      scope=["user-read-recently-played", "user-top-read"],
      response_type="code",
      #state=session['state']
    ))

if __name__ == '__main__':
  app.run(host='localhost', port=6969)

Я вызываю ее с master.py:

from subprocess import Popen, PIPE
import webbrowser

jflask=Popen(['python', 'jflask.py'])

webbrowser.open('http://localhost:6969/authorize')

Я уже пробовал использовать Popen с stdout = PIPE.После дальнейших исследований я почти уверен, что это также мешало моему успеху.Спецификация предназначена для использования с subprocess.communicate ()

https://docs.python.org/3/library/subprocess.html#subprocess.PIP

Спасибо всем за помощь.

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Метод Spotipy prompt_for_user_token предоставляется как быстрый и грязный метод, позволяющий кому-либо, использующему модуль локально, приступить к работе и не предназначен для того, чтобы быть кодом, который должен быть построен непосредственно, если вы хотите, чтобы произвольные пользователи моглиаутентифицировать себя через веб-сайт.Поскольку у вас есть приложение Flask, вероятно, оно и ваш код Spotipy взаимодействуют напрямую через импорт, а не через каналы и стандартный ввод / вывод.

Некоторые вещи, на которые следует обратить внимание:

  • Flask-Login , если вы хотите управлять пользователями, входящими на веб-сайт
  • Альтернативные методы передачи аутентификации на spotipy.Spotify, кроме простого токена доступа (менеджер учетных данных клиента или requests)сессия).Эти другие методы позволяют клиенту Spotipy обновлять токен доступа, если он истекает в середине использования, обрабатывать пользовательские аннулирования и т. Д.
  • request-oauth2 (обратите внимание, что это только один из многих OAuth2Python любит и, возможно, не самый лучший), что делает все средства авторизации немного более удобными и позволяет сделать что-то вроде:
# import Flask things, requests-oauth2, 
from requests_oauth2 import OAuth2
from spotipy import Spotify
from flask import redirect

spotify_auth = OAuth2(
    client_id=os.environ["SPOTIFY_CLIENT_ID"],
    client_secret=os.environ["SPOTIFY_CLIENT_SECRET"],
    redirect_uri=f"http://{os.environ['HOST_NAME']}/authorize",
    site="https://accounts.spotify.com",
    authorization_url="/authorize",
    token_url="/api/token",
    scope_sep=" "
)

# and then use this url as a link within a public login view
spotify_auth.authorize_url(
    scope=["user-read-recently-played", "user-top-read"],
    response_type="code"
)

# and have an authorize route that can direct you to Spotify or handle you being redirected back here from Spotify
@app.route('/authorize')
def authorize():

    error = request.args.get("error")
    if error:
        abort(404)

    code = request.args.get("code")
    if code:
        data = spotify_auth.get_token(
            code=code,
            grant_type="authorization_code",
        )
        access_token = data["access_token"]
        refresh_token = data["refresh_token"]
        scopes = data["scope"].split()
        spotify_client = spotipy.Spotify(auth=access_token)
    else:
        return redirect(spotify_auth.authorize_url(
            scope=["user-read-recently-played", "user-top-read"],
            response_type="code",
            state=session['state']
        ))

При первом посещении /authorize этоперенаправит пользователя на страницу входа в Spotify.Но когда пользователь успешно входит в систему, он перенаправляет пользователя обратно на сайт Flask (обратно к /authorize), а не выполняет копирование / вставку части prompt_for_user_token().

, как только он снова включается./authorize, на этот раз есть параметр запроса code, поэтому он делает запрос клиента-поставщика OAuth2 на преобразование этого кода в токены доступа для вас.

И этот, и prompt_for_user_token следуюттот же подход:

  1. Получите URL-адрес авторизации Spotify, чтобы направить пользователя на вход в
  2. Обработка перенаправления из Spotify Login - Flask делает это, получая входные данные от URL-адреса, на который перенаправляет Spotifyи prompt_for_user_token делает это путем копирования / вставки URL-адреса с несуществующей веб-страницы.
  3. Выполните вызов для преобразования кода в доступ и обновления токенов для пользователя.

Возможно, я немного убил этот код, потому что он выбран из моей старой реализации Flask моей интеграции Spotify.Вот более полная суть , но я почти уверен, что многие вещи SQLAlchemy, представление авторизации, довольно плохие, так что возьмите это с щепоткой соли.

0 голосов
/ 03 марта 2019

Вы можете попробовать изменить модуль утилит.Замените блок try-exc на response = raw_input () внутри:

response = sys.stdin.readline().strip()

Не забудьте импортировать sys, если он еще не импортирован.

Это должно позволить нормальную PIPE-ing.

Или вы можете использовать библиотеку pexpect вместо модуля подпроцесса.Он знает, как обрабатывать ввод, который настроил флаги fcntl терминала или использует mscvrt в Windows.

Кроме того, когда PIPE-данные, не забывайте, что raw_input (), input () или sys.stdin.readline () не вернется, пока не получит соответствующий символ конца строки."\ r", "\ n" или "\ r \ n".Вы уже отправляли его с URL авторизации?

...