mirror of
https://github.com/spotipy-dev/spotipy.git
synced 2026-06-19 01:03:53 +00:00
Merge branch 'master' of github.com:spotipy-dev/spotipy into v3_rebase_rebase
This commit is contained in:
commit
3c75886229
47
CHANGELOG.md
47
CHANGELOG.md
@ -5,12 +5,55 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
Add your changes below.
|
||||
## Unreleased [3.0.0-alpha]
|
||||
|
||||
While this is unreleased, please only add v3 features here.
|
||||
Rebasing master onto v3 doesn't require a changelog update.
|
||||
|
||||
### Added
|
||||
|
||||
* `Scope` - An enum which contains all of the authorization scopes (see [here](https://github.com/plamere/spotipy/issues/652#issuecomment-797461311)).
|
||||
|
||||
### Changed
|
||||
|
||||
* Made `CacheHandler` an abstract base class
|
||||
* Modified the return structure of the `audio_features` function (wrapping the [Get Audio Features for Several Tracks](https://developer.spotify.com/documentation/web-api/reference/#endpoint-get-several-audio-features) API) to conform to the return structure of the similar methods listed below. The functions wrapping these APIs do not unwrap the single key JSON response, and this is currently the only function that does this.
|
||||
* [Get Several Tracks](https://developer.spotify.com/documentation/web-api/reference/#endpoint-get-several-tracks)
|
||||
* [Get Multiple Artists](https://developer.spotify.com/documentation/web-api/reference/#endpoint-get-multiple-artists)
|
||||
* [Get Multiple Albums](https://developer.spotify.com/documentation/web-api/reference/#endpoint-get-multiple-albums)
|
||||
* Renamed the `auth` parameter of `Spotify.__init__` to `access_token` for better clarity.
|
||||
* Removed the `client_credentials_manager` and `oauth_manager` parameters because they are redundant.
|
||||
* Replaced the `set_auth` and `auth_manager` properties with standard attributes.
|
||||
|
||||
### Removed
|
||||
|
||||
* Removed the following deprecated methods from `Spotify`:
|
||||
* `playlist_tracks`
|
||||
* `user_playlist`
|
||||
* `user_playlist_tracks`
|
||||
* `user_playlist_change_details`
|
||||
* `user_playlist_unfollow`
|
||||
* `user_playlist_add_tracks`
|
||||
* `user_playlist_replace_tracks`
|
||||
* `user_playlist_reorder_tracks`
|
||||
* `user_playlist_remove_all_occurrences_of_tracks`
|
||||
* `user_playlist_remove_specific_occurrences_of_tracks`
|
||||
* `user_playlist_follow_playlist`
|
||||
* `user_playlist_is_following`
|
||||
|
||||
* Removed the deprecated `as_dict` parameter from the `get_access_token` method of `SpotifyOAuth` and `SpotifyPKCE`.
|
||||
* Removed the deprecated `get_cached_token` and `_save_token_info` methods of `SpotifyOAuth` and `SpotifyPKCE`.
|
||||
* Removed `SpotifyImplicitGrant`.
|
||||
* Removed `prompt_for_user_token`.
|
||||
|
||||
## Unreleased [2.x.x]
|
||||
|
||||
### Added
|
||||
- Added examples for audiobooks, shows and episodes methods to examples directory
|
||||
|
||||
### Fixed
|
||||
- Fixed scripts in examples directory that didn't run correctly
|
||||
- Updated documentation for `Client.current_user_top_artists` to indicate maximum number of artists limit
|
||||
|
||||
### Removed
|
||||
|
||||
|
||||
28
examples/add_saved_episodes.py
Normal file
28
examples/add_saved_episodes.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""
|
||||
Add episodes to current user's library
|
||||
Usage: add_saved_episodes.py -e episode_id episode_id ...
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'user-library-modify'
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Add episodes to library')
|
||||
# Default args set to This American Life episodes 814 and 815
|
||||
parser.add_argument('-e', '--eids', nargs='+',
|
||||
default=['6rxg9Lpt2ywNHFea8LxEBO', '7q8or6oYYRFQFYlA0remoy'],
|
||||
help='Episode ids')
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
print('Adding following episode ids to library: ' + str(args.eids))
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
sp.current_user_saved_episodes_add(episodes=args.eids)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
28
examples/add_saved_shows.py
Normal file
28
examples/add_saved_shows.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""
|
||||
Add shows to current user's library
|
||||
Usage: add_saved_shows.py -s show_id show_id ...
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'user-library-modify'
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Add shows to library')
|
||||
# Default args set to Radiolab and 99% invisible
|
||||
parser.add_argument('-s', '--sids', nargs='+',
|
||||
default=['2hmkzUtix0qTqvtpPcMzEL', '2VRS1IJCTn2Nlkg33ZVfkM'],
|
||||
help='Show ids')
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
print('Adding following show ids to library: ' + str(args.sids))
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
sp.current_user_saved_shows_add(shows=args.sids)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
31
examples/check_show_is_saved.py
Normal file
31
examples/check_show_is_saved.py
Normal file
@ -0,0 +1,31 @@
|
||||
"""
|
||||
Check if shows are saved in user's library
|
||||
Usage: check_show_is_saved -s show_id show_id ...
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'user-library-read'
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Check that a show is saved')
|
||||
# Default args set to Radiolab and 99% invisible
|
||||
parser.add_argument('-s', '--sids', nargs='+',
|
||||
default=['2hmkzUtix0qTqvtpPcMzEL', '2VRS1IJCTn2Nlkg33ZVfkM'],
|
||||
help='Show ids')
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
results = sp.current_user_saved_episodes_contains(episodes=args.sids)
|
||||
show_names = sp.shows(shows=args.sids)
|
||||
# Print show names and if show is saved by current user
|
||||
for i, show in enumerate(show_names['shows']):
|
||||
print(show['name'] + ': ' + str(results[i]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
28
examples/delete_saved_episodes.py
Normal file
28
examples/delete_saved_episodes.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""
|
||||
Delete episodes from current user's library
|
||||
Usage: delete_saved_episodes.py -e episode_id episode_id ...
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'user-library-modify'
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Delete episodes from library')
|
||||
# Default args set to This American Life episodes 814 and 815
|
||||
parser.add_argument('-e', '--eids', nargs='+',
|
||||
default=['6rxg9Lpt2ywNHFea8LxEBO', '7q8or6oYYRFQFYlA0remoy'],
|
||||
help='Episode ids')
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
print('Deleting following episode ids from library: ' + str(args.eids))
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
sp.current_user_saved_episodes_delete(episodes=args.eids)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1,27 +1,22 @@
|
||||
import argparse
|
||||
# Follow a playlist
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'playlist-modify-public'
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Follows a playlist based on playlist ID')
|
||||
parser.add_argument('-p', '--playlist', required=True, help='Playlist ID')
|
||||
|
||||
# Default to Top 50 Global if no playlist is provided
|
||||
parser.add_argument('-p', '--playlist', help='Playlist ID', nargs='?', default='37i9dQZEVXbMDoHDwVN2tF')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
|
||||
if args.playlist is None:
|
||||
# Uses the Spotify Global Top 50 playlist
|
||||
spotipy.Spotify(auth_manager=SpotifyOAuth()).current_user_follow_playlist(
|
||||
'37i9dQZEVXbMDoHDwVN2tF')
|
||||
|
||||
else:
|
||||
spotipy.Spotify(auth_manager=SpotifyOAuth()).current_user_follow_playlist(args.playlist)
|
||||
|
||||
sp.current_user_follow_playlist(args.playlist)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
29
examples/get_audiobook_chapters_info.py
Normal file
29
examples/get_audiobook_chapters_info.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
Print chapter titles and lengths for given audiobook
|
||||
Usage: get_audiobooks_chapters_info.py -a audiobook_id
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Get chapter info for an audiobook')
|
||||
# Default set to Dune
|
||||
parser.add_argument('-a', '--audiobook', default='2h01INWMBvfpzNMpGFzhdF', help='Audiobook id')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
print('Getting chapter info for follow audiobook id: ' + str(args.audiobook))
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth())
|
||||
results = sp.get_audiobook_chapters(id=args.audiobook)
|
||||
# Print chapter name and length
|
||||
for item in results['items']:
|
||||
print('Name: ' + item['name'] + ', length: ' + str(round(item['duration_ms']/60000,1)) + ' minutes')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
29
examples/get_audiobooks_info.py
Normal file
29
examples/get_audiobooks_info.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
Print audiobook title and description for a list of audiobook ids
|
||||
Usage: get_audiobooks_info.py -a audiobook_id audiobook_id ...
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Get information for a list of audiobooks')
|
||||
# Defaults set to The Great Gatsby, The Chronicles of Narnia and Dune
|
||||
parser.add_argument('-a', '--aids', nargs='+',
|
||||
default=['6qjpt1CUHhKXiNoeNoU7nu', '1ezmXd68LbDtxebvygEQ2U', '2h01INWMBvfpzNMpGFzhdF'],
|
||||
help='Audiobook ids')
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
print('Getting info for follow audiobook ids: ' + str(args.aids) + '\n')
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth())
|
||||
results = sp.get_audiobooks(ids=args.aids)
|
||||
# Print book title and description
|
||||
for book in results['audiobooks']:
|
||||
print('Title: ' + book['name'] + '\n' + book['description'] + '\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1,12 +0,0 @@
|
||||
# Add a list of items (URI) to a playlist (URI)
|
||||
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id="YOUR_APP_CLIENT_ID",
|
||||
client_secret="YOUR_APP_CLIENT_SECRET",
|
||||
redirect_uri="YOUR_APP_REDIRECT_URI",
|
||||
scope="playlist-modify-private"
|
||||
))
|
||||
|
||||
sp.playlist_add_items('playlist_id', ['list_of_items'])
|
||||
@ -5,6 +5,6 @@ import json
|
||||
auth_manager = SpotifyClientCredentials()
|
||||
sp = spotipy.Spotify(auth_manager=auth_manager)
|
||||
|
||||
playlist_id = 'spotify:user:spotifycharts:playlist:37i9dQZEVXbJiZcmkrIHGU'
|
||||
playlist_id = '37i9dQZEVXbJiZcmkrIHGU'
|
||||
results = sp.playlist(playlist_id)
|
||||
print(json.dumps(results, indent=4))
|
||||
|
||||
@ -7,8 +7,8 @@ from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
playlist_id = sys.argv[2]
|
||||
track_ids = sys.argv[3:]
|
||||
playlist_id = sys.argv[1]
|
||||
track_ids = sys.argv[2:]
|
||||
else:
|
||||
print(f"Usage: {sys.argv[0]} playlist_id track_id ...")
|
||||
sys.exit()
|
||||
|
||||
@ -6,7 +6,7 @@ import sys
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
if len(sys.argv) > 2:
|
||||
playlist_id = sys.argv[1]
|
||||
track_ids = sys.argv[2:]
|
||||
else:
|
||||
|
||||
@ -3,21 +3,26 @@
|
||||
|
||||
given a list of track IDs show the artist and track name
|
||||
'''
|
||||
from spotipy.oauth2 import SpotifyClientCredentials
|
||||
import sys
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
import spotipy
|
||||
import argparse
|
||||
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Print artist and track name given a list of track IDs')
|
||||
parser.add_argument('-u', '--uris', nargs='+',
|
||||
required=True, help='Track ids')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth())
|
||||
track_list = sp.tracks(args.uris)
|
||||
for track in track_list['tracks']:
|
||||
print(track['name'] + ' - ' + track['artists'][0]['name'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
max_tracks_per_call = 50
|
||||
if len(sys.argv) > 1:
|
||||
file = open(sys.argv[1])
|
||||
else:
|
||||
file = sys.stdin
|
||||
tids = file.read().split()
|
||||
main()
|
||||
|
||||
auth_manager = SpotifyClientCredentials()
|
||||
sp = spotipy.Spotify(auth_manager=auth_manager)
|
||||
for start in range(0, len(tids), max_tracks_per_call):
|
||||
results = sp.tracks(tids[start: start + max_tracks_per_call])
|
||||
for track in results['tracks']:
|
||||
print(track['name'] + ' - ' + track['artists'][0]['name'])
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = "user-library-read"
|
||||
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
|
||||
results = sp.current_user_saved_tracks()
|
||||
for idx, item in enumerate(results['items']):
|
||||
track = item['track']
|
||||
print(idx, track['artists'][0]['name'], " – ", track['name'])
|
||||
@ -4,6 +4,8 @@ import logging
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'playlist-modify-public'
|
||||
|
||||
logger = logging.getLogger('examples.unfollow_playlist')
|
||||
logging.basicConfig(level='DEBUG')
|
||||
|
||||
@ -23,9 +25,9 @@ def get_args():
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth())
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
sp.current_user_unfollow_playlist(args.playlist)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
29
examples/user_saved_episodes.py
Normal file
29
examples/user_saved_episodes.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
List current user's saved episodes
|
||||
Usage: user_saved_episodes -l <num> -o <num>
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'user-library-read'
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Show user\'s saved episodes')
|
||||
parser.add_argument('-l', '--limit', default=20, help='Num of episodes to return')
|
||||
parser.add_argument('-o', '--offset', default=0, help='Index of first show to return')
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
results = sp.current_user_saved_episodes(limit=args.limit, offset=args.offset)
|
||||
# Print episode names
|
||||
for item in results['items']:
|
||||
print(item['episode']['name'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
29
examples/user_saved_shows.py
Normal file
29
examples/user_saved_shows.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
List current user's saved shows
|
||||
Usage: user_saved_shows -l <num> -o <num>
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import spotipy
|
||||
from spotipy.oauth2 import SpotifyOAuth
|
||||
|
||||
scope = 'user-library-read'
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description='Show user\'s saved shows')
|
||||
parser.add_argument('-l', '--limit', default=20, help='Num of shows to return')
|
||||
parser.add_argument('-o', '--offset', default=0, help='Index of first show to return')
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
|
||||
results = sp.current_user_saved_shows(limit=args.limit, offset=args.offset)
|
||||
# Print episode names
|
||||
for item in results['items']:
|
||||
print(item['show']['name'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1178,7 +1178,7 @@ class Spotify:
|
||||
""" Get the current user's top artists
|
||||
|
||||
Parameters:
|
||||
- limit - the number of entities to return
|
||||
- limit - the number of entities to return (max 50)
|
||||
- offset - the index of the first entity to return
|
||||
- time_range - Over what time frame are the affinities computed
|
||||
Valid-values: short_term, medium_term, long_term
|
||||
|
||||
Loading…
Reference in New Issue
Block a user