Estoy construyendo un reproductor de música de Spotify personalizado usando Flask en el backend para manejar llamadas a la API de Spotify. Obtiene información de la pista que se está reproduciendo actualmente y llena la página web local. Ahora necesito sondear la API de Spotify (cada 2 segundos más o menos) para verificar si la canción ha cambiado y, de ser así, actualizar la página web (con suerte con JavaScript para que no haya necesidad de actualizar la página). No estoy seguro de cómo hacer esto con Flask o si hay un mejor método para hacerlo. Creo que puedo resolver el problema creando y llamando a una función asincrónica para realizar el sondeo, pero si se identificó un cambio, no estoy seguro de adónde ir desde allí.
Aquí está la vista de Spotify que tengo hasta ahora. Estoy usando la biblioteca spotipy dentro de las funciones de autenticación personalizada y now_playing en un archivo spotify.py.
@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 )Tengo una experiencia limitada en desarrollo web y esta es la primera vez que uso Flask. Estoy usando este proyecto para obtener más información, pero me he topado con este obstáculo.
Concepto
Una excelente manera de sondear las API es programar solicitudes en javascript y luego esperar una cierta cantidad de tiempo (no más de 10 a 30 segundos) para que el servidor retenga la solicitud para ver si la canción cambia y luego devolver el resultado. Si el resultado se encuentra antes de 10-30 segundos, el servidor lo devuelve antes. El cliente ve la solicitud como en progreso y puede recibirla en toda la ventana que el servidor tiene, siempre que la solicitud no se agote (más de 30 segundos más o menos). También puede simplemente solicitar la URL cada pocos segundos para verificar, pero eso usa muchos recursos del sistema.
Código 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 ) El código provisto tomará las solicitudes de un cliente, luego verificará si el valor global song que representa la canción cuando el cliente actualizó la página por última vez es diferente a la canción actual que usa la API. En el caso de que lo sea, el servidor enviará un código de redirección para que el cliente redirija y esencialmente actualice la página actual en la que se encuentra, ¡obteniendo así la canción y la información!
JavaScript
El código javascript usará solicitudes simples y capturará continuamente los datos del servidor en el punto final/pista usando GET. Se puede encontrar aquí o simplemente investigando por sí mismo solicitudes de obtención de javascript. Para hacer solicitudes continuamente, use el siguiente código.
function stopFunction(){ clearInterval(myVar); // stop the timer } $(document).ready(function(){ myVar = setInterval("makeRequest()", 1000); });Esta no es una pieza de código escalable que proporcioné, pero debería funcionar para el acceso privado y se puede adaptar conceptualmente a un punto final escalable.