如何以编程方式将数据输入到python的“input()”提示符中?

问题描述 投票:2回答:2

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

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

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

我真的不想让随机的人使用命令提示符。

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

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

所以 -

我保留了我的Flask装备并在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')

我已经尝试过使用带有stdout = PIPE的Popen。经过进一步的研究,我很确定这也抑制了我的成功。该规范旨在与subprocess.communicate()一起使用

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

感谢大家的帮助。

python flask subprocess pipe spotipy
2个回答
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 Client-to-Provider请求将此代码转换为访问令牌。

这和prompt_for_user_token都遵循相同的方法:

  1. 获取Spotify授权URL以指导用户登录
  2. 处理Spotify登录中的重定向 - Flask通过接收Spotify重定向到的URL的输入来执行此操作,prompt_for_user_token通过从不存在的网页复制/粘贴URL来执行此操作。
  3. 进行调用以将代码转换为访问权限并为用户刷新令牌。

我可能已经对这段代码进行了一些屠杀,因为它是从我的Spotsk集成的旧Flask实现中挑选出来的。这是一个more complete gist,但我很确定很多SQLAlchemy的东西,授权视图,非常糟糕,所以拿一点盐。


1
投票

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

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

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

这应该允许正常的PIPE。

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

此外,在PIPE-ing数据时,不要忘记raw_input(),input()或sys.stdin.readline()在收到适当的行尾字符之前不会返回。 “\ r”,“\ n”或“\ r \ n”。您之前是否使用授权URL发送了它?

© www.soinside.com 2019 - 2024. All rights reserved.