py-sonic
is a Python library that wraps the Subsonic REST API. This is meant to essentially be a convenience layer when you are writing an app to work against your Subsonic server. You will notice when going through the documentation here that this is a thin layer on top of the REST API. I have plans to make this a bit more “Pythonic” (if I can ever muster up enough time to do it), but though this returns simple language constructs (dict, list, etc.) at this point, it is still very usable.
You can download this the package from Github, or just git clone
it.
You can also use pip
or easy_install
:
pip install py-sonic
NOTE: The RPMs are not guaranteed to be the latest versions. Check Github to find out what the latest version is. That said, I will try and keep these up to date.
By no means should anyone feel they have to donate. However, if you've used this stuff to save some time, prevent head shaped holes in the wall, raise your children or you just think this is awesome and want to contribute to my Surly fund (that stuff isn't cheap, but it's soooooo good), you can click the Paypal donate button below and toss me a couple of dollars. I've heard from others who have donated that they were visited by flying monkeys that spoke Icelandic, and were subsequently showered with fantastic gifts from said monkeys. I don't know if this is true, or if drug use was involved, but it still sounds pretty awesome.
<html> <form action=“https://www.paypal.com/cgi-bin/webscr” method=“post”> <input type=“hidden” name=“cmd” value=“_s-xclick”> <input type=“hidden” name=“hosted_button_id” value=“83ENX2ZV8E694”> <input type=“image” src=“https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif” border=“0” name=“submit” alt=“PayPal - The safer, easier way to pay online!”> <img alt=“” border=“0” src=“https://www.paypalobjects.com/en_US/i/scr/pixel.gif” width=“1” height=“1”> </form> </html>
Please use the bug tracker built in to Github for all bug reports and feature requests
I'm always open to code contributions. Please use the “fork” and “pull request” mechanisms on Github for this.
You can install manually:
tar -xvzf py-sonic-*.tar.gz cd py-sonic-* python setup.py install
Or you can install with pip
or easy_install
:
pip install py-sonic
NOTE: All of the information in this section is also available with pydoc
:
pydoc libsonic.connection
This is the only real class (at this point) that you need to use. You will notice that this very much follows the API as documented on the subsonic website. You will notice that the methods for your libsonic.Connection
instance all note their relative REST API
versions. You can find the API version to Subsonic version on Subsonic's API documentation page.
I've found that there is a major wart in the upstream API. It appears that any of the calls which can return multiple results will, instead of always returning a
list
, will return only a dict
instead if there is one item. For example, if you call getPlaylists()
with only one playlist set up on your server, you would get a structure like the following:
{ u'playlists': {u'playlist': {u'id': u'62656174732e6d3375', u'name': u'beats' } } u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
However, if there are multiple playlists, you will get a structure like this:
{ u'playlists': {u'playlist': [{u'id': u'62656174732e6d3375', u'name': u'beats' } , {u'id': u'766172696574792e6d3375', u'name': u'variety' }] } , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
As of this writing, you will have to check whether you receive a list
or a dict
back. I plan on fixing this in a future release so that you always we receive a list
when it is possible to have multiple entries, even if there is only one entry.
A quick note about when you enable HTTPS on your Subsonic server. I recently discovered that when you set SUBSONIC_HTTPS_PORT
to a non-zero value (essentially, turning on HTTPS), this will cause Subsonic to 302 redirect all incoming traffic to the now enabled HTTPS port. This should not be a problem, but it seems that the Python urllib2.HTTPRedirectHandler
does not handle this correctly, probably because I'm submitting a POST request here. I'm going to look into this further, but the simple workaround is simply: If you set the SUBSONIC_HTTPS_PORT
, be sure that your libsonic.Connection
arguments are pointing to the HTTPS port (for the example, I assume you set SUBSONIC_HTTPS_PORT=4430
):
import libsonic conn = libsonic.Connection('https://example.com' , 'myuser' , 'mypass' , port=4430)
UPDATE: I found that the urllib2.HTTPRedirectHandler
issue is actually a “bug” wherein the POST data is not redirected. It is somewhat questionable practice in terms of security, so who knows if it will be accepted. Since py-sonic
sends everything via POST requests, redirection was breaking it by dropping all data. Though I submitted a bug report with patch, I'm going to put a fix into py-sonic
that fixes this regardless of whether the upstream Python maintainers fix this.
UPDATE to the UPDATE: I've fixed this in version 0.1.10. This will now handle redirects from Subsonic correctly.
It's important to note that Subsonic API version 1.8.0 added some methods that are not compatible with previous methods. Prior to 1.8.0, the access to your library was only usable within a directory hierarchy context. With 1.8.0, a number of access methods were added to search and get artists, albums, songs, etc. based on, instead of file system structure, the ID3 tags of the music files themselves.
The problem this brings about is that the IDs returned for one type of lookup are not compatible with the other. For example, if you were to use the search2() method to search for, say, an artist. If you then used the resulting artist ID from that search to getArtist(id), you would not get what you expected! Instead, you would get either an error or a different artist altogether.
The crux of this is that if you must make sure you don't mix these methods in what your code. Anything that is introduced in API 1.8.0 (or later) that makes mention of using ID3 tags will not be compatible with things like getMusicDirectory().
This is the initialization method for the class. As you can see, the baseUrl
, username
and password
are all required. Set the rest of the options as needed. This will return a libsonic.Connection
instance that you will use to perform all interactions with the server.
Name | Type | Description |
---|---|---|
baseUrl | str | The base url for your server. Be sure to use “https” for SSL connections. ex: http://subsonic.example.com |
username | str | The username to use for the connection |
password | str | The password to use for the connection |
port | int | The port number to connect on. The default for unencrypted subsonic connections is 4040 |
serverPath | str | The base resource path for the subsonic views. This is useful if you have your subsonic server behind a proxy and the path that you are proxying is differnt from the default of /rest . Ex: serverPath='/path/to/subs ' The full url that would be built then would be (assuming defaults and using “example.com” and you are using the “ping” view): http://example.com:4040/path/to/subs/ping.view |
appName | str | The name of your application. |
apiVersion | str | The version of the API you wish your application to support. Subsonic will throw an error if you Subsonic will throw an error if you the server supports. See the Subsonic API docs to find the Subsonic version → API version table. This is useful if you are connecting to an olderversion of Subsonic. |
Since API version: 1.2.0
Adds a message to the chat log
Name | Type | Description |
---|---|---|
message | str | The message to add |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.2.0
Changes the password of an existing Subsonic user. Note that the user performing this must have admin privileges.
Name | Type | Description |
---|---|---|
username | str | The username whose password is being changed |
password | str | The new password of the user |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.2.0
Creates OR updates a playlist. If updating the list, the playlistId
is required. If creating a list, the name
is required.
Name | Type | Description |
---|---|---|
playlistId | str | The ID of the playlist to UPDATE |
name | str | The name of the playlist to CREATE |
songIds | list[str] | The list of songIds to populate the list with in either create or update mode. Note that this list will replace the existing list if updating. |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.9.0
Adds a new Podcast channel. Note: The user must be authorized for Podcast administration
Name | Type | Description |
---|---|---|
url | str | The URL of the Podcast to add |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.6.0
Creates a public URL that can be used by anyone to stream music or video from the Subsonic server. The URL is short and suitable for posting on Facebook, Twitter etc. Note: The user must be authorized to share (see Settings > Users > User is allowed toshare files with anyone).
Name | Type | Description |
---|---|---|
shids | list[str] | A list of IDs of songs, albums or videos |
description | str | A description that will be displayed to people visiting the shared media (optional). |
expires | float | A timestamp pertaining to the time at which this should expire (optional) |
This returns a structure like you would get back from getShares()
containing just your new share.
Since API version: 1.1.0
Creates a new subsonic user, using the parameters defined. See the documentation at the Subsonic site for more info on all the roles.
Name | Type | Description |
---|---|---|
username | str | The username of the new user |
password | str | The password for the new user |
See the documention on the Subsonic site for more information on all the boolean role args.
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.9.0
Deletes the bookmark for a given file
Name | Type | Description |
---|---|---|
mid | str | The ID of the media file to delete the bookmark from. Other users' bookmarks are not affected |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.2.0
Deletes a saved playlist.
Name | Type | Description |
---|---|---|
pid | str | ID of the playlist to delete, as obtained by getPlaylists() |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.9.0
Deletes a Podcast channel. Note: The user must be authorized for Podcast administration
Name | Type | Description |
---|---|---|
pid | str | ID of the Podcast channel to delete |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.9.0
Deletes a Podcast episode. Note: The user must be authorized for Podcast administration
Name | Type | Description |
---|---|---|
pid | str | ID of the Podcast episode to delete |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.6.0
Deletes an existing share.
Name | Type | Description |
---|---|---|
shid | str | The ID of the share to delete |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.3.0
Deletes an existing Subsonic user. Of course, you must have admin rights for this.
Name | Type | Description |
---|---|---|
username | str | The username of the user to delete |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
Downloads a given media file.
Name | Type | Description |
---|---|---|
sid | str | The ID of the media file to download. |
Returns the file-like object for reading or raises an exception on error.
Since API version: 1.9.0
Tells the server to start downloading a given Podcast episode. Note: The user must be authorized for Podcast administration
Name | Type | Description |
---|---|---|
pid | str | The ID of the Podcast episode to download. |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.8.0
Returns the info and songs for an album. This method uses the ID3 tags for organization.
Name | Type | Description |
---|---|---|
id | str | The ID of the album. |
Returns a dict like the following:
{u'album': {u'artist': u'Massive Attack', u'artistId': 0, u'coverArt': u'al-0', u'created': u'2009-08-28T10:00:44', u'duration': 3762, u'id': 0, u'name': u'100th Window', u'song': [{u'album': u'100th Window', u'albumId': 0, u'artist': u'Massive Attack', u'artistId': 0, u'bitRate': 192, u'contentType': u'audio/mpeg', u'coverArt': 2, u'created': u'2009-08-28T10:00:57', u'duration': 341, u'genre': u'Rock', u'id': 14, u'isDir': False, u'isVideo': False, u'parent': 2, u'path': u'Massive Attack/100th Window/01 - Future Proof.mp3', u'size': 8184445, u'suffix': u'mp3', u'title': u'Future Proof', u'track': 1, u'type': u'music', u'year': 2003}], u'songCount': 9}, u'status': u'ok', u'version': u'1.8.0', u'xmlns': u'http://subsonic.org/restapi'}
Since API version: 1.2.0
Returns a list of random, newest, highest rated etc. albums. Similar to the album lists on the home page of the Subsonic web interface.
Name | Type | Description |
---|---|---|
ltype | str | The list type. Must be one of the following: random, newest, highest, frequent, recent |
size | int | The number of albums to return. Max 500 |
offset | int | The list offset. Use for paging. Max 5000 |
Returns a dict like the following:
{ u'albumList': {u'album': [ { u'artist': u'Hank Williams', u'id': u'3264928374', u'isDir': True, u'parent': u'9238479283', u'title': u'The Original Singles Collection...Plus' } , { u'artist': u'Freundeskreis' , u'coverArt': u'9823749823', u'id': u'23492834', u'isDir': True, u'parent': u'9827492374', u'title': u'Quadratur des Kreises' } ]} u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.8.0
Returns a list of random, newest, highest rated etc. albums. This is similar to getAlbumList, but uses ID3 tags for organization.
Name | Type | Description |
---|---|---|
ltype | str | The list type. Must be one of the following: random, newest, highest, frequent, recent |
size | int | The number of albums to return. Max 500 |
offset | int | The list offset. Use for paging. Max 5000 |
Returns a dict like the following:
{u'albumList2': {u'album': [{u'artist': u'Massive Attack', u'artistId': 0, u'coverArt': u'al-0', u'created': u'2009-08-28T10:00:44', u'duration': 3762, u'id': 0, u'name': u'100th Window', u'songCount': 9}, {u'artist': u'Massive Attack', u'artistId': 0, u'coverArt': u'al-5', u'created': u'2003-11-03T22:00:00', u'duration': 2715, u'id': 5, u'name': u'Blue Lines', u'songCount': 9}]}, u'status': u'ok', u'version': u'1.8.0', u'xmlns': u'http://subsonic.org/restapi'}
Since API version: 1.8.0
Name | Type | Description |
---|---|---|
id | int | Get the artist by id |
Since API version: 1.8.0
Similar to getIndexes(), but this method uses the ID3 tags to determine the artist
Returns a dict like the following:
{u'artists': {u'index': [{u'artist': {u'albumCount': 7, u'coverArt': u'ar-0', u'id': 0, u'name': u'Massive Attack'}, u'name': u'M'}, {u'artist': {u'albumCount': 2, u'coverArt': u'ar-1', u'id': 1, u'name': u'Tune-Yards'}, u'name': u'T'}]}, u'status': u'ok', u'version': u'1.8.0', u'xmlns': u'http://subsonic.org/restapi'}
Since API version: 1.8.0
Returns the avatar for a user or None if the avatar does not exist
Name | Type | Description |
---|---|---|
username | str | The user to retrieve the avatar for |
Returns the file-like object for reading or raises an exception on error
Since API version: 1.9.0
Returns all bookmarks for this user. A bookmark is a position within a media file
{ "bookmarks": { "bookmark": { "changed": "2013-04-28T13:18:55", "comment": "testing a bookmark", "created": "2013-04-28T13:18:55", "entry": { "album": "The Anthology", "albumId": 3480, "artist": "A Tribe Called Quest", "artistId": 1512, "bitRate": 128, "contentType": "audio/mpeg", "coverArt": 45794, "created": "2005-07-27T14:27:42", "duration": 292, "id": 45827, "isDir": false, "isVideo": false, "parent": 45794, "path": "A Tribe Called Quest/The Anthology/13 Stressed Out.mp3", "size": 4685211, "suffix": "mp3", "title": "Stressed Out", "track": 13, "type": "music" }, "position": 30000, "username": "admin" } }, "status": "ok", "version": "1.9.0", "xmlns": "http://subsonic.org/restapi" }
Since API version: 1.2.0
Returns the current visible (non-expired) chat messages.
Name | Type | Description |
---|---|---|
since | int | Only return messages newer than this timestamp |
NOTE: All times returned are in MILLISECONDS since the Epoch, not seconds!
Returns a dict like the following:
{ u'chatMessages': [{u'chatMessage': {u'message': u'testing 123', u'time': 1303411919872L, u'username': u'admin' } }] , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
Returns a cover art image
Name | Type | Description |
---|---|---|
aid | str | ID string for the cover art image to download |
size | int | If specified, scale image to this size |
Returns the file-like object for reading or raises an exception on error.
Since API version: 1.9.0
Returns all genres
Since API version: 1.0.0
Returns an indexed structure of all artists
Name | Type | Description |
---|---|---|
musicFolderId | int | If this is specified, it will only return artists for the given folder ID from the getMusicFolders call |
ifModifiedSince | int | If specified, return a result if the artist collection has changed since the given time |
Returns a dict like the following:
{ u'indexes': {u'index': [{u'name': 'A' , u'artist': [{u'id': u'29834728934', u'name': u'A Perfect Circle' } , {u'id': u'238472893', u'name': u'A Small Good Thing' } , ... ... ] } , {u'name': 'B' , u'artist': [{u'id': u'983249823' , ... ... }] }] } , u'lastModified': 1303318347000L }
Since this is a bit ugly and hard to discern, I'm going to lay it out in types table here.
Name | Type | Keys (if a dict) | Description |
---|---|---|---|
<base>b | dict | u'status', u'xmlns', u'version', u'indexes' | This is the root object that contains the usual (“status”, “version”, “xmlns”) and also “indexes” |
b['indexes'] | dict | u'index', u'shortcut', u'lastModified' | This contains a list of shortcuts, which may or may not be there for you (I won't describe this here). It also contains the “index”, which is where all our real data is |
b['indexes']['index'] | list | N/A | This is a list of dictionaries containing the root of the index. |
b['indexes']['index'][0] | dict | u'name', u'artist' | The name value here is a string that will be the index name, basically the first letter of this sections artist names (or a # for numbers) |
b['indexes']['index'][0]['artist'] | list | N/A | This will be a list of the artist dictionaries within the name section. So, if name is “A”, then this will be a list of all the artists starting with the letter “A” |
b['indexes']['index'][0]['artist'][0] | dict | u'id', u'name' | This is the internal ID value for the artist and the actual artist name |
I hope that table clarifies things a bit.
Since API version: 1.9.0
Returns all internet radio stations
Returns a dict like the following:
{ "internetRadioStations": { "internetRadioStation": { "homePageUrl": "http://www.di.fm/", "id": 0, "name": "DI hard dance", "streamUrl": "http://listen.di.fm/public3/harddance.pls" } }, "status": "ok", "version": "1.9.0", "xmlns": "http://subsonic.org/restapi" }
Since API version: 1.0.0
Gets details related to the software license
Returns a dict like the following:
{ u'license': {u'date': u'2010-05-21T11:14:39', u'email': u'email@example.com', u'key': u'12345678901234567890123456789012', u'valid': True } , u'status': u'ok' , u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.2.0
Searches for and returns lyrics for a given song
Name | Type | Description |
---|---|---|
artist | str | The artist name |
title | str | The song title |
Returns a dict like the following for getLyrics('Bob Dylan' , 'Blowin in the wind')
:
{ u'lyrics': {u'artist': u'Bob Dylan', u'content': u"How many roads must a man walk down<snip>", u'title': u"Blowin' in the Wind" } u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
Returns a listing of all files in a music directory. Typically used to get a list of albums for an artist or list of songs for an album.
Name | Type | Description |
---|---|---|
mid | str | The string ID value which uniquely identifies the folder. Obtained via calls to getIndexes() or getMusicDirectory() . |
Returns a dict like the following if I were to call this with id for the artist “A Tribe Called Quest”:
{ u'directory': {u'child': [{u'artist': u'A Tribe Called Quest', u'coverArt': u'223484', u'id': u'329084', u'isDir': True, u'parent': u'234823940', u'title': u'Beats, Rhymes And Life' } , {u'artist': u'A Tribe Called Quest', u'coverArt': u'234823794', u'id': u'238472893', u'isDir': True, u'parent': u'2308472938' u'title': u'Midnight Marauders' }] u'id': u'329847293', u'name': u'A Tribe Called Quest' }, u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
Returns all configured music folders
Returns a dict like the following:
{ u'musicFolders': {u'musicFolder': [{u'id': 0, u'name': u'folder1'}, {u'id': 1, u'name': u'folder2'}, {u'id': 2, u'name': u'folder3'} ] } u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
Returns what is currently being played by all users
Returns a dict like the following:
{ u'nowPlaying': {u'entry': [{u'album': u"Jazz 'Round Midnight 12", u'artist': u'Astrud Gilberto', u'bitRate': 172, u'contentType': u'audio/mpeg', u'coverArt': u'98349284', u'duration': 325, u'genre': u'Jazz', u'id': u'2424324', u'isDir': False, u'isVideo': False, u'minutesAgo': 0, u'parent': u'542352', u'path': u"Astrud Gilberto/Jazz 'Round Midnight 12/01 - The Girl From Ipanema.mp3", u'playerId': 1, u'size': 7004089, u'suffix': u'mp3', u'title': u'The Girl From Ipanema', u'track': 1, u'username': u'user1', u'year': 1996 }, { ... ... }] } , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
Returns a listing of files in a saved playlist
Name | Type | Description |
---|---|---|
id | str | The ID of the playlist as returned in getPlaylists() |
Returns a dict like the following:
{ u'playlist': {u'entry': [{u'album': u'The Essential Bob Dylan', u'artist': u'Bob Dylan', u'bitRate': 32, u'contentType': u'audio/mpeg', u'coverArt': u'2983478293', u'duration': 984, u'genre': u'Classic Rock', u'id': u'982739428', u'isDir': False, u'isVideo': False, u'parent': u'98327428974', u'path': u"Bob Dylan/Essential Bob Dylan Disc 1/Bob Dylan - The Essential Bob Dylan - 03 - The Times They Are A-Changin'.mp3", u'size': 3921899, u'suffix': u'mp3', u'title': u"The Times They Are A-Changin'", u'track': 3 } , {u'album': u'Another album', ... ... }] , u'id': u'44796c616e2e6d3375', u'name': u'Dylan'} } , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
Returns the ID and name of all saved playlists
Returns a dict like the following:
{ u'playlists': {u'playlist': [{u'id': u'62656174732e6d3375', u'name': u'beats' } , {u'id': u'766172696574792e6d3375', u'name': u'variety' }] } , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.6.0
Returns all podcast channels the server subscribes to and their episodes.
Name | Type | Description |
---|---|---|
incEpisodes | bool | (since: 1.9.0) Whether to include Podcast episodes in the returned result. |
pid | str | (since: 1.9.0) If specified, only return the Podcast channel with this ID. |
Returns a dict like the following:
{ u'podcasts': {u'channel': {u'description': u"Dr Chris Smith...", u'episode': [{u'album': u'Dr Karl and the Naked Scientist', u'artist': u'BBC Radio 5 live', u'bitRate': 64, u'contentType': u'audio/mpeg', u'coverArt': u'2f6f70742f', u'description': u'Dr Karl answers all your science related questions.', u'duration': 2902, u'genre': u'Podcast', u'id': 0, u'isDir': False, u'isVideo': False, u'parent': u'2f6f70742f7', u'publishDate': u'2011-08-17 22:06:00.0', u'size': 23313059, u'status': u'completed', u'streamId': u'2f6f70742', u'suffix': u'mp3', u'title': u'DrKarl: Peppermints, Chillies & Receptors', u'year': 2011 } , {u'album': u'klsddfjks', ... ... }], u'id': 0, u'status': u'completed', u'title': u'Dr Karl and the Naked Scientist', u'url': u'http://downloads.bbc.co.uk/podcasts/fivelive/drkarl/rss.xml' } }, u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.2.0
Returns random songs matching the given criteria
Name | Type | Description |
---|---|---|
size | int | The max number of songs to return. Max 500 |
genre | str | Only return songs from this genre |
fromYear | int | Only return songs after or in this year |
toYear | int | Only return songs before or in this year |
musicFolderId | str | Only return songs in the music folder with the given ID. See getMusicFolders() |
Returns a dict like the following:
{ u'randomSongs': {u'song': [{u'album': u'1998 EP - Airbag (How Am I Driving)', u'artist': u'Radiohead', u'bitRate': 320, u'contentType': u'audio/mpeg', u'duration': 129, u'id': u'9284728934', u'isDir': False, u'isVideo': False, u'parent': u'983249823', u'path': u'Radiohead/1998 EP - Airbag (How Am I Driving)/06 - Melatonin.mp3', u'size': 5177469, u'suffix': u'mp3', u'title': u'Melatonin' } , {u'album': u'Mezmerize', ... ... }] } , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.2.0
Returns information about shared media this user is allowed to manage
Returns a dict like the following:
{ u'shares': {u'share': [{u'created': u'2011-08-18T10:01:35', u'entry': [{u'artist': u'Alice In Chains', u'coverArt': u'2f66696c65732f6d', u'id': u'2f66696c65732f', u'isDir': True, u'parent': u'2f66696c65732f6d7', u'title': u'Alice In Chains' } , {u'artist': u'ldksjfklsjf', ... ... }] , u'expires': u'2012-08-18T10:01:35', u'id': 0, u'url': u'http://someone.subsonic.org/share/BuLbF', u'username': u'admin', u'visitCount': 0 }] } , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.8.0
Returns the info for a song. This method uses the ID3 tags for organization.
Name | Type | Description |
---|---|---|
id | str | The song ID |
{u'song': {u'album': u'W H O K I L L', u'albumId': 8, u'artist': u'Tune-Yards', u'artistId': 1, u'bitRate': 320, u'contentType': u'audio/mpeg', u'coverArt': 106, u'created': u'2011-03-22T15:08:00', u'discNumber': 1, u'duration': 192, u'genre': u'Indie Rock', u'id': 120, u'isDir': False, u'isVideo': False, u'parent': 106, u'path': u'Tune Yards/Who Kill/10 Killa.mp3', u'size': 7692656, u'suffix': u'mp3', u'title': u'Killa', u'track': 10, u'type': u'music', u'year': 2011}, u'status': u'ok', u'version': u'1.8.0', u'xmlns': u'http://subsonic.org/restapi'}
Since API version: 1.9.0
Returns songs in a given genre
Name | Type | Description |
---|---|---|
genre | str | The genre, as returned by getGenres() |
count | int | The maximum number of songs to return. Max is 500. default: 10 |
offset | int | The offset if you are paging. default: 0 |
Since API version: 1.8.0
Returns starred songs, albums and artists
Returns a dict like the following:
{u'starred': {u'album': {u'album': u'Bird-Brains', u'artist': u'Tune-Yards', u'coverArt': 105, u'created': u'2012-01-30T13:16:58', u'id': 105, u'isDir': True, u'parent': 104, u'starred': u'2012-08-26T13:18:34', u'title': u'Bird-Brains'}, u'song': [{u'album': u'Mezzanine', u'albumId': 4, u'artist': u'Massive Attack', u'artistId': 0, u'bitRate': 256, u'contentType': u'audio/mpeg', u'coverArt': 6, u'created': u'2009-06-15T07:48:28', u'duration': 298, u'genre': u'Dub', u'id': 72, u'isDir': False, u'isVideo': False, u'parent': 6, u'path': u'Massive Attack/Mezzanine/Massive Attack_02_mezzanine.mp3', u'size': 9564160, u'starred': u'2012-08-26T13:19:26', u'suffix': u'mp3', u'title': u'Risingson', u'track': 2, u'type': u'music'}, {u'album': u'Mezzanine', u'albumId': 4, u'artist': u'Massive Attack', u'artistId': 0, u'bitRate': 256, u'contentType': u'audio/mpeg', u'coverArt': 6, u'created': u'2009-06-15T07:48:25', u'duration': 380, u'genre': u'Dub', u'id': 71, u'isDir': False, u'isVideo': False, u'parent': 6, u'path': u'Massive Attack/Mezzanine/Massive Attack_01_mezzanine.mp3', u'size': 12179456, u'starred': u'2012-08-26T13:19:03', u'suffix': u'mp3', u'title': u'Angel', u'track': 1, u'type': u'music'}]}, u'status': u'ok', u'version': u'1.8.0', u'xmlns': u'http://subsonic.org/restapi'}
Since API version: 1.8.0
Returns starred songs, albums and artists like getStarred(), but this uses ID3 tags for organization.
See the output from getStarred(self)
Since API version: 1.3.0
Get details about a given user, including which auth roles it has. Can be used to enable/disable certain features in the client, such as jukebox control.
Name | Type | Description |
---|---|---|
username | str | The username to retrieve. You can only retrieve your own user unless you have admin privs. |
Returns a dict like the following:
{ u'user': {u'adminRole': False, u'commentRole': False, u'coverArtRole': False, u'downloadRole': True, u'jukeboxRole': False, u'playlistRole': True, u'podcastRole': False, u'settingsRole': True, u'streamRole': True, u'uploadRole': True, u'username': u'test' } u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.8.0
Returns all video files
Returns a dict like the following:
{u'status': u'ok', u'version': u'1.8.0', u'videos': {u'video': {u'bitRate': 384, u'contentType': u'video/x-matroska', u'created': u'2012-08-26T13:36:44', u'duration': 1301, u'id': 130, u'isDir': False, u'isVideo': True, u'path': u'South Park - 16x07 - Cartman Finds Love.mkv', u'size': 287309613, u'suffix': u'mkv', u'title': u'South Park - 16x07 - Cartman Finds Love', u'transcodedContentType': u'video/x-flv', u'transcodedSuffix': u'flv'}}, u'xmlns': u'http://subsonic.org/restapi'}
Since API version: 1.9.0
Creates an HTTP live streaming playlist for streaming video or audio HLS is a streaming protocol implemented by Apple and works by breaking the overall stream into a sequence of small HTTP-based file downloads. It's supported by iOS and newer versions of Android. This method also supports adaptive bitrate streaming, see the bitRate parameter.
Name | Type | Description |
---|---|---|
mid | str | The ID of the media to stream |
bitrate | str | If specified, the server will attempt to limit the bitrate to this value, in kilobits per second. If this parameter is specified more than once, the server will create a variant playlist, suitable for adaptive bitrate streaming. The playlist will support streaming at all the specified bitrates. The server will automatically choose video dimensions that are suitable for the given bitrates. (since: 1.9.0) you may explicitly request a certain width (480) and height (360) like so: bitRate=1000@480×360 |
Returns the raw m3u8 file as a string
Since API version: 1.2.0
NOTE: Some options were added as of API version 1.7.0
Controls the jukebox, i.e., playback directly on the server's audio hardware. Note: The user must be authorized to control the jukebox
Name | Type | Description |
---|---|---|
action | str | The operation to perform. Must be one of: get, start, stop, skip, add, clear, remove, shuffle, setGain, status (added in API 1.7.0), set (added in API 1.7.0) |
index | int | Used by skip and remove. Zero-based index of the song to skip to or remove. |
sids | str | Used by “add” and “set”. ID of song to add to the jukebox playlist. Use multiple id parameters to add many songs in the same request. Whether you are passing one song or many into this, this parameter MUST be a list |
gain | float | Used by setGain to control the playback volume. A float value between 0.0 and 1.0 |
offset | int | (Added in API version: 1.7.0) Used by the “skip” action. Start playing this many seconds into the track. |
Since API version: 1.0.0
Returns a boolean True if the server is alive, False otherwise
Since API version: 1.9.0
Tells the server to check for new Podcast episodes. Note: The user must be authorized for Podcast administration
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.5.0
“Scrobbles” a given music file on last.fm. Requires that the user has set this up.
Name | Type | Description |
---|---|---|
sid | str | The ID of the file to scrobble |
submission | bool | Whether this is a “submission” or a “now playing” notification |
listenTime | int | The unix timestamp for the listen to scrobble. |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.0.0
DEPRECATED SINCE API 1.4.0! USE search2()
INSTEAD!
Returns a listing of files matching the given search criteria. Supports paging with offset
Name | Type | Description |
---|---|---|
artist | str | Search for artist |
album | str | Search for album |
title | str | Search for title of song |
any | str | Search all fields |
count | int | Max number of results to return [default: 20] |
offset | int | Search result offset. For paging [default: 0] |
newerThan | int | Return matches newer than this timestamp |
Since API version: 1.4.0
Returns albums, artists and songs matching the given search criteria. Supports paging through the result.
Name | Type | Description |
---|---|---|
query | str | The search query |
artistCount | int | Max number of artists to return [default: 20] |
artistOffset | int | Search offset for artists (for paging) [default: 0] |
albumCount | int | Max number of albums to return [default: 20] |
albumOffset | int | Search offset for albums (for paging) [default: 0] |
songCount | int | Max number of songs to return [default: 20] |
songOffset | int | Search offset for songs (for paging) [default: 0] |
Returns a dict like the following:
{ u'searchResult2': {u'album': [{u'artist': u'A Tribe Called Quest', u'coverArt': u'289347', u'id': u'32487298', u'isDir': True, u'parent': u'98374289', u'title': u'The Love Movement' }] , u'artist': [{u'id': u'2947839', u'name': u'A Tribe Called Quest' }, {u'id': u'239847239', u'name': u'Tribe' }], u'song': [{u'album': u'Beats, Rhymes And Life', u'artist': u'A Tribe Called Quest', u'bitRate': 224, u'contentType': u'audio/mpeg', u'coverArt': u'329847', u'duration': 148, u'genre': u'default', u'id': u'3928472893', u'isDir': False, u'isVideo': False, u'parent': u'23984728394', u'path': u'A Tribe Called Quest/Beats, Rhymes And Life/A Tribe Called Quest - Beats, Rhymes And Life - 03 - Motivators.mp3', u'size': 4171913, u'suffix': u'mp3', u'title': u'Motivators', u'track': 3 }] } , u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Since API version: 1.8.0
Works the same way as search2(), but uses ID3 tags for organization
Name | Type | Description |
---|---|---|
query | str | The search query |
artistCount | int | Max number of artists to return [default: 20] |
artistOffset | int | Search offset for artists (for paging) [default: 0] |
albumCount | int | Max number of albums to return [default: 20] |
albumOffset | int | Search offset for albums (for paging) [default: 0] |
songCount | int | Max number of songs to return [default: 20] |
songOffset | int | Search offset for songs (for paging) [default: 0] |
Returns a dict like the following:
{u'searchResult3': {u'album': [{u'artist': u'Tune-Yards', u'artistId': 1, u'coverArt': u'al-7', u'created': u'2012-01-30T12:35:33', u'duration': 3229, u'id': 7, u'name': u'Bird-Brains', u'songCount': 13}, {u'artist': u'Tune-Yards', u'artistId': 1, u'coverArt': u'al-8', u'created': u'2011-03-22T15:08:00', u'duration': 2531, u'id': 8, u'name': u'W H O K I L L', u'songCount': 10}], u'artist': {u'albumCount': 2, u'coverArt': u'ar-1', u'id': 1, u'name': u'Tune-Yards'}, u'song': [{u'album': u'Bird-Brains', u'albumId': 7, u'artist': u'Tune-Yards', u'artistId': 1, u'bitRate': 160, u'contentType': u'audio/mpeg', u'coverArt': 105, u'created': u'2012-01-30T12:35:33', u'duration': 328, u'genre': u'Lo-Fi', u'id': 107, u'isDir': False, u'isVideo': False, u'parent': 105, u'path': u'Tune Yards/Bird-Brains/10-tune-yards-fiya.mp3', u'size': 6588498, u'suffix': u'mp3', u'title': u'Fiya', u'track': 10, u'type': u'music', u'year': 2009}]}, u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi'}
Sets the appName
, as is set in init
to the new appName
Changes the base url to url
Sets the connection password to password
Sets the connection port to port
Since API version: 1.6.0
Sets the rating for a media file
Name | Type | Description |
---|---|---|
id | str | The id of the item (song/artist/album) to rate |
rating | int | The rating between 1 and 5 (inclusive), or 0 to remove the rating |
Returns a dict like the following:
{ u'status': u'ok', u'version': u'1.5.0', u'xmlns': u'http://subsonic.org/restapi' }
Sets the path portion of the url to path
. See init
Changes the connection username to username
Since API version: 1.0.0
Streams a given music file.
Name | Type | Description |
---|---|---|
sid | str | The ID of the music file to download. |
maxBitRate | int | (since API version: 1.2.0) If specified, the server will attempt to limit the bitrate to this value, in kilobits per second. If set to zero (default), no limit is imposed. Legal values are: 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320. |
tformat | str | (since: 1.6.0) Specifies the target format (e.g. “mp3” or “flv”) in case there are multiple applicable transcodings (since: 1.9.0) You can use the special value “raw” to disable transcoding |
timeOffset | int | (since: 1.6.0) Only applicable to video streaming. Start the stream at the given offset (in seconds) into the video |
size | str | (since: 1.6.0) The requested video size in WxH, for instance 640×480 |
estimateContentLength | bool | (since: 1.8.0) If set to True, the HTTP Content-Length header will be set to an estimated value for trancoded media |
Returns the file-like object for reading or raises an exception on error
Since API version: 1.6.0
Updates the description and/or expiration date for an existing share
Name | Type | Description |
---|---|---|
shid | str | The id of the share to update |
description | str | The new description for the share (optional). |
expires | float | The new timestamp for the expiration time of this share (optional). |
These are the constants defined for the class:
The version of the Subsonic API that this library currently supports.
A mapping of numbers to libsonic.error.*
. This is for internal use to map the error number from the server to the correct error type in this library.
The basic usage