如何以编程方式将数据馈入python'input()'提示符?

时间:2019-03-01 23:30:58

标签: python flask subprocess pipe spotipy

我正在为Spotify API使用python包装器。

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

作为授权过程的一部分,Spotify API让用户登录到其默认Web浏览器中的Spotify,然后将其发送到预定义的REDIRECT_URI(当您向Spotify注册​​应用程序时)。该REDIRECT_URI当前设置为localhost:6969。登录后,它会生成一个input()(死亡输入)供您复制,将您重定向到的URI复制粘贴到命令提示符中。

我真的不想在使用命令提示符时卖掉随机的人。

目标是在localhost:6969上打开一个Flask服务器(向我起诉),然后双击其/ authorize页面(发送到oauth2登录名然后捕获代码)

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

所以-

我保留了Flask装备并在jflask.py中发现了catcher:

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 :(得分:1)

您可以尝试修改util模块。 将try-except块替换为其中的response = raw_input()

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

如果尚未导入sys,请不要忘记导入它。

这应该允许正常的PIPE-ing。

或者您可以使用pexpect库代替子流程模块。它知道如何处理调整了终端的fcntl标志或在Windows上使用mscvrt的输入。

此外,当对数据进行PIPE处理时,请不要忘记raw_input(),input()或sys.stdin.readline()不会返回,直到它们收到适当的行尾字符。 “ \ r”,“ \ n”或“ \ r \ n”。您之前发送过带有授权URL的邮件吗?

答案 1 :(得分:1)

Spotipy的prompt_for_user_token方法是一种快速而肮脏的方法,它允许本地使用该模块的人启动并运行,并且如果要让任意用户使用,则不应将其作为直接构建的代码。能够通过网站进行身份验证。由于您拥有Flask应用,因此您可能应该拥有它,并且您的Spotipy代码可以直接通过导入进行交互,而不是使用管道和标准I / O。

需要研究的一些事情是

  • Flask-Login,如果您要管理登录网站的用户
  • 除了访问令牌(客户端凭据管理器或spotipy.Spotify会话)以外,将auth传递到requests的替代方法。这些其他方法允许Spotipy客户端在访问令牌在使用中到期时刷新访问令牌,处理用户吊销等。
  • requests-oauth2(请注意,这只是许多OAuth2 Python库之一,可能不是最好的),这使所有授权工作变得更加方便,并允许您执行以下操作:
# 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. 获取Spotify授权URL以指导用户登录
  2. 处理来自Spotify登录的重定向-Flask通过接收来自Spotify重定向到的URL的输入来完成此操作,而prompt_for_user_token则是通过从不存在的网页中复制/粘贴该URL来完成此操作。 / li>
  3. 进行调用以将代码转换为用户的访问和刷新令牌。

我可能对此代码略有保留,因为它是从我的Spotify集成的旧Flask实现中挑选出来的。这是more complete gist,但我可以肯定,很多SQLAlchemy东西(授权视图)都非常糟糕,因此请稍加加盐。