我正在为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
谢谢大家的帮助。
答案 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。
需要研究的一些事情是
spotipy.Spotify
会话)以外,将auth传递到requests
的替代方法。这些其他方法允许Spotipy客户端在访问令牌在使用中到期时刷新访问令牌,处理用户吊销等。# 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
都采用相同的方法:
prompt_for_user_token
则是通过从不存在的网页中复制/粘贴该URL来完成此操作。 / li>
我可能对此代码略有保留,因为它是从我的Spotify集成的旧Flask实现中挑选出来的。这是more complete gist,但我可以肯定,很多SQLAlchemy东西(授权视图)都非常糟糕,因此请稍加加盐。