Hi everyone!
Introduction
I'm currently working on a project where I'm creating an independent controller to manage Spotify player using their API. The controller is intended to expose localhost for authorization with a Spotify account. All basic controller functions are to be executed using physical switches, and data will be displayed on a simple TFT display.
What I'm using
Raspberry Pi Pico WH(main controller board)CircuitPythonby Adafruit (Python software)- Various Adafruit libraries (listed in code)
Problem
While writing the software, I encountered a rather strange issue that I don't fully understand.
When sending the second request to the API (using HTTP-GET protocols via the Adafruit_requests lib), the compiler reported a critical memory error. Placing the request.get(...) function within a try-except block only resulted in an empty error message.
Interestingly, this situation only occurs when sending a request to the Spotify API. For example, when I used worldtimeapi as the URL address, everything worked correctly, and I received a response in JSON format.
Here's my code:
import board, time
import os, json
import socketpool, wifi, ipaddress
import adafruit_requests, ssl
from adafruit_httpserver import Server, Request, Response, Redirect, FileResponse, GET, POST, Headers
from circuitpython_parse import urlencode
# Spotify API
# ****************************************************************
# Variables (...)
# Server
# ****************************************************************
ssid = os.getenv("WIFI_SSID")
password = os.getenv("WIFI_PASSWORD")
wifi.radio.connect(ssid, password)
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context()) # HTTP requests
server = Server(pool, "/static", debug=True)
# Routing
# ****************************************************************
@server.route("/")
def base(request: Request):
return FileResponse(request, "index.html", "/public")
@server.route('/login')
def login(request: Request):
scope = # (...)
params = # (...)
auth_url = f"https://accounts.spotify.com/authorize?{urlencode(params)}"
return Redirect(request, auth_url)
@server.route('/callback')
def callback(request: Request):
if 'code' in request.query_params.fields:
req_body = # (...)
try:
TOKEN_URL = "https://accounts.spotify.com/api/token"
response = requests.post(TOKEN_URL, data=req_body) # Works fine
token_info = response.json()
response.close()
global access_token, refresh_token, expires_at
access_token = token_info['access_token']
refresh_token = token_info['refresh_token']
expires_at = time.time() + token_info['expires_in'])
except Exception as e:
print("Error-callback:\n", str(e))
return Redirect(request, "/main")
@server.route('/main')
def main(request: Request):
try:
req_url = "https://api.spotify.com/v1/me/player/currently-playing"
# req_url = "http://worldtimeapi.org/api/timezone/Europe/London" # Test Non-Spotify API
req_headers = {'Authorization': f"Bearer {access_token}"}
response = requests.get(req_url, headers=req_headers) # ERROR
curr_playing = response.json()
response.close()
except Exception as e:
print("Error-main:\n", str(e))
return FileResponse(request, "main.html", "/public")
# Main APP
# ****************************************************************
server.serve_forever(str(wifi.radio.ipv4_address)) # Start localhost
while True:
# Code...
I don't understand what is causing this error.
I've tried many methods, but none of them helped.
- At first, I thought it might be a synchronization issue, but importing asyncio isn't possible because for some reason the module doesn't exist.
- It might be due to the limited memory of the RP Pico W (but I'm not sure about that).
- I also found a relatively similar thread here, but it wasn't very helpful for me.
I would appreciate help, advice, suggestions, or tips. Thank you in advance.