Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-spotipy for openSUSE:Factory 
checked in at 2022-11-12 17:41:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-spotipy (Old)
 and      /work/SRC/openSUSE:Factory/.python-spotipy.new.1597 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-spotipy"

Sat Nov 12 17:41:04 2022 rev:9 rq:1035256 version:2.21.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-spotipy/python-spotipy.changes    
2022-09-30 17:58:18.237313960 +0200
+++ /work/SRC/openSUSE:Factory/.python-spotipy.new.1597/python-spotipy.changes  
2022-11-12 17:41:21.338234602 +0100
@@ -1,0 +2,15 @@
+Wed Nov  9 19:13:31 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com>
+
+- Update to version 2.21.0 
+  Added
+  * Added market parameter to album and albums to address #753
+  * Added 'show_featured_artists.py' to 'examples'.
+  * Expanded contribution and license sections of the documentation.
+  * Added FlaskSessionCacheHandler, a cache handler that stores the token info 
in a flask session.
+  * Added Python 3.10 in GitHub Actions
+  Fixed
+  * Updated the documentation to specify ISO-639-1 language codes.
+  * Fix AttributeError for text attribute of the Response object
+  * Require redis v3 if python2.7 (fixes readthedocs)
+
+-------------------------------------------------------------------

Old:
----
  2.20.0.tar.gz

New:
----
  2.21.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-spotipy.spec ++++++
--- /var/tmp/diff_new_pack.E9yW22/_old  2022-11-12 17:41:21.718236864 +0100
+++ /var/tmp/diff_new_pack.E9yW22/_new  2022-11-12 17:41:21.726236911 +0100
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-spotipy
-Version:        2.20.0
+Version:        2.21.0
 Release:        0
 Summary:        Client for the Spotify Web API
 License:        MIT

++++++ 2.20.0.tar.gz -> 2.21.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/.github/workflows/pythonapp.yml 
new/spotipy-2.21.0/.github/workflows/pythonapp.yml
--- old/spotipy-2.20.0/.github/workflows/pythonapp.yml  2022-06-18 
23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/.github/workflows/pythonapp.yml  2022-10-27 
00:03:42.000000000 +0200
@@ -8,7 +8,7 @@
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [2.7, 3.6, 3.7, 3.8, 3.9]
+        python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"]
 
     steps:
     - uses: actions/checkout@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/CHANGELOG.md 
new/spotipy-2.21.0/CHANGELOG.md
--- old/spotipy-2.20.0/CHANGELOG.md     2022-06-18 23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/CHANGELOG.md     2022-10-27 00:03:42.000000000 +0200
@@ -9,6 +9,22 @@
 
 // Add your changes here and then delete this line
 
+## [2.21.0] - 2022-09-26
+
+### Added 
+
+* Added `market` parameter to `album` and `albums` to address 
([#753](https://github.com/plamere/spotipy/issues/753)
+* Added 'show_featured_artists.py' to 'examples'.
+* Expanded contribution and license sections of the documentation.
+* Added `FlaskSessionCacheHandler`, a cache handler that stores the token info 
in a flask session.
+* Added Python 3.10 in GitHub Actions
+
+### Fixed
+
+* Updated the documentation to specify ISO-639-1 language codes.
+* Fix `AttributeError` for `text` attribute of the `Response` object
+* Require redis v3 if python2.7 (fixes readthedocs)
+
 ## [2.20.0] - 2022-06-18
 
 ### Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/CONTRIBUTING.md 
new/spotipy-2.21.0/CONTRIBUTING.md
--- old/spotipy-2.20.0/CONTRIBUTING.md  2022-06-18 23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/CONTRIBUTING.md  2022-10-27 00:03:42.000000000 +0200
@@ -5,16 +5,24 @@
 ### Export the needed environment variables
 
 ```bash
+# Linux or Mac
 export SPOTIPY_CLIENT_ID=client_id_here
 export SPOTIPY_CLIENT_SECRET=client_secret_here
 export SPOTIPY_CLIENT_USERNAME=client_username_here # This is actually an id 
not spotify display name
 export SPOTIPY_REDIRECT_URI=http://localhost:8080 # Make url is set in app you 
created to get your ID and SECRET
+
+# Windows
+$env:SPOTIPY_CLIENT_ID="client_id_here"
+$env:SPOTIPY_CLIENT_SECRET="client_secret_here"
+$env:SPOTIPY_CLIENT_USERNAME="client_username_here" 
+$env:SPOTIPY_REDIRECT_URI="http://localhost:8080"; 
 ```
 
 ### Create virtual environment, install dependencies, run tests:
 
 ```bash
 $ virtualenv --python=python3.7 env
+$ source env/bin/activate
 (env) $ pip install --user -e .
 (env) $ python -m unittest discover -v tests
 ```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/docs/index.rst 
new/spotipy-2.21.0/docs/index.rst
--- old/spotipy-2.20.0/docs/index.rst   2022-06-18 23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/docs/index.rst   2022-10-27 00:03:42.000000000 +0200
@@ -9,7 +9,7 @@
 you get full access to all of the music data provided by the Spotify platform.
 
 Assuming you set the ``SPOTIPY_CLIENT_ID`` and ``SPOTIPY_CLIENT_SECRET``
-environment variables, here's a quick example of using *Spotipy* to list the
+environment variables (here is a `video <https://youtu.be/3RGm4jALukM>`_ 
explaining how to do so), here's a quick example of using *Spotipy* to list the
 names of all the albums released by the artist 'Birdy'::
 
     import spotipy
@@ -132,7 +132,7 @@
         print(idx, track['artists'][0]['name'], " – ", track['name'])
 
 or if you are reluctant to immortalize your app credentials in your source 
code,
-you can set environment variables like so (use ``SET`` instead of ``export``
+you can set environment variables like so (use ``$env:"credentials"`` instead 
of ``export``
 on Windows)::
 
     export SPOTIPY_CLIENT_ID='your-spotify-client-id'
@@ -235,6 +235,7 @@
   - ``CacheFileHandler``
   - ``MemoryCacheHandler``
   - ``DjangoSessionCacheHandler``
+  - ``FlaskSessionCacheHandler``
   - ``RedisCacheHandler``
 
 Feel free to contribute new cache handlers to the repo.
@@ -292,31 +293,96 @@
 
 Spotipy authored by Paul Lamere (plamere) with contributions by:
 
-  - Daniel Beaudry // danbeaudry
-  - Faruk Emre Sahin // fsahin
-  - George // rogueleaderr
-  - Henry Greville // sethaurus
-  - Hugo // hugovk
-  - José Manuel Pérez // JMPerez
-  - Lucas Nunno // lnunno
-  - Lynn Root // econchick
-  - Matt Dennewitz // mattdennewitz
-  - Matthew Duck // mattduck
-  - Michael Thelin // thelinmichael
-  - Ryan Choi // ryankicks
-  - Simon Metson // drsm79
-  - Steve Winton // swinton
-  - Tim Balzer // timbalzer
-  - corycorycory // corycorycory
-  - Nathan Coleman // nathancoleman
-  - Michael Birtwell // mbirtwell
-  - Harrison Hayes // Harrison97
-  - Stephane Bruckert // stephanebruckert
-  - Ritiek Malhotra // ritiek
+  - Daniel Beaudry (`danbeaudry on Github <https://github.com/danbeaudry>`_)
+  - Faruk Emre Sahin (`fsahin on Github <https://github.com/fsahin>`_)
+  - George (`rogueleaderr on Github <https://github.com/rogueleaderr>`_)
+  - Henry Greville (`sethaurus on Github <https://github.com/sethaurus>`_)
+  - Hugo van Kemanade (`hugovk on Github <https://github.com/hugovk>`_)
+  - José Manuel Pérez (`JMPerez on Github <https://github.com/JMPerez>`_)
+  - Lucas Nunno (`lnunno on Github <https://github.com/lnunno>`_)
+  - Lynn Root (`econchick on Github <https://github.com/econchick>`_)
+  - Matt Dennewitz (`mattdennewitz on Github 
<https://github.com/mattdennewitz>`_)
+  - Matthew Duck (`mattduck on Github <https://github.com/mattduck>`_)
+  - Michael Thelin (`thelinmichael on Github 
<https://github.com/thelinmichael>`_)
+  - Ryan Choi (`ryankicks on Github <https://github.com/ryankicks>`_)
+  - Simon Metson (`drsm79 on Github <https://github.com/drsm79>`_)
+  - Steve Winton (`swinton on Github <https://github.com/swinton>`_)
+  - Tim Balzer (`timbalzer on Github <https://github.com/timbalzer>`_)
+  - `corycorycory on Github <https://github.com/corycorycory>`_
+  - Nathan Coleman (`nathancoleman on Github 
<https://github.com/nathancoleman>`_) 
+  - Michael Birtwell (`mbirtwell on Github <https://github.com/mbirtwell>`_)
+  - Harrison Hayes (`Harrison97 on Github <https://github.com/Harrison97>`_)
+  - Stephane Bruckert (`stephanebruckert on Github 
<https://github.com/stephanebruckert>`_)
+  - Ritiek Malhotra (`ritiek on Github <https://github.com/ritiek>`_)
+
+If you are a developer with Python experience, and you would like to 
contribute to Spotipy, please
+be sure to follow the guidelines listed below:
+
+Export the needed Environment variables:::
+    export SPOTIPY_CLIENT_ID=client_id_here
+    export SPOTIPY_CLIENT_SECRET=client_secret_here
+    export SPOTIPY_CLIENT_USERNAME=client_username_here # This is actually an 
id not spotify display name
+    export SPOTIPY_REDIRECT_URI=http://localhost:8080 # Make url is set in app 
you created to get your ID and SECRET
+
+Create virtual environment, install dependencies, run tests:::
+    $ virtualenv --python=python3.7 env
+    (env) $ pip install --user -e .
+    (env) $ python -m unittest discover -v tests
+
+**Lint**
+
+To automatically fix the code style:::
+    pip install autopep8
+    autopep8 --in-place --aggressive --recursive .
+
+To verify the code style:::
+    pip install flake8
+    flake8 .
+
+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 --repository-url https://upload.pypi.org/legacy/ 
--skip-existing dist/*.(whl|gz|zip)~dist/*linux*.whl
+- 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
+- Build the documentation again to ensure it's on the latest version
+
+**Changelog**
+
+Don't forget to add a short description of your change in the `CHANGELOG 
<https://github.com/plamere/spotipy/blob/master/CHANGELOG.md>`_!
+
+
 
 License
 =======
-https://github.com/plamere/spotipy/blob/master/LICENSE.md
+(Taken from https://github.com/plamere/spotipy/blob/master/LICENSE.md)::
+
+    MIT License
+    Copyright (c) 2021 Paul Lamere
+    Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction, including 
without limitation the rights to use, copy, modify, merge, 
+    publish, distribute, sublicense, and/or sell copies of the Software, and 
to permit persons to whom the Software is furnished to do
+    so, subject to the following conditions:
+    The above copyright notice and this permission notice shall be included in 
all copies or substantial portions of the Software.
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
+    IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
 
 
 Indices and tables
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/examples/app.py 
new/spotipy-2.21.0/examples/app.py
--- old/spotipy-2.20.0/examples/app.py  2022-06-18 23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/examples/app.py  2022-10-27 00:03:42.000000000 +0200
@@ -27,7 +27,6 @@
 from flask import Flask, session, request, redirect
 from flask_session import Session
 import spotipy
-import uuid
 
 app = Flask(__name__)
 app.config['SECRET_KEY'] = os.urandom(64)
@@ -35,57 +34,44 @@
 app.config['SESSION_FILE_DIR'] = './.flask_session/'
 Session(app)
 
-caches_folder = './.spotify_caches/'
-if not os.path.exists(caches_folder):
-    os.makedirs(caches_folder)
-
-def session_cache_path():
-    return caches_folder + session.get('uuid')
 
 @app.route('/')
 def index():
-    if not session.get('uuid'):
-        # Step 1. Visitor is unknown, give random ID
-        session['uuid'] = str(uuid.uuid4())
 
-    cache_handler = 
spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
+    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
     auth_manager = 
spotipy.oauth2.SpotifyOAuth(scope='user-read-currently-playing 
playlist-modify-private',
-                                                cache_handler=cache_handler, 
-                                                show_dialog=True)
+                                               cache_handler=cache_handler,
+                                               show_dialog=True)
 
     if request.args.get("code"):
-        # Step 3. Being redirected from Spotify auth page
+        # Step 2. Being redirected from Spotify auth page
         auth_manager.get_access_token(request.args.get("code"))
         return redirect('/')
 
     if not auth_manager.validate_token(cache_handler.get_cached_token()):
-        # Step 2. Display sign in link when no token
+        # Step 1. Display sign in link when no token
         auth_url = auth_manager.get_authorize_url()
         return f'<h2><a href="{auth_url}">Sign in</a></h2>'
 
-    # Step 4. Signed in, display data
+    # Step 3. Signed in, display data
     spotify = spotipy.Spotify(auth_manager=auth_manager)
     return f'<h2>Hi {spotify.me()["display_name"]}, ' \
            f'<small><a href="/sign_out">[sign out]<a/></small></h2>' \
            f'<a href="/playlists">my playlists</a> | ' \
            f'<a href="/currently_playing">currently playing</a> | ' \
-                  f'<a href="/current_user">me</a>' \
+        f'<a href="/current_user">me</a>' \
+
 
 
 @app.route('/sign_out')
 def sign_out():
-    try:
-        # Remove the CACHE file (.cache-test) so that a new user can authorize.
-        os.remove(session_cache_path())
-        session.clear()
-    except OSError as e:
-        print ("Error: %s - %s." % (e.filename, e.strerror))
+    session.pop("token_info", None)
     return redirect('/')
 
 
 @app.route('/playlists')
 def playlists():
-    cache_handler = 
spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
+    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
     auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
     if not auth_manager.validate_token(cache_handler.get_cached_token()):
         return redirect('/')
@@ -96,7 +82,7 @@
 
 @app.route('/currently_playing')
 def currently_playing():
-    cache_handler = 
spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
+    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
     auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
     if not auth_manager.validate_token(cache_handler.get_cached_token()):
         return redirect('/')
@@ -109,7 +95,7 @@
 
 @app.route('/current_user')
 def current_user():
-    cache_handler = 
spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
+    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
     auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
     if not auth_manager.validate_token(cache_handler.get_cached_token()):
         return redirect('/')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/examples/follow_playlist.py 
new/spotipy-2.21.0/examples/follow_playlist.py
--- old/spotipy-2.20.0/examples/follow_playlist.py      1970-01-01 
01:00:00.000000000 +0100
+++ new/spotipy-2.21.0/examples/follow_playlist.py      2022-10-27 
00:03:42.000000000 +0200
@@ -0,0 +1,23 @@
+import argparse
+
+import spotipy
+from spotipy.oauth2 import SpotifyOAuth
+
+def get_args():
+    parser = argparse.ArgumentParser(description='Follows a playlist based on 
playlist ID')
+    parser.add_argument('-p', '--playlist', required=True, help='Playlist ID')
+    
+    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)
+    
+if __name__ == '__main__':
+    main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/examples/show_featured_artists.py 
new/spotipy-2.21.0/examples/show_featured_artists.py
--- old/spotipy-2.20.0/examples/show_featured_artists.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/spotipy-2.21.0/examples/show_featured_artists.py        2022-10-27 
00:03:42.000000000 +0200
@@ -0,0 +1,27 @@
+# Shows all artists featured on an album
+
+# usage: featured_artists.py spotify:album:[album urn]
+
+from spotipy.oauth2 import SpotifyClientCredentials
+import sys
+import spotipy
+from pprint import pprint
+
+if len(sys.argv) > 1:
+    urn = sys.argv[1]
+else:
+    urn = 'spotify:album:5yTx83u3qerZF7GRJu7eFk'
+
+sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())
+album = sp.album(urn)
+
+featured_artists = set()
+
+items = album['tracks']['items']
+
+for item in items:
+    for ele in item['artists']:
+        if 'name' in ele:
+            featured_artists.add(ele['name'])
+
+pprint(featured_artists)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/setup.py new/spotipy-2.21.0/setup.py
--- old/spotipy-2.20.0/setup.py 2022-06-18 23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/setup.py 2022-10-27 00:03:42.000000000 +0200
@@ -18,18 +18,22 @@
 
 setup(
     name='spotipy',
-    version='2.20.0',
+    version='2.21.0',
     description='A light weight Python library for the Spotify Web API',
     long_description=long_description,
     long_description_content_type="text/markdown",
     author="@plamere",
     author_email="p...@echonest.com",
     url='https://spotipy.readthedocs.org/',
+    project_urls={
+        'Source': 'https://github.com/plamere/spotipy',
+    },
     install_requires=[
-        'redis>=3.5.3',
-        'requests>=2.25.0',
-        'six>=1.15.0',
-        'urllib3>=1.26.0'
+        "redis>=3.5.3",
+        "redis<4.0.0;python_version<'3.4'",
+        "requests>=2.25.0",
+        "six>=1.15.0",
+        "urllib3>=1.26.0"
     ],
     tests_require=test_reqs,
     extras_require=extra_reqs,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/spotipy/cache_handler.py 
new/spotipy-2.21.0/spotipy/cache_handler.py
--- old/spotipy-2.20.0/spotipy/cache_handler.py 2022-06-18 23:59:37.000000000 
+0200
+++ new/spotipy-2.21.0/spotipy/cache_handler.py 2022-10-27 00:03:42.000000000 
+0200
@@ -2,6 +2,7 @@
     'CacheHandler',
     'CacheFileHandler',
     'DjangoSessionCacheHandler',
+    'FlaskSessionCacheHandler',
     'MemoryCacheHandler',
     'RedisCacheHandler']
 
@@ -146,6 +147,31 @@
         except Exception as e:
             logger.warning("Error saving token to cache: " + str(e))
 
+
+class FlaskSessionCacheHandler(CacheHandler):
+    """
+    A cache handler that stores the token info in the session framework
+    provided by flask.
+    """
+
+    def __init__(self, session):
+        self.session = session
+
+    def get_cached_token(self):
+        token_info = None
+        try:
+            token_info = self.session["token_info"]
+        except KeyError:
+            logger.debug("Token not found in the session")
+
+        return token_info
+
+    def save_token_to_cache(self, token_info):
+        try:
+            self.session["token_info"] = token_info
+        except Exception as e:
+            logger.warning("Error saving token to cache: " + str(e))
+
 
 class RedisCacheHandler(CacheHandler):
     """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/spotipy/client.py 
new/spotipy-2.21.0/spotipy/client.py
--- old/spotipy-2.20.0/spotipy/client.py        2022-06-18 23:59:37.000000000 
+0200
+++ new/spotipy-2.21.0/spotipy/client.py        2022-10-27 00:03:42.000000000 
+0200
@@ -144,7 +144,7 @@
             See urllib3 
https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html
         :param language:
             The language parameter advertises what language the user prefers 
to see.
-            See ISO-639 language code: 
https://www.loc.gov/standards/iso639-2/php/code_list.php
+            See ISO-639-1 language code: 
https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
         """
         self.prefix = "https://api.spotify.com/v1/";
         self._auth = auth
@@ -420,15 +420,19 @@
         trid = self._get_id("artist", artist_id)
         return self._get("artists/" + trid + "/related-artists")
 
-    def album(self, album_id):
+    def album(self, album_id, market=None):
         """ returns a single album given the album's ID, URIs or URL
 
             Parameters:
                 - album_id - the album ID, URI or URL
+                - market - an ISO 3166-1 alpha-2 country code
         """
 
         trid = self._get_id("album", album_id)
-        return self._get("albums/" + trid)
+        if market is not None:
+            return self._get("albums/" + trid + '?market=' + market)
+        else:
+            return self._get("albums/" + trid)
 
     def album_tracks(self, album_id, limit=50, offset=0, market=None):
         """ Get Spotify catalog information about an album's tracks
@@ -446,15 +450,19 @@
             "albums/" + trid + "/tracks/", limit=limit, offset=offset, 
market=market
         )
 
-    def albums(self, albums):
+    def albums(self, albums, market=None):
         """ returns a list of albums given the album IDs, URIs, or URLs
 
             Parameters:
                 - albums - a list of  album IDs, URIs or URLs
+                - market - an ISO 3166-1 alpha-2 country code
         """
 
         tlist = [self._get_id("album", a) for a in albums]
-        return self._get("albums/?ids=" + ",".join(tlist))
+        if market is not None:
+            return self._get("albums/?ids=" + ",".join(tlist) + '&market=' + 
market)
+        else:
+            return self._get("albums/?ids=" + ",".join(tlist))
 
     def show(self, show_id, market=None):
         """ returns a single show given the show's ID, URIs or URL
@@ -680,7 +688,7 @@
         )
 
     def playlist_cover_image(self, playlist_id):
-        """ Get cover of a playlist.
+        """ Get cover image of a playlist.
 
             Parameters:
                 - playlist_id - the playlist ID, URI or URL
@@ -709,7 +717,7 @@
             DeprecationWarning,
         )
 
-        """ Gets playlist of a user
+        """ Gets a single playlist of a user
 
             Parameters:
                 - user - the id of the user
@@ -841,7 +849,7 @@
         return self.playlist_add_items(playlist_id, tracks, position)
 
     def user_playlist_replace_tracks(self, user, playlist_id, tracks):
-        """ Replace all tracks in a playlist
+        """ Replace all tracks in a playlist for a user
 
             Parameters:
                 - user - the id of the user
@@ -863,7 +871,7 @@
         range_length=1,
         snapshot_id=None,
     ):
-        """ Reorder tracks in a playlist
+        """ Reorder tracks in a playlist from a user
 
             Parameters:
                 - user - the id of the user
@@ -982,7 +990,8 @@
         collaborative=None,
         description=None,
     ):
-        """ Changes a playlist's name and/or public/private state
+        """ Changes a playlist's name and/or public/private state,
+            collaborative state, and/or description
 
             Parameters:
                 - playlist_id - the id of the playlist
@@ -1082,7 +1091,7 @@
     def playlist_remove_all_occurrences_of_items(
         self, playlist_id, items, snapshot_id=None
     ):
-        """ Removes all occurrences of the given tracks from the given playlist
+        """ Removes all occurrences of the given tracks/episodes from the 
given playlist
 
             Parameters:
                 - playlist_id - the id of the playlist
@@ -1385,7 +1394,7 @@
         )
 
     def current_user_following_users(self, ids=None):
-        """ Check if the current user is following certain artists
+        """ Check if the current user is following certain users
 
             Returns list of booleans respective to ids
 
@@ -1483,8 +1492,8 @@
 
             Parameters:
                 - locale - The desired language, consisting of a lowercase ISO
-                  639 language code and an uppercase ISO 3166-1 alpha-2 country
-                  code, joined by an underscore.
+                  639-1 alpha-2 language code and an uppercase ISO 3166-1 
alpha-2
+                  country code, joined by an underscore.
 
                 - country - An ISO 3166-1 alpha-2 country code.
 
@@ -1533,7 +1542,7 @@
                 - category_id - The Spotify category ID for the category.
 
                 - country - An ISO 3166-1 alpha-2 country code.
-                - locale - The desired language, consisting of an ISO 639
+                - locale - The desired language, consisting of an ISO 639-1 
alpha-2
                   language code and an ISO 3166-1 alpha-2 country code, joined
                   by an underscore.
         """
@@ -1548,7 +1557,7 @@
 
             Parameters:
                 - country - An ISO 3166-1 alpha-2 country code.
-                - locale - The desired language, consisting of an ISO 639
+                - locale - The desired language, consisting of an ISO 639-1 
alpha-2
                   language code and an ISO 3166-1 alpha-2 country code, joined
                   by an underscore.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotipy-2.20.0/spotipy/oauth2.py 
new/spotipy-2.21.0/spotipy/oauth2.py
--- old/spotipy-2.20.0/spotipy/oauth2.py        2022-06-18 23:59:37.000000000 
+0200
+++ new/spotipy-2.21.0/spotipy/oauth2.py        2022-10-27 00:03:42.000000000 
+0200
@@ -140,7 +140,7 @@
             # then try do decode it into text
 
             # if we receive an empty string (which is falsy), then replace it 
with `None`
-            error = response.txt or None
+            error = response.text or None
             error_description = None
 
         raise SpotifyOauthError(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spotipy-2.20.0/tests/integration/test_non_user_endpoints.py 
new/spotipy-2.21.0/tests/integration/test_non_user_endpoints.py
--- old/spotipy-2.20.0/tests/integration/test_non_user_endpoints.py     
2022-06-18 23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/tests/integration/test_non_user_endpoints.py     
2022-10-27 00:03:42.000000000 +0200
@@ -63,13 +63,13 @@
 
     def test_audio_analysis(self):
         result = self.spotify.audio_analysis(self.four_tracks[0])
-        assert('beats' in result)
+        assert ('beats' in result)
 
     def test_audio_features(self):
         results = self.spotify.audio_features(self.four_tracks)
         self.assertTrue(len(results) == len(self.four_tracks))
         for track in results:
-            assert('speechiness' in track)
+            assert ('speechiness' in track)
 
     def test_audio_features_with_bad_track(self):
         bad_tracks = ['spotify:track:bad']
@@ -78,7 +78,7 @@
         self.assertTrue(len(results) == len(input))
         for track in results[:-1]:
             if track is not None:
-                assert('speechiness' in track)
+                assert ('speechiness' in track)
         self.assertTrue(results[-1] is None)
 
     def test_recommendations(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spotipy-2.20.0/tests/integration/test_user_endpoints.py 
new/spotipy-2.21.0/tests/integration/test_user_endpoints.py
--- old/spotipy-2.20.0/tests/integration/test_user_endpoints.py 2022-06-18 
23:59:37.000000000 +0200
+++ new/spotipy-2.21.0/tests/integration/test_user_endpoints.py 2022-10-27 
00:03:42.000000000 +0200
@@ -359,6 +359,22 @@
         response = self.spotify.categories()
         self.assertGreater(len(response['categories']), 0)
 
+    def test_categories_country(self):
+        response = self.spotify.categories(country='US')
+        self.assertGreater(len(response['categories']), 0)
+
+    def test_categories_locale(self):
+        response = self.spotify.categories(locale='en_US')
+        self.assertGreater(len(response['categories']), 0)
+
+    def test_categories_limit_low(self):
+        response = self.spotify.categories(limit=1)
+        self.assertEqual(len(response['categories']), 1)
+
+    def test_categories_limit_high(self):
+        response = self.spotify.categories(limit=50)
+        self.assertLessEqual(len(response['categories']), 50)
+
     def test_category_playlists(self):
         response = self.spotify.categories()
         category = 'rock'
@@ -368,6 +384,24 @@
                 response = self.spotify.category_playlists(category_id=cat_id)
                 self.assertGreater(len(response['playlists']["items"]), 0)
 
+    def test_category_playlists_limit_low(self):
+        response = self.spotify.categories()
+        category = 'rock'
+        for cat in response['categories']['items']:
+            cat_id = cat['id']
+            if cat_id == category:
+                response = self.spotify.category_playlists(category_id=cat_id, 
limit=1)
+                self.assertEqual(len(response['categories']['items']), 1)
+
+    def test_category_playlists_limit_high(self):
+        response = self.spotify.categories()
+        category = 'rock'
+        for cat in response['categories']['items']:
+            cat_id = cat['id']
+            if cat_id == category:
+                response = self.spotify.category_playlists(category_id=cat_id, 
limit=50)
+                self.assertLessEqual(len(response['categories']['items']), 50)
+
     def test_new_releases(self):
         response = self.spotify.new_releases()
         self.assertGreater(len(response['albums']), 0)

Reply via email to