diff --git a/CHANGELOG.md b/CHANGELOG.md index ced98709..b3403e41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +// Add your changes here and then delete this line + +## [2.17.0] - 2021-02-28 + ### Changed - moved os.remove(session_cache_path()) inside try block to avoid TypeError on app.py example file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5fca0976..5fa2acf8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,6 +36,28 @@ To make sure if the import lists are stored correctly: pip install isort isort . -c -v +### Publishing (by maintainer) + + - Bump version in setup.py + - Bump and date changelog + - Add to changelog: + + ## Unreleased + + // Add your changes here and then delete this line + + - Commit changes + - Package to pypi: + + python setup.py sdist bdist_wheel + python3 setup.py sdist bdist_wheel + twine check dist/* + twine upload --skip-existing dist/*.whl dist/*.gz dist/*.zip + + - Create github release https://github.com/plamere/spotipy/releases with the changelog content + for the version and a short name that describes the main addition + - Verify doc uses latest https://readthedocs.org/projects/spotipy/ + ### Changelog Don't forget to add a short description of your change in the [CHANGELOG](CHANGELOG.md) diff --git a/docs/index.rst b/docs/index.rst index 6dba018f..a6a45cb5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -212,6 +212,23 @@ IDs URIs and URLs In general, any *Spotipy* method that needs an artist, album, track or playlist ID will accept ids in any of the above form + +Customized token caching +======================== + +Tokens are refreshed automatically and stored by default in the project main folder. +As this might not suit everyone's needs, spotipy provides a way to create customized +cache handlers. + +https://github.com/plamere/spotipy/blob/master/spotipy/cache_handler.py + +The custom cache handler would need to be a class that inherits from the base +cache handler ``CacheHandler``. The default cache handler ``CacheFileHandler`` is a good example. +An instance of that new class can then be passed as a parameter when +creating ``SpotifyOAuth``, ``SpotifyPKCE`` or ``SpotifyImplicitGrant``. + +Feel free to contribute new cache handlers to the repo. + Examples ======================= diff --git a/setup.py b/setup.py index d3b85bde..bcae4557 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( name='spotipy', - version='2.16.1', + version='2.17.0', description='A light weight Python library for the Spotify Web API', long_description=long_description, long_description_content_type="text/markdown", diff --git a/tests/integration/test_user_endpoints.py b/tests/integration/test_user_endpoints.py index d008ee08..e5bd9d4b 100644 --- a/tests/integration/test_user_endpoints.py +++ b/tests/integration/test_user_endpoints.py @@ -165,9 +165,9 @@ def test_playlist_add_episodes(self): self.assertEqual(playlist["total"], 0) def test_playlist_cover_image(self): - # Upload random dog image - r = requests.get('https://dog.ceo/api/breeds/image/random') - dog_base64 = helpers.get_as_base64(r.json()['message']) + # From https://dog.ceo/api/breeds/image/random + small_image = "https://images.dog.ceo/breeds/poodle-toy/n02113624_8936.jpg" + dog_base64 = helpers.get_as_base64(small_image) self.spotify.playlist_upload_cover_image(self.new_playlist_uri, dog_base64) res = self.spotify.playlist_cover_image(self.new_playlist_uri) @@ -177,6 +177,18 @@ def test_playlist_cover_image(self): self.assertIn('height', first_image) self.assertIn('url', first_image) + def test_large_playlist_cover_image(self): + # From https://dog.ceo/api/breeds/image/random + large_image = "https://images.dog.ceo/breeds/pointer-germanlonghair/hans2.jpg" + dog_base64 = helpers.get_as_base64(large_image) + try: + self.spotify.playlist_upload_cover_image(self.new_playlist_uri, dog_base64) + except Exception as e: + self.assertIsInstance(e, SpotifyException) + self.assertEqual(e.http_status, 413) + return + self.fail() + def test_deprecated_starred(self): pl = self.spotify.user_playlist(self.username) self.assertTrue(pl["tracks"] is None)