Commit Graph

691 Commits

Author SHA1 Message Date
Tim Gates
44970c3348
docs: fix simple typo, retrival -> retrieval (#629)
There is a small typo in spotipy/oauth2.py.

Should read `retrieval` rather than `retrival`.
2020-12-26 08:47:11 +01:00
Peter DeVita
3ae3d8cab1
Fix Spotify.user_playlist_reorder_items parameter order (#628)
* Fix Spotify.user_playlist_reorder_items

* Update CHANGELOG.md
2020-12-26 08:46:58 +01:00
Tony Jackson
9550c8fd86
Create CacheHandler to abstract caching tokens (#625)
* Refactor functions into static methods of AuthBase

Functions is_token_expired was a loose function that was added to
SpotifyClientCredentials, SpotifyPKCE, and SpotifyImplicitGrant classes
through a method on each class that passed the call to the loose
is_token_expired function. Function _is_scope_subset was duplicated on
SpotifyClientCredentials, SpotifyPKCE, and SpotifyImplicitGrant classes.

Refactoring is_token_expired and _is_scope_subset to be static methods
on SpotifyAuthBase means both are available for all derived classes and
require less boilerplate.

* Create CacheHandler to abstract caching tokens

Previous code only supported caching to and from json files in a given
directory. In addition, the get_cached_token method mixed getting and
getting the token in the same method.

This change creates a CacheHandler class to abstract out the caching
implementation and allow the user to cache tokens in any way they
see fit. For example, the user could create a MongoCache class to store
and retrieve tokens from a Mongo database and specify that
cache_handler=MongoCache in creating an auth_manager object.

To implement the CacheHandler abstraction, the following changes are
implemented:

The validation code in each get_cached_token method in SpotifyOAuth,
SpotifyPKCE, and SpotifyImplicitGrant is moved into a validate_token
method in each class.

The CacheHandler class is created with get_cached_token and
save_token_to_cache methods.

Previous instances of self.get_cached_token() are now replaced with
self.validate_token(self.cache_handler.get_cached_token()) to preserve
the getting and validation behaviour.

cache_handler is added as an argument to SpotifyOAuth, SpotifyPKCE, and
SpotifyImplicitGrant. Specifying a cache_handler now overrides any
specification of cache_path and/or username.

To preserve backwards compatibility in handling cache files, a
CacheFileHandler class extending CacheHandler is created. If no
cache_handler is specified, the cache_path and username arguments are
used to create an instance of CacheFileHandler. It may be worth
deprecating the cache_path and username fields in favour of using
CacheFileHandler.

Tests are also modified and extended to cover the new functionality. A
sample MemoryCache CacheHandler is created to test getting and saving to
a custom CacheHandler.

* Fix cache_handler subclass check for Python 2

* Split assert message to fix line over max length

* Split cache handlers into cache_handler.py

* flake8 and autopep fixes

* Fix init to allow importing CacheHandler

When spotipy is installed as a package, CacheHandler is not accessible
from a `from spotipy import CacheHandler` statement because the import
is not specified in the __init__.py file. This commit adds CacheHandler
and CacheFileHandler to the init file so the user can import them.

* flake8 fix
2020-12-21 11:31:21 +01:00
Joshua Baunach
ec8a1105b1
Fix examples for saved tracks (#624)
This fixes the examples showin in delete_a_saved_track.py and contains_a_saved_track.py
2020-12-13 02:55:42 +00:00
Peter Schorn
94e164385e
Added more logging and fixed docs for search endpoint (#609)
* Added an exception clause that catches `FileNotFoundError` and logs a debug message in `SpotifyOAuth.get_cached_token`, `SpotifyPKCE.get_cached_token` and `SpotifyImplicitGrant.get_cached_token`.

* Changed docs for `auth` parameter of `Spotify.init` to `access token` instead of `authorization token`. In issue #599, a user confused the access token with the authorization code.

* Updated CHANGELOG.md

* Removed `FileNotFoundError` because it does not exist in python 2.7 (*sigh*) and replaced it with a call to `os.path.exists`.

* Replaced ` os.path.exists` with `error.errno == errno.ENOENT` to supress errors when the cache file does not exist.

* Changed docs for `search` to mention that you can provide multiple multiple types to search for. The query parameters of requests are now logged. Added log messages for when the access token and refresh tokens are retrieved and when they are refreshed. Other small grammar fixes.

* Removed duplicate word "multiple" from CHANGELOG

Co-authored-by: Stéphane Bruckert <stephane.bruckert@gmail.com>
2020-11-15 22:22:41 +00:00
Rob Sanek
7531d141c0
Add market argument to track info (#610) 2020-11-15 22:20:11 +00:00
Peter Schorn
d920f77713
Suppress warnings when cache path does not exist. (#608)
* Added an exception clause that catches `FileNotFoundError` and logs a debug message in `SpotifyOAuth.get_cached_token`, `SpotifyPKCE.get_cached_token` and `SpotifyImplicitGrant.get_cached_token`.

* Changed docs for `auth` parameter of `Spotify.init` to `access token` instead of `authorization token`. In issue #599, a user confused the access token with the authorization code.

* Updated CHANGELOG.md

* Removed `FileNotFoundError` because it does not exist in python 2.7 (*sigh*) and replaced it with a call to `os.path.exists`.

* Replaced ` os.path.exists` with `error.errno == errno.ENOENT` to supress errors when the cache file does not exist.
2020-11-11 23:44:05 +00:00
Miguel Ángel
3f2592d631
Small adjustment on sign_out function (#603)
* Small adjustment on sing_out function

First, thanks for this. It has been a great help. I was having trouble with this function, getting a TypeError (TypeError: can only concatenate str (not "NoneType") to str) because apparently the second os.remove(session_cache_path()) is trying to delete a file that does not exist anymore so this is what worked for me.

* Change description on app.py file

* Update app.py on line 79

Fixed indent
2020-11-11 19:55:29 +00:00
Stephane Bruckert
8198947428 Bump to 2.16.1 2020-10-24 14:41:14 +01:00
Stéphane Bruckert
dd948c49d9
Retry for POST, PUT and DELETE, fixes #577 (#596)
* Retry for POST, PUT and DELETE, fixes #577

* Lint
2020-10-24 14:32:04 +01:00
slipstream42
275cd7ea89
Added scope, 'playlist-read-private', to examples that access user playlists using the spotipy api: current_user_playlists() (fixes #591) (#595)
* - Added scope, 'playlist-read-private', to examples that access user playlists using the spotipy api: current_user_playlists() (fixes #591)

* Fix example to use user_playlists again

Co-authored-by: Stephane Bruckert <stephane.bruckert@gmail.com>
2020-10-23 22:57:14 +01:00
fathom9x
bea781d28f
Fixed output of playlist_tracks example (#594)
Co-authored-by: Chris Danger <chris@The-Castle-Tower.local>
2020-10-23 17:35:16 +01:00
Stéphane Bruckert
36b857dc15
Improve help.md 2020-10-22 09:05:40 +01:00
Ali Reza Yahyapour
f9422eb384
isort Module is Observed in /spotipy/* (#589)
* isort observed

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update CONTRIBUTING.md
2020-10-20 00:13:14 +01:00
Stéphane Bruckert
88ad7e05d5
Create help.md issue template 2020-10-17 13:28:04 +01:00
Callum
4bb42598e1
Fixed UnboundLocalError / AttributeError #571, #581 (#583)
* Fix plamere/spotipy#571, plamere/spotipy#581

* Add integration test for reaching max retries

* Update tests/integration/test_non_user_endpoints.py

Co-authored-by: Stéphane Bruckert <contact@stephanebruckert.com>

* Update CHANGELOG.md, integration test mock data

Co-authored-by: Stéphane Bruckert <contact@stephanebruckert.com>
2020-10-07 09:00:45 +01:00
Stéphane Bruckert
76b640ae1e
Revert "Fixed UnboundLocalError #571 (#580)" (#582)
This reverts commit 18e82b6625.
2020-10-06 08:01:52 +01:00
Nicklas Tegner
18e82b6625
Fixed UnboundLocalError #571 (#580) 2020-10-02 22:26:47 +01:00
Stephane Bruckert
406f7deeda Bump to 2.16.0 2020-09-16 17:22:35 +01:00
Nick
87fe473672
Allow open_browser to be set on creation of auth_manager (SpotifyOAuth/SpotifyPKCE) (#574)
* Fix plamere/spotipy#560

* Adhere to code style

* Update CHANGELOG.md for changes in 939f869bbc

* open_browser passed to get_auth_response should take precedence over the same argument in the constructor

* Update FAQ

* Add information about headless auth

* Add headless auth example
2020-09-12 12:14:08 +01:00
Stephane Bruckert
a42f2ccd0f Bump to 2.15.0 2020-09-08 10:57:07 +01:00
Stéphane Bruckert
d0ca977647
Made cache_path and username optional (#567)
* Made cache_path and username optional

* Update readme and example

* Lint

* Lint

* Feedback / add warning
2020-08-30 23:59:38 +01:00
IdmFoundInHim
d448d33704
Add Warning to SpotifyImplicitGrant.__init__ (#568)
* Clean up namespace in SpotifyPKCE._get_auth_response_interactive

* Add Warning to SpotifyImplicitGrant.__init__

* Update changelog with addition of warning
2020-08-30 17:02:18 +01:00
IdmFoundInHim
df99eab61c
Refinement of PKCE (#566)
* Improve SpotifyPKCE.get_authorization_url

Ensure that a code challenge has been generated for the auth url

* Clean up namespace in SpotifyPKCE._get_auth_response_interactive

* Duplicate parse_auth_response_url into SpotifyPKCE

* Update SpotifyPKCE security advisory

* Update changelog for PKCE refinements
2020-08-30 11:01:05 +01:00
Stéphane Bruckert
c927f02c1c
Bump to 2.14.0 (#565)
* Add missing changelog entries

* Mark search_markets as experimental

* Bump to 2.14.0

* Improve FAQ, closes #522

* Remove non-beginner friendly exports from README, closes #521
2020-08-29 13:00:49 +01:00
Ilya Gubins
a7dfda54d3
Adds option to retrieve currently playing podcast episode. Fixes #562 (#563)
* Adds option to retrieve currently playing podcast episode. Fixes #562

* Fixing lint error: a bit over the 99 character limit

* Fixing lint error: ugh
2020-08-29 11:38:39 +01:00
Stéphane Bruckert
3eb3154ddc
Enforce changelog (#564)
* Enforce changelog

* Update changelog
2020-08-29 11:37:21 +01:00
Bram Kragten
5e9f97df8e
Add category info (#561)
* Add category info

* Add slash

* Add test
2020-08-27 20:49:56 +01:00
Paul Lamere
651080e3da
Fix playlist add items (#559)
* fixed uri issue in playlist_add_items

All uris were being converted to track uris
making it impossible to add episodes to playlists.

* Added tests for episode adds

also fixed creep uri so those tests no longer fail

* Fixed creep_url to match creep_uri

* revert pip version, added FIX to changelog

Co-authored-by: Paul Lamere <paull@spotify.com>
2020-08-25 19:37:53 +01:00
IdmFoundInHim
3d48d77615
Add code parameter to get_access_token of SpotifyPKCE (#556)
* Add code parameter to oauth2.SpotifyPKCE.get_access_token

* Fix the PKCE integration test cache
2020-08-24 19:57:05 +01:00
Mike iLL Kilmer
004df7b2df
A few updates to the example app (#540)
* No username needed + can be used by multiple users

* cleanup

* Remove caches when signing out

* Persist token only once

* Always show auth page

* Add one scope..

* Add a second scope and also a view which utilizes a scope.

* Add a __main__ clause example.

* Include further documentation.

* Move utility function higher in document.

* Add threading to application run call in __main__.

* Add (or reinstate–I thought it had been there) the "me" view.

* Add notes about SPOTIPY_REDIRECT_URI and using alternate port.

And specify that it should be the address that the App runs over.

* Whitespace only.

* Here is an example of importing credentials.

* Delete session_cache file on logout so new user can Authorize.

* Not going to use at this point.

* Update the "me" route method to use new approach to auth.

* Update app.py

Co-authored-by: Stephane Bruckert <contact@stephanebruckert.com>
Co-authored-by: Stephane Bruckert <stephane.bruckert@gmail.com>
2020-07-30 23:05:47 +01:00
Stéphane Bruckert
d211a33618
Update CHANGELOG.md 2020-07-27 06:51:21 +01:00
BozeBro
f95d065a38
Update CHANGELOG.md (#548) 2020-07-27 06:49:45 +01:00
BozeBro
d1c16daa97
Added the parameter collaborative to user_playlist_create and "collaborative" key into data (#546) 2020-07-27 06:49:30 +01:00
Stéphane Bruckert
f136442c2d
Fix Flask example app (#539) 2020-07-26 20:46:35 +01:00
Esamanoaz
36bbf7d15e
Give a reason for player errors in SpotifyException (#543)
* Added reason to SpotifyException

* Updated the changelog

* Fixing code style

Co-authored-by: Stéphane Bruckert <stephane.bruckert@gmail.com>
2020-07-23 17:08:47 +01:00
Yingshiuan Pan
bb4c98033f
Advertise preferred language to Spotify (#544)
Some artist or track provide different translation for different language
usage. This requires send http request with Accept-Language in header.
Create this option for people who wants to see proper translation.
2020-07-23 17:06:28 +01:00
DJSdev
c425102659
Adding Initial PKCE Auth Flow Support (#542)
* Added base funtionality for PKCE Authorization - i538

* fixed a mistake with the auth code

* fixed more misunderstandings. fixed grant_access_token to now call authorization if needed

* added comments and references to code verifier and code challenge

* removed debug print statement

* updated unit tests for new PKCE flow

* cleaned up username issues - added doc strings to class

* fixed import issue, added user endpoint tests

* forgot to commit this file

* linted

* clarified comment

* no longer generates code verifier or challenge in constructor, only when needed

* fixed flake8 complaints, added forgotten unit tests

* fixed linting with unit tests

* anotha one

* added python3.5 support

* linting

* added to CHANGELOG

* removed as_dict option from get_access_token()

Co-authored-by: tomCLANCC <26153156+tomCLANCC@users.noreply.github.com>
2020-07-21 17:08:09 +01:00
IdmFoundInHim
88cf75b778
Update Playlist Endpoints and Add Following Endpoints (#531)
* Update playlist endpoints to modern format

Deprecate user_playlist_* in favor of the following replacements:
* user_playlist_change_details -> playlist_change_details
* user_playlist_unfollow -> current_user_unfollow_playlist
* user_playlist_add_tracks -> playlist_add_tracks
* user_playlist_replace_tracks -> playlist_replace_tracks
* user_playlist_reorder_tracks -> playlist_reorder_tracks
* user_playlist_remove_all_occurrences_of_tracks -> playlist_remove_all_occurrences_of_tracks
* user_playlist_remove_specific_occurrences_of_tracks -> playlist_remove_specific_occurrences_of_tracks
* user_playlist_follow_playlist -> current_user_follow_playlist
* user_playlist_is_following -> playlist_is_following

* Add current_user_following_artists and current_user_following_users

* Update tests and examples

Resolve TODO in test_user_endpoints.py > SpotifyFollowApiTests.test_user_follows_and_unfollows_user

Use modern playlist endpoints (no username required) in tests and examples.

* Update changelog

* Deprecate playlist_tracks in favor of playlist_items

* Link deprecated functions to new functions and change tracks to items

* Fix references to playlist_tracks

* Change test_playlist_add_items as requested
2020-07-11 11:23:18 +01:00
foobuzz
cc5e234a28
Allow for total headless mode by instructing the user to open the URL in a browser. (#528)
* Allow for total headless mode by instructing the user to open the URL in a browser.

* Fix line too long

* Update changelog

* Clarify changelog entry

* Remove reduntant log about pasting the URL.
2020-07-08 17:45:17 +01:00
Nathan LeRoy
f7fb8757e9
Fix return object formatting for multi-market searches (#527)
* resolve return object formatting issues referened in #526

* resolve comments from @ritiek

* create separate method to search multiple markets

* Use old description again

* market -> markets + fix test

* pep8

* Use break

Co-authored-by: Stephane Bruckert <contact@stephanebruckert.com>
2020-07-07 07:20:23 +01:00
Mike iLL Kilmer
7eb0eaaebc
Add redirect_uri (#529)
And specify that it should be the address that the App runs over.
2020-07-06 18:58:39 +01:00
Nathan LeRoy
2bfa7e0151
Add support to search multiple markets at once (#526)
* Add support to search multiple markets. Pass in a list or ALL to search all markets.

* pep8 formatting and verification with flake8

* work on comments from stephanebruckert

* pep8 formatting

* run autopep8 formatting

* fix typo

* allow tuple of markets to be passed. Add unit tests for this case
2020-07-03 19:31:52 +01:00
Omglolyes
a8b77ac37d
Get all non-local tracks from a spotify playlist (#518)
* Create playlist_all_tracks.py

* Update playlist_all_tracks.py

forgot first items from playlist

* print result instead of returning it

* rename to playlist_all_non_local_tracks

* Update playlist_all_non_local_tracks.py

removed "== True" as it's implied
give an example playlist (global top 50)
more comments
corrected typo

* print only length and excluding instead of entire result
2020-06-30 18:15:25 +01:00
Stephane Bruckert
24df9ea4cf Bump to 2.13.0 2020-06-25 22:04:44 +01:00
IdmFoundInHim
38515689bc
Support Implicit Grant Authorization Flow (Fix #499) (#515)
* Add SpotifyImplicitGrant with get_access_token and get_cached_token (and minimum related functions)

* Add some overlooked necessary methods/values in SpotifyImplicitGrant

* Remove unsuppported functionality and make SpotifyImplicitGrant public

* Allow/Expose integration of SpotifyImplicitGrant in client

* Add Implicit Grant tests and decrease abilities of prompt_for_user_token

Remove Implicit Grant and state support from prompt_for_user_token

* Add documentation and changelog entry

* Touch up PEP8 compliance

* Ignore long line with link for flake8

* Correct changelog

* Restore compatibility with Python 2.7

* Correct help(SpotifyImplicitGrant.get_access_token)

* Remove as_dict from SpotifyImplicitGrant.get_access_token

* Combine status check functionality with implicit grant support

In oauth2.py:
* Add state checking to SpotifyImplicitGrant
* Add dedicated SpotifyStateError as subclass of SpotifyOauthError
* Moved `_get_user_input` from SpotifyOAuth to superclass SpotifyAuthBase
* Renamed `parse_oauth_response_url` to `parse_auth_response_url`
* Moved error handling into `parse_auth_response_url`

Made minor changes in tests and client.py accordingly

* Update changelog

* Trim down tests for SpotifyImplicitGrant

* Fix trailing whitespace
2020-06-25 21:39:51 +01:00
foobuzz
ed136d15df
Check the state (#509)
* - Verify that the state received alongside the authorization code is consistent with the one sent
- Refactor URL parsing for the local server way and the interactive way
- Add tests for interactive way

* Resurrect public methods parse_response_code and get_authorization_code

* Use new method parse_oatuh_response_url for parse_response_code implementation.
2020-06-20 21:48:19 +01:00
kenmacf
d7ebc611b2
Enable market parameter for album_tracks (#516)
* enable market parameter for album_tracks

* update album_tracks docstring, add CHANGELOG entry
2020-06-19 22:30:54 +01:00
Stephane Bruckert
ccc73b9d22 Update Issues section 2020-06-15 21:28:13 +01:00
Stephane Bruckert
25e6ed61bb Update issue templates 2020-06-15 21:22:08 +01:00