Code Monkey home page Code Monkey logo

asksonic's Introduction

AskSonic

AskSonic is an Alexa skill to play music from Subsonic API compatible music servers. It's powered by Flask-Ask and the Flask Python web framework.

Features

  • Shuffle music from your library
    • Ask sub sonic to play my library
  • Play music from an artist
    • Ask sub sonic to play music by Deftones
  • Play an album
    • Ask sub sonic to play the album Morning View by Incubus
  • Current track information
    • Ask sub sonic what song this is
    • Ask sub sonic what album this song is from
  • Star tracks
    • Tell sub sonic to star this song
    • Tell sub sonic to star the last song
  • List albums by artist
    • Ask sub sonic to list Yellowcard albums

Standard playback controls (Alexa: Pause, Resume, Previous, Next, etc.) can be used without using the skill's name. AskSonic will scrobble tracks with the server after they finish playing.

Planned Features

  • Play specific songs, playlists
  • Add specific songs to the play queue via interactive search

Setup

AskSonic can easily run alongside your Subsonic server. Once it's running, you'll need to Create the Alexa skill

Configuring the Subsonic server

It's recommended to use a non-admin user as we will be storing the login credentials in AskSonic's configuration. Consider how your Subsonic server handles play counts, starred tracks, playlists, etc. to decide if you want to create a new user account or use your existing one. You may want to configure transcoding for this user/player as Alexa has limited file-type support.

Running locally

If you instead prefer to host the AskSonic server yourself, you can follow these steps:

  1. Clone the repository and install requirements: pip install -r requirements.txt. AskSonic requires Python 3.9+
  2. Copy .env.example to .env and fill it in. See Configuration for further details
  3. Install foreman (Either the Gem or the Node version)
  4. You can start the server with foreman start. If you would like to run the server in debug mode, you can use the Procfile.dev instead
  5. Your AskSonic server will need to be publicly accessible over https with a valid certificate. The best option is to use a reverse proxy such as Caddy with a certificate from Let's Encrypt

Creating the Alexa Skill

  1. Visit the Alexa Console and select Create Skill. Use the same Amazon account that is logged in to your Alexa-powered device
  2. Enter a name for your skill (this doesn't affect how you invoke the skill from Alexa). Select Custom for the model and Provision your Own for the backend. Select Start from Scratch for the skill template
  3. Once the skill is created, from the skill menu, select Interaction Model -> JSON Editor and paste in the contents of your preferred language's interaction model (English: en.json). Then select Save Model. Check all available languages here
  4. Select Invocation from the menu. Here you can adjust how you invoke the skill from within Alexa
  5. Select Endpoint from the menu. Change to HTTPS and enter the URL to your AskSonic instance under Default Region. If you customized ASKS_ROUTE_PREFIX, add that to the end of the URL, otherwise add /alexa. Select the SSL certificate type.
  6. Select Interfaces from menu. Enable the Audio Player interface
  7. Select Save Model and Build Model

Important: Do not publish the skill as that would allow anyone to access your Subsonic server and potentially retrieve the login credentials

Configuration

Variable Description Required
ASKS_SUBSONIC_URL The base URL of your Subsonic-compatible music server. Must be https. Example: https://subdomain.example.com
ASKS_SUBSONIC_USER Your Subsonic server username
ASKS_SUBSONIC_PASS Your Subsonic server password
ASKS_SUBSONIC_PORT The port your Subsonic server listens on (if not the default for https) Default: 443
ASKS_SUBSONIC_SERVERPATH The server path of your Subsonic server. Must contain only the path, not the domain. Example: /path/to/rest Default: /rest
ASKS_SUBSONIC_APIVERSION The supported API version of your Subsonic server. (Airsonic servers should use version 1.15.0) Default: 1.16.1
ASKS_SUBSONIC_APPNAME The name of your AskSonic instance Default: py-sonic
ASKS_HOST The host AskSonic's server will listen on Default: 0.0.0.0
ASKS_PORT The port AskSonic's server will listen on Default: 4545 or $PORT
ASKS_ROUTE_PREFIX The endpoint that Alexa will use to communicate with AskSonic. You can obscure your AskSonic instance by customizing this Default: /alexa
ASKS_TRACKS_COUNT The number of tracks enqueued at a time Default: 50
ASKS_EXTRA_SECRET An extra secret that will be appended to all requests as either a header or to the query string. Useful for authenticating requests if your Subsonic server is behind a WAF such as Cloudflare

Acknowledgements

AskSonic was inspired by the following projects:

AskSonic recommends the following Subsonic-compatible music server:

License

AskSonic is licensed under the MIT License.

asksonic's People

Contributors

alesanmed avatar devwulf avatar srichter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

asksonic's Issues

Enqueue specific songs

The user should be able to tell AskSonic to queue the song Title by Artist and have AskSonic add that song to top of the current queue

AttributeError: 'NoneType' object has no attribute 'sendall'

Hello,
I don't really understand why i'm getting this error but looks like asksonic can't talk with the airsonic rest apis:

11:37:17 PM web.1 |  {"playerActivity": "STOPPED"}
11:37:17 PM web.1 |  [2022-01-25 23:37:17,701] DEBUG in navigation: Shuffle Library
11:37:17 PM web.1 |  192.168.1.160 - - [25/Jan/2022 23:37:17] "POST /alexa HTTP/1.1" 500 -
11:37:17 PM web.1 |  Traceback (most recent call last):
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2069, in __call__
11:37:17 PM web.1 |      return self.wsgi_app(environ, start_response)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2054, in wsgi_app
11:37:17 PM web.1 |      response = self.handle_exception(e)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2051, in wsgi_app
11:37:17 PM web.1 |      response = self.full_dispatch_request()
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1501, in full_dispatch_request
11:37:17 PM web.1 |      rv = self.handle_user_exception(e)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1499, in full_dispatch_request
11:37:17 PM web.1 |      rv = self.dispatch_request()
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1485, in dispatch_request
11:37:17 PM web.1 |      return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask_ask/core.py", line 890, in _flask_view_func
11:37:17 PM web.1 |      result = self._map_intent_to_view_func(self.request.intent)()
11:37:17 PM web.1 |    File "/app/asksonic/intents/navigation.py", line 25, in play_random_tracks
11:37:17 PM web.1 |      tracks = subsonic.random_tracks(tracks_count)
11:37:17 PM web.1 |    File "/app/asksonic/utils/subsonic/api.py", line 81, in random_tracks
11:37:17 PM web.1 |      tracks = self.getRandomSongs(count)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/libsonic/connection.py", line 1353, in getRandomSongs
11:37:17 PM web.1 |      res = self._doInfoReq(req)
11:37:17 PM web.1 |    File "/app/asksonic/utils/subsonic/api.py", line 25, in _doInfoReq
11:37:17 PM web.1 |      return super()._doInfoReq(req)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/libsonic/connection.py", line 2781, in _doInfoReq
11:37:17 PM web.1 |      res = self._opener.open(req)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/urllib/request.py", line 517, in open
11:37:17 PM web.1 |      response = self._open(req, data)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/urllib/request.py", line 534, in _open
11:37:17 PM web.1 |      result = self._call_chain(self.handle_open, protocol, protocol +
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/urllib/request.py", line 494, in _call_chain
11:37:17 PM web.1 |      result = func(*args)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/site-packages/libsonic/connection.py", line 56, in https_open
11:37:17 PM web.1 |      return self.do_open(HTTPSConnectionChain, req)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/urllib/request.py", line 1346, in do_open
11:37:17 PM web.1 |      h.request(req.get_method(), req.selector, req.data, headers,
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/http/client.py", line 1285, in request
11:37:17 PM web.1 |      self._send_request(method, url, body, headers, encode_chunked)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/http/client.py", line 1331, in _send_request
11:37:17 PM web.1 |      self.endheaders(body, encode_chunked=encode_chunked)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/http/client.py", line 1280, in endheaders
11:37:17 PM web.1 |      self._send_output(message_body, encode_chunked=encode_chunked)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/http/client.py", line 1040, in _send_output
11:37:17 PM web.1 |      self.send(msg)
11:37:17 PM web.1 |    File "/usr/local/lib/python3.9/http/client.py", line 1001, in send
11:37:17 PM web.1 |      self.sock.sendall(data)
11:37:17 PM web.1 |  AttributeError: 'NoneType' object has no attribute 'sendall'

Here my config:

# Subsonic server information
ASKS_SUBSONIC_URL=https://airsonic.mydomain.it
ASKS_SUBSONIC_USER=user
ASKS_SUBSONIC_PASS=pw
ASKS_SUBSONIC_PORT=4040
#ASKS_SUBSONIC_SERVERPATH=/rest
ASKS_SUBSONIC_APIVERSION=1.16.1
#ASKS_SUBSONIC_APPNAME=py-sonic

# AskSonic server config
ASKS_HOST=0.0.0.0
ASKS_PORT=5000
ASKS_ROUTE_PREFIX=/alexa

# AskSonic config
#ASKS_EXTRA_SECRET=
ASKS_TRACKS_COUNT=200

I have airsonic under nginx reverse proxy on https://airsonic.mydomain.it (port 4040) and asksonic under https://airsonic.mydomain.it/alexa, reversed to port 5000

What am i doing wrong?

For subsonic i'm using this docker-image: https://github.com/linuxserver/docker-airsonic-advanced

The reverse proxy is done like that:

location / {
      proxy_http_version                 1.1;
      proxy_set_header Connection        "Upgrade";
      proxy_set_header Host              $http_host;
      proxy_set_header Origin            '';
      proxy_set_header Upgrade           $http_upgrade;
      proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Host  $http_host;
      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header X-Real-IP         $remote_addr;
      proxy_max_temp_file_size           0;
      proxy_buffering                    off;
      proxy_request_buffering            off;
      client_max_body_size               0;
      proxy_pass http://192.168.1.160:4040;
      proxy_redirect                     http:// https://;

  }


  location /alexa {
       proxy_pass http://192.168.1.160:5000;
  proxy_headers_hash_max_size 512;
          proxy_headers_hash_bucket_size 64;

          add_header Front-End-Https on;
          proxy_set_header Range $http_range;
      proxy_set_header If-Range $http_if_range;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      #Next three lines allow websockets
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      }

Thanks

Play specific songs

The user should be able to ask AskSonic to play the song Title by Artist and have AskSonic replace the queue with just that song

ERROR in app: Exception on /alexa [POST]

Hi,

I am trying to configure asksonic with the following:

  • Ampache v5.6.0 which has subsonic API v1.13.0 ( I have configured env variable ASKS_SUBSONIC_APIVERSION=1.13.0)
  • Python 3.9.16
  • Alexa skill configured as per the readme

I can see that the Alexa service is hitting my asksonic instance fine but I get the following errors in the logs and it doesn't work.

20:05:44 web.1  | [2023-04-13 20:05:44 +1000] [15] [INFO] Listening at: http://0.0.0.0:4545 (15)
20:05:44 web.1  | [2023-04-13 20:05:44 +1000] [15] [INFO] Using worker: sync
20:05:44 web.1  | [2023-04-13 20:05:44 +1000] [16] [INFO] Booting worker with pid: 16

20:06:04 web.1  | [2023-04-13 20:06:04,072] ERROR in app: Exception on /alexa [POST]
20:06:04 web.1  | Traceback (most recent call last):
20:06:04 web.1  |   File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2051, in wsgi_app
20:06:04 web.1  |     rv = self.handle_user_exception(e)
20:06:04 web.1  |   File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1499, in full_dispatch_request
20:06:04 web.1  |     rv = self.dispatch_request()
20:06:04 web.1  |   File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1485, in dispatch_request
20:06:04 web.1  |     return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
20:06:04 web.1  |   File "/usr/local/lib/python3.9/site-packages/flask_ask/core.py", line 890, in _flask_view_func
20:06:04 web.1  |     result = self._map_intent_to_view_func(self.request.intent)()
20:06:04 web.1  |   File "/app/asksonic/intents/navigation.py", line 33, in play_artist
20:06:04 web.1  |     tracks = subsonic.artist_tracks(artist, tracks_count)
20:06:04 web.1  |   File "/app/asksonic/utils/subsonic/api.py", line 94, in artist_tracks
20:06:04 web.1  |     albums = self.artist_albums(artist)
20:06:04 web.1  |     found_artist = self.find_artist(artist)
20:06:04 web.1  |   File "/app/asksonic/utils/subsonic/api.py", line 62, in find_artist
20:06:04 web.1  |     return self._find_x('artist', query)
20:06:04 web.1  |   File "/app/asksonic/utils/subsonic/api.py", line 46, in _find_x
20:06:04 web.1  |     result = self.search(
20:06:04 web.1  |   File "/app/asksonic/utils/subsonic/api.py", line 41, in search
20:06:04 web.1  |     return self.search3(query=query, **options)
20:06:04 web.1  |   File "/usr/local/lib/python3.9/site-packages/libsonic/connection.py", line 651, in search3
20:06:04 web.1  |     res = self._doInfoReq(req)
20:06:04 web.1  |   File "/app/asksonic/utils/subsonic/api.py", line 25, in _doInfoReq
20:06:04 web.1  |     return super()._doInfoReq(req)
20:06:04 web.1  |   File "/usr/local/lib/python3.9/site-packages/libsonic/connection.py", line 2783, in _doInfoReq
20:06:04 web.1  |     return dres['subsonic-response']
20:06:04 web.1  | KeyError: 'subsonic-response'

Any suggestions as to why it is not working would be greatly appreciated.

Thanks :)

Use Interactive search

AskSonic should use an interactive search via a dialog when it is unsure about the results of a user's query for a specific song/artist/album

Getting the next track doesn't work all the time

When I am playing an artist on my Echo Show 5, it will play one song, play the next song, and then repeat that song again. I ask for the next song, and it plays the same one again until I ask for the next track again.

I am unsure where to look to troubleshoot this one. Could it be a timing issue?

Is anyone else having this issue?

Keeping the interaction open while playing music

I have tried music streaming services, but they all fall short in some way. This is why I am using this project to stream my own music. I have noticed (not just with your skill or even only on Alexa) that skills like these do not really replace music streaming functionality on these smart devices. I'm sure this is intentional on their part. It is not because these skills are not feature complete. The problem is that once you are playing music from a skill you cannot ask for something else (queue another song) without asking to speak to the skill again. I was wondering if keeping the interaction open "indefinitely" is an option.

For my personal version of this skill, I was thinking about making sure that each intent does not send the shouldendinteraction (or something) tag back to Alexa. Is this possible? What can I do to keep talking to this skill until I say stop music or exit?

Missing serverPath parameter

Hello! I followed everything to setup AskSonic on Heroku and the Alexa Skill setup too. However, it doesn't seem to work with my Airsonic server. Here are the logs shown whenever I try to use the Alexa Skill:

2021-09-10T03:34:31.825306+00:00 app[web.1]: [2021-09-10 03:34:31,824] ERROR in app: Exception on /alexa [POST]
2021-09-10T03:34:31.825316+00:00 app[web.1]: Traceback (most recent call last):
2021-09-10T03:34:31.825319+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 2051, in wsgi_app
2021-09-10T03:34:31.825319+00:00 app[web.1]:     response = self.full_dispatch_request()
2021-09-10T03:34:31.825320+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1501, in full_dispatch_request
2021-09-10T03:34:31.825320+00:00 app[web.1]:     rv = self.handle_user_exception(e)
2021-09-10T03:34:31.825321+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1499, in full_dispatch_request
2021-09-10T03:34:31.825321+00:00 app[web.1]:     rv = self.dispatch_request()
2021-09-10T03:34:31.825321+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1485, in dispatch_request
2021-09-10T03:34:31.825322+00:00 app[web.1]:     return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
2021-09-10T03:34:31.825322+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask_ask/core.py", line 890, in _flask_view_func
2021-09-10T03:34:31.825322+00:00 app[web.1]:     result = self._map_intent_to_view_func(self.request.intent)()
2021-09-10T03:34:31.825323+00:00 app[web.1]:   File "/app/asksonic/intents/navigation.py", line 25, in play_random_tracks
2021-09-10T03:34:31.825323+00:00 app[web.1]:     tracks = subsonic.random_tracks(tracks_count)
2021-09-10T03:34:31.825324+00:00 app[web.1]:   File "/app/asksonic/utils/subsonic/api.py", line 77, in random_tracks
2021-09-10T03:34:31.825324+00:00 app[web.1]:     tracks = self.getRandomSongs(count)
2021-09-10T03:34:31.825324+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/libsonic/connection.py", line 1353, in getRandomSongs
2021-09-10T03:34:31.825325+00:00 app[web.1]:     res = self._doInfoReq(req)
2021-09-10T03:34:31.825325+00:00 app[web.1]:   File "/app/asksonic/utils/subsonic/api.py", line 21, in _doInfoReq
2021-09-10T03:34:31.825326+00:00 app[web.1]:     return super()._doInfoReq(req)
2021-09-10T03:34:31.825326+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/libsonic/connection.py", line 2781, in _doInfoReq
2021-09-10T03:34:31.825326+00:00 app[web.1]:     res = self._opener.open(req)
2021-09-10T03:34:31.825326+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/urllib/request.py", line 523, in open
2021-09-10T03:34:31.825327+00:00 app[web.1]:     response = meth(req, response)
2021-09-10T03:34:31.825327+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/urllib/request.py", line 632, in http_response
2021-09-10T03:34:31.825327+00:00 app[web.1]:     response = self.parent.error(
2021-09-10T03:34:31.825327+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/urllib/request.py", line 561, in error
2021-09-10T03:34:31.825327+00:00 app[web.1]:     return self._call_chain(*args)
2021-09-10T03:34:31.825328+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/urllib/request.py", line 494, in _call_chain
2021-09-10T03:34:31.825328+00:00 app[web.1]:     result = func(*args)
2021-09-10T03:34:31.825328+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/urllib/request.py", line 641, in http_error_default
2021-09-10T03:34:31.825329+00:00 app[web.1]:     raise HTTPError(req.full_url, code, msg, hdrs, fp)
2021-09-10T03:34:31.825329+00:00 app[web.1]: urllib.error.HTTPError: HTTP Error 403: 

The error 403 at the bottom means that access wasn't allowed for some reason. However, using Postman and this resource to craft the URL for pinging the Airsonic server, it seems to work, since I get this response:

<?xml version="1.0" encoding="UTF-8"?>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.15.0"/>

I looked around a bit further and found this issue on the py-sonic library and the documentation associated with it. Since my Airsonic is installed in a seedbox and therefore has a URL that looks like this:

https://xxx.xxxxx.usbx.me/airsonic

having only the baseUrl parameter for the libsonic.Connection class that you have sadly won't be enough for this. It'll also need a serverPath parameter, and both parameters would look like so:

baseUrl="https://xxx.xxxxx.usbx.me",
serverPath="/airsonic/rest"

Would this be possible to implement? A Heroku configuration parameter will be greatly appreciated too! Thank you so much!

Edit: One more thing I almost forgot! Apparently Airsonic's API version only goes up to 1.15.0. Would it be possible to include the apiVersion parameter on both the Subsonic class that you have and the Heroku configuration too? Actually, when I have time tomorrow and if you're not able to implement this anytime soon, I'll just do a pull request and implement these things, if that's alright? Thank you once again for creating this wonderful guide and tool too!

Can't shuffle the library: TypeError: __init__() missing 1 required positional argument: 'artistId

Hi,
this error started showing up yesterday, when i say "alexa, tell sub sonic to shuffle my library"

9:22:45 AM web.1 |  Traceback (most recent call last):
9:22:45 AM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2051, in wsgi_app
9:22:45 AM web.1 |      response = self.full_dispatch_request()
9:22:45 AM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1501, in full_dispatch_request
9:22:45 AM web.1 |      rv = self.handle_user_exception(e)
9:22:45 AM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1499, in full_dispatch_request
9:22:45 AM web.1 |      rv = self.dispatch_request()
9:22:45 AM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1485, in dispatch_request
9:22:45 AM web.1 |      return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
9:22:45 AM web.1 |    File "/usr/local/lib/python3.9/site-packages/flask_ask/core.py", line 890, in _flask_view_func
9:22:45 AM web.1 |      result = self._map_intent_to_view_func(self.request.intent)()
9:22:45 AM web.1 |    File "/app/asksonic/intents/navigation.py", line 25, in play_random_tracks
9:22:45 AM web.1 |      tracks = subsonic.random_tracks(tracks_count)
9:22:45 AM web.1 |    File "/app/asksonic/utils/subsonic/api.py", line 83, in random_tracks
9:22:45 AM web.1 |      tracks = [Track(**track) for track in tracks]
9:22:45 AM web.1 |    File "/app/asksonic/utils/subsonic/api.py", line 83, in <listcomp>
9:22:45 AM web.1 |      tracks = [Track(**track) for track in tracks]
9:22:45 AM web.1 |  TypeError: __init__() missing 1 required positional argument: 'artistId'

Initially it was working, i've changed nothing since some days ago and now i can't shuffle my library anymore

What's the problem? May be something wrong with Navidrome?

Yes i use Navidrome as music server, it has 1.16.1 subsonic api

python error when attempting to start

Trying to run asksonic with navidrome. I have swag running for my reverse proxy and it works as expected on port 443.

I get the following error, regardless of whether I run asksonic locally or on Heroku.

08:44:05 web.1  | started with pid 1908524
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908526] [INFO] Starting gunicorn 20.1.0
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908526] [INFO] Listening at: http://0.0.0.0:5000 (1908526)
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908526] [INFO] Using worker: sync
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908528] [INFO] Booting worker with pid: 1908528
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908528] [ERROR] Exception in worker process
08:44:05 web.1  | Traceback (most recent call last):
08:44:05 web.1  |   File "/home/*****/.local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker
08:44:05 web.1  |     worker.init_process()
08:44:05 web.1  |   File "/home/*****/.local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 134, in init_process
08:44:05 web.1  |     self.load_wsgi()
08:44:05 web.1  |   File "/home/*****/.local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
08:44:05 web.1  |     self.wsgi = self.app.wsgi()
08:44:05 web.1  |   File "/home/*****/.local/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
08:44:05 web.1  |     self.callable = self.load()
08:44:05 web.1  |   File "/home/*****/.local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
08:44:05 web.1  |     return self.load_wsgiapp()
08:44:05 web.1  |   File "/home/*****/.local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
08:44:05 web.1  |     return util.import_app(self.app_uri)
08:44:05 web.1  |   File "/home/*****/.local/lib/python3.8/site-packages/gunicorn/util.py", line 359, in import_app
08:44:05 web.1  |     mod = importlib.import_module(module)
08:44:05 web.1  |   File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
08:44:05 web.1  |     return _bootstrap._gcd_import(name[level:], package, level)
08:44:05 web.1  |   File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
08:44:05 web.1  |   File "<frozen importlib._bootstrap>", line 991, in _find_and_load
08:44:05 web.1  |   File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
08:44:05 web.1  |   File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
08:44:05 web.1  |   File "<frozen importlib._bootstrap_external>", line 848, in exec_module
08:44:05 web.1  |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
08:44:05 web.1  |   File "/home/*****/navidrome_docker/asksonic/asksonic/__init__.py", line 21, in <module>
08:44:05 web.1  |     from . import intents
08:44:05 web.1  |   File "/home/*****/navidrome_docker/asksonic/asksonic/intents/__init__.py", line 1, in <module>
08:44:05 web.1  |     from asksonic.utils.queue.queue_manager import QueueManager
08:44:05 web.1  |   File "/home/*****/navidrome_docker/asksonic/asksonic/utils/queue/queue_manager.py", line 8, in <module>
08:44:05 web.1  |     from asksonic.utils.subsonic.track import Track
08:44:05 web.1  |   File "/home/*****/navidrome_docker/asksonic/asksonic/utils/subsonic/__init__.py", line 2, in <module>
08:44:05 web.1  |     from .api import Subsonic
08:44:05 web.1  |   File "/home/*****/navidrome_docker/asksonic/asksonic/utils/subsonic/api.py", line 6, in <module>
08:44:05 web.1  |     from .track import Track
08:44:05 web.1  |   File "/home/*****/navidrome_docker/asksonic/asksonic/utils/subsonic/track.py", line 5, in <module>
08:44:05 web.1  |     class Track():
08:44:05 web.1  |   File "/home/*****/navidrome_docker/asksonic/asksonic/utils/subsonic/track.py", line 82, in Track
08:44:05 web.1  |     def metadata(self) -> dict[str, str]:
08:44:05 web.1  | TypeError: 'type' object is not subscriptable
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908528] [INFO] Worker exiting (pid: 1908528)
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908526] [INFO] Shutting down: Master
08:44:05 web.1  | [2021-08-20 08:44:05 -0400] [1908526] [INFO] Reason: Worker failed to boot.

Before I started trying to debug the code myself, I figured I would ask here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.