如果返回的数据已更改,则使用 Flask 轮询 API 并更新网页
Posted
技术标签:
【中文标题】如果返回的数据已更改,则使用 Flask 轮询 API 并更新网页【英文标题】:Polling an API with Flask and updating webpage if returned data has changed 【发布时间】:2022-01-20 20:25:09 【问题描述】:我正在使用后端的 Flask 构建自定义 Spotify 音乐播放器,以处理对 Spotify API 的调用。它从当前播放的曲目中获取信息并填充本地网页。我现在需要轮询 Spotify API(每 2 秒左右)以检查歌曲是否已更改,如果是,请更新网页(希望使用 javascript,因此无需刷新页面)。我不确定如何使用 Flask 进行此操作,或者是否有更好的方法来解决它。我相信我可以通过创建和调用异步函数来进行轮询来解决这个问题,但是如果发现了更改,我不确定从那里去哪里。
这是我到目前为止的 spotify 视图。我在 spotify.py 文件中的自定义 auth 和 now_playing 函数中使用了 spotipy 库。
@app.route('/spotify')
def spotify():
# Get Spotify instance and authorization token
authData = dev.auth()
sp = authData[0]
token = authData[1]
current = dev.now_playing(sp, token)
# Assign individual track information to variable for sending to web page via Jinja
separator = ', '
return render_template('spotify.html',
artists = separator.join(current[0]),
song = current[1],
album = current[2],
cover_url = current[3],
year = current[4],
auth_tok = token
)
我的 Web 开发经验有限,这是我第一次使用 Flask。我正在使用这个项目来了解更多信息,但遇到了这个障碍。
【问题讨论】:
【参考方案1】:概念
轮询 API 的一种好方法是在 javascript 中安排请求,然后等待一定时间(不超过 10-30 秒)让服务器保留请求以查看歌曲是否更改,然后返回结果。如果发现结果早于 10-30 秒,则服务器会提前返回。客户端将请求视为正在进行中,并且可以在服务器拥有它的整个窗口中接收它,只要请求不超时(超过 30+ 秒左右)。您也可以每隔几秒钟简单地请求一次 url 来检查,但这会占用大量系统资源。
API 代码
from flask import Flask, redirect
song = "" # global identifier
@app.route("/track", methods=["GET"])
def track():
for _ in range(10):
time.sleep(1)
global song # regrab the song value every iteration
current = dev.now_playing(sp, token) # get current song
if current[1] != song: # song changed
song = current[1]
return redirect("http://www.website.com/spotify", code=302) #essentially an automatic refresh by redirecting to itself, and will regrab the song data!
return , 200 # give the client SOMETHING so the request doesn't timeout and error
@app.route('/spotify')
def spotify():
global song
# Get Spotify instance and authorization token
authData = dev.auth()
sp = authData[0]
token = authData[1]
current = dev.now_playing(sp, token)
# Assign individual track information to variable for sending to web page via Jinja
separator = ', '
song = "" # assign the song value to whatever is sent to the client
return render_template('spotify.html',
artists = separator.join(current[0]),
song = current[1],
album = current[2],
cover_url = current[3],
year = current[4],
auth_tok = token
)
提供的代码将接受来自客户端的请求,然后检查代表客户端上次刷新页面时的歌曲的值 global song
是否与 API 正在使用的当前歌曲不同。在这种情况下,服务器将发送一个重定向代码,因此客户端将重定向并实质上刷新它所在的当前页面,从而获取歌曲和信息!
Javascript
javascript 代码将使用简单的请求,并使用 GET 持续获取端点 /track 上的服务器数据。可以找到here 或简单地自己研究 javascript get 请求。要连续发出请求,请使用以下代码。
function stopFunction()
clearInterval(myVar); // stop the timer
$(document).ready(function()
myVar = setInterval("makeRequest()", 1000);
);
这不是我提供的可扩展代码,但应该适用于私人访问,并且可以在概念上适应可扩展端点。
【讨论】:
这似乎正是我所需要的,谢谢。我现在几乎在歌曲更改后立即看到正确的重定向响应。我现在遇到的问题实际上是使用新歌曲数据更新网页,因为来自 /poll 的重定向实际上并没有刷新页面。我认为最好的方法是将新歌曲数据从 Flask 发送到 JS 文件,并使用 AJAX 更新专辑封面 url、歌曲标题等。我不确定如何将所需的数据添加到响应中并从那里更改页面。 您可以像您提到的那样将所有数据作为 json 对象重新发送,然后执行 document.innerHtml 并将现有元素更改为新值。我建议不要发送整个模板,因为那样 URL 会完全改变,但页面看起来还是一样的,而且不好。我会看看我是否可以找出重定向,然后如果可以的话编辑我的回复。很高兴为您提供帮助,祝您有美好的一天!以上是关于如果返回的数据已更改,则使用 Flask 轮询 API 并更新网页的主要内容,如果未能解决你的问题,请参考以下文章