A Ruby interface to the Napster API.
Add this line to your application's Gemfile:
gem 'napster'
And then execute:
$ bundle
Or install it yourself as:
$ gem install napster
Ruby version should be 2.0 or greater.
A client prepares you to make calls to Napster API. Here is an example code for setting up a client using implicit method.
require 'napster'
options = {
api_key: 'API_KEY',
api_secret: 'API_SECRET',
}
client = Napster::Client.new(options)
You can still set up a client with just an access token. However, you will not be able to refresh the access token and you won't be able to make any metadata calls. Only authenticated member calls will be allowed with this client.
options = { access_token: 'ACCESS_TOKEN' }
client = Napster::Client.new(options)
client_hash = {
api_key: 'API_KEY',
api_secret: 'API_SECRET',
username: 'USERNAME',
password: 'PASSWORD'
}
# Just by instantiating with api_key, api_secret, username, and password
# you can authenticate by password_grant.
client = Napster::Client.new(client_hash)
client.authentication.access_token # => returns access_token
client.authentication.refresh_token
client.authentication.expires_in
client_hash = {
api_key: 'API_KEY',
api_secret: 'API_SECRET'
}
client = Napster::Client.new(client_hash)
client.username = 'USERNAME'
client.password = 'PASSWORD'
client.connect
client.authentication.access_token # => returns access_token
client.authentication.refresh_token
client.authentication.expires_in
client_hash = {
api_key: 'API_KEY',
api_secret: 'API_SECRET',
redirect_uri: 'REDIRECT_URI',
auth_code: 'AUTH_CODE'
}
client = Napster::Client.new(client_hash)
client.connect
client.authentication.access_token # => returns access_token
client.authentication.refresh_token
client.authentication.expires_in
Napster API's access_token
expires in 24 hours after it is issued.
You need to use the refresh_token
to generate a new access_token
when
it is expired.
It is not recommended to get a new access_token - refresh_token through authentication after the old access_token expires.
client.refresh # => returns new access_token by refreshing it
Metadata endpoints do not need the client to be authenticated.
First, set up a client with api_key
and api_secret
.
Then you can call metadata endpoints following this pattern.
# takes a form of client.[resources].[method]
# albums
client.albums.new_releases(limit: 10)
client.albums.staff_picks(limit: 10)
client.albums.top(limit: 10)
client.albums.find(artist_id) # => returns an album
client.albums.find(artist_name) # => returns an album
client.albums.find(artist_id).tracks(limit: 10) # => returns an album
client.albums.find(artist_name).tracks(limit: 10) # => returns an album
# artists
client.artists.top(limit: 5)
client.artists.find(artist_id) # => returns an artist
client.artists.find(artist_name) # => returns an artist
client.artists.find(artist_id).albums(offset: 5)
client.artists.find(artist_id).new_albums(offset: 5)
client.artists.find(artist_id).tracks(limit: 5)
client.artists.find(artist_id).top_tracks(limit: 5)
# favorites
client.favorites.members_who_favorited_albums('Alb.5153820')
client.favorites.members_who_favorited_artists('Art.954')
client.favorites.member_favorites_for('Tra.5156528')
# members
client.members.playlists_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
client.members.favorites_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
client.members.favorite_playlists_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
client.members.chart_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
client.members.find('D877082A5CBC5AC7E040960A390313EF')
client.members.find('dduda')
client.members.screenname_available?('dduda')
client.members.find('dduda').playlists(limit: 5)
client.members.find('dduda').favorites(limit: 5)
client.members.find('dduda').favorite_playlists(limit: 5)
client.members.find('dduda').chart(limit: 5)
# playlists
client.playlists.playlists_of_the_day(limit: 3)
client.playlists.featured(limit: 3)
client.playlists.find('pp.125821370')
client.playlists.find('pp.125821370').tracks(limit: 10)
client.playlists.find('pp.125821370').tags
# tags
client.tags.all
client.tags.find('tag.156763217')
# tracks
client.tracks.find('Tra.5156528')
client.tracks.find_by_name('Marvins Room')
Authenticated member endpoints require the client to be authenticated.
First, set up a client with api_key
and api_secret
.
Authenticate the client by going through password grant method or
OAuth2 method.
Ensure that the client has access_token and refresh_token.
Then you can call metadata endpoints following this pattern.
# takes a form of client.me.[resources].[method]
# favorites
client.me.favorites.get(limit: 5)
client.me.favorites.status(['Art.954', 'Alb.5153820', 'Tra.5156528'])
client.me.favorites.add(['Art.954', 'Alb.5153820', 'Tra.5156528'])
client.me.favorites.remove('Art.954')
# followers
client.me.followers.members(limit: 5)
client.me.followers.by?(guids)
# following
client.me.following.members(limit: 5)
client.me.following.by?(guids)
client.me.following.follow(guids)
client.me.following.unfollow(guids)
# library
client.me.library.artists(limit: 10)
client.me.library.artist_albums('Art.954', limit: 10)
client.me.library.artist_tracks('Art.954', limit: 10)
client.me.library.albums(limit: 10)
client.me.library.album_tracks('Alb.5153820', limit: 10)
client.me.library.tracks(limit: 10)
client.me.library.add_track(['Tra.5156528'])
client.me.library.remove_track('Tra.5156528')
client.me.library.last_updated_date
# listening history
client.me.listening_history(limit: 10)
# playlists
client.me.playlists.all(limit: 10)
client.me.playlists.create({ 'name' => 'hiphop playlist' })
client.me.playlists.find('mp.123123')
client.me.playlists.update('mp.123123', { 'name' => 'hiphop playlist 2' })
client.me.playlists.delete('mp.123123')
client.me.playlists.set_private('mp.123123', 'public')
client.me.playlists.set_private('mp.123123', 'private')
client.me.playlists.add_tracks('mp.123123', ['Tra.5156528'])
client.me.playlists.recommended_tracks('mp.123123')
client.me.playlists.uploaded_images(id: 'mp.123123', size: 500) # id and size in px
client.me.playlists.sourced_by('my_own_playlists',
{ artists: ['art.123', 'art.234'], tags: ['tag.123', 'tag.234'], guid: 'xyz', sort: 'alpha_asc', include_private: true, limit: 10, offset: 5})
client.me.playlists.find('mp.123123').tracks(limit: 10)
client.me.playlists.find('mp.123123').tags
client.me.playlists.find('mp.123123').uploaded_images(500) # size in px
# profile
client.me.profile.get
client.me.profile.update({ 'me' => { 'bio' => Faker::Lorem.word } })
# tags
client.me.tags.contents('favorite', '', {})
client.artists.top(limit: 5, offset: 5)
request_hash = {
body: {
name: 'name of the playlist',
tags: ['tag.1', 'tag.2'],
privacy: 'public',
tracks: ['tra.1', 'tra.2']
}
}
client.me.create_playlist(request_hash)
Napster gem provides ResponseError
which wraps response errors from Napster
API. You can inspect error attributes as shown below.
begin
client.playlists.find('pp.125821370').tracks({}) # problematic request
rescue Exception => error
puts error.http_status # => 400
puts error.response_body
# => {"code":"BadRequestError","message":"limit query parameter is required"}
puts error.faraday_response.inspect
# => #<Faraday::Response:0x007fe9bc957150 @on_complete_callbacks=[], ...
end
Napster gem uses RSpec and FactoryGirl.
-
Get the API key and API secret from Napster Developers site.
-
Create a file called
config.yml
inspec
directory. -
Add the following with the correct API key and API secret
config_variables:
API_KEY: 'API_KEY'
API_SECRET: 'API_SECRET'
USERNAME: 'USERNAME'
PASSWORD: 'PASSWORD'
REDIRECT_URI: 'REDIRECT_URI'
-
$ bundle install
-
$ rspec
We use yard gem for documentation. In order to run the documenation server,
run, $ bundle exec yard doc
.
Bug reports and pull requests are welcome on GitHub at https://github.com/napster/napster-ruby.
The gem is available as open source under the terms of the MIT License.
Napster and Napster logo are registered and unregistered trademarks of Rhapsody International in the United States and/or other countries. All company, product and service names used in this website are for identification purposes only. All product names, logos, and brands are property of their respective owners.