【问题标题】:Polling an API with Flask and updating webpage if returned data has changed如果返回的数据已更改,则使用 Flask 轮询 API 并更新网页
【发布时间】: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。我正在使用这个项目来了解更多信息,但遇到了这个障碍。

【问题讨论】:

    标签: javascript python flask asynchronous spotify


    【解决方案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 会完全改变,但页面看起来还是一样的,而且不好。我会看看我是否可以找出重定向,然后如果可以的话编辑我的回复。很高兴为您提供帮助,祝您有美好的一天!
    猜你喜欢
    • 2014-01-08
    • 1970-01-01
    • 2021-04-04
    • 2013-01-30
    • 2018-07-09
    • 2014-07-08
    • 1970-01-01
    • 2014-03-06
    • 2021-12-01
    相关资源
    最近更新 更多