[GH-ISSUE #870] warning:couldn't write token cache to .cache- #532

Open
opened 2026-02-27 23:23:11 +03:00 by kerem · 8 comments
Owner

Originally created by @F-Wer on GitHub (Oct 12, 2022).
Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/870

Describe the bug
I try to run spotipy via a scheduled job on Windows 10.

Therefore I created a .bat file that calls the script.
When I run the script normally it works, but if I try to run it via a job or via the .bat file I get a popup of the command prompt with a url I have to go and insert the url I got redirected to.
Afterwars I get the error

Couldn't write token to cache at: .cache-XXXXXX

.bat file

"C:\Users\F\AppData\Local\Programs\Python\Spotify_Playlist_followed_artists\Scripts\python.exe" -i "C:\Users\F\PycharmProjects\Spotify_Playlist_followed_artists\main.py"
pause

In my Script it throws the error in my method where I initialize Spotipy:

def get_env():
    load_dotenv()
    SPOTIPY_CLIENT_ID = os.environ.get("SPOTIPY_CLIENT_ID")
    SPOTIPY_CLIENT_SECRET = os.environ.get("SPOTIPY_CLIENT_SECRET")
    SPOTIPY_REDIRECT_URI = os.environ.get("SPOTIPY_REDIRECT_URI")
    SPOTIPY_USER_ID = os.environ.get("SPOTIPY_USER_ID")
    scope = "user-follow-read,playlist-modify-private,playlist-modify-public"
    client_credentials_manager = spotipy.oauth2.SpotifyOAuth(
        scope=scope,
        username=SPOTIPY_USER_ID,
        client_id=SPOTIPY_CLIENT_ID,
        client_secret=SPOTIPY_CLIENT_SECRET,
        redirect_uri=SPOTIPY_REDIRECT_URI,
        open_browser=False)
    SP = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

Expected behavior
I expect to enter the return url and that the .cache file could be written to.

Output
Go to the following URL: https://accounts.spotify.com/authorize?client_id=XXXXX&response_type=code&redirect_uri=http%3A%2F%XXXXX%3A8080&scope=playlist-modify-private+playlist-modify-public+user-follow-read
Enter the URL you were redirected to: http://XXXXXX/?code=XXXX-YYYY-ZZZZ-DDDD-WWWW
Couldn't write token to cache at: .cache-XXXXXX

Environment:

  • OS: Windows
  • Python version 3.10
  • spotipy version 2.20.0
  • your IDE PyCharm

Additional context
I know that there is already an issue #363 , but the workarounds in there didn't work for me

Originally created by @F-Wer on GitHub (Oct 12, 2022). Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/870 **Describe the bug** I try to run spotipy via a scheduled job on Windows 10. Therefore I created a .bat file that calls the script. When I run the script normally it works, but if I try to run it via a job or via the .bat file I get a popup of the command prompt with a url I have to go and insert the url I got redirected to. Afterwars I get the error Couldn't write token to cache at: .cache-XXXXXX .bat file ```bat "C:\Users\F\AppData\Local\Programs\Python\Spotify_Playlist_followed_artists\Scripts\python.exe" -i "C:\Users\F\PycharmProjects\Spotify_Playlist_followed_artists\main.py" pause ``` In my Script it throws the error in my method where I initialize Spotipy: ```python def get_env(): load_dotenv() SPOTIPY_CLIENT_ID = os.environ.get("SPOTIPY_CLIENT_ID") SPOTIPY_CLIENT_SECRET = os.environ.get("SPOTIPY_CLIENT_SECRET") SPOTIPY_REDIRECT_URI = os.environ.get("SPOTIPY_REDIRECT_URI") SPOTIPY_USER_ID = os.environ.get("SPOTIPY_USER_ID") scope = "user-follow-read,playlist-modify-private,playlist-modify-public" client_credentials_manager = spotipy.oauth2.SpotifyOAuth( scope=scope, username=SPOTIPY_USER_ID, client_id=SPOTIPY_CLIENT_ID, client_secret=SPOTIPY_CLIENT_SECRET, redirect_uri=SPOTIPY_REDIRECT_URI, open_browser=False) SP = spotipy.Spotify(client_credentials_manager=client_credentials_manager) ``` **Expected behavior** I expect to enter the return url and that the .cache file could be written to. **Output** Go to the following URL: https://accounts.spotify.com/authorize?client_id=XXXXX&response_type=code&redirect_uri=http%3A%2F%XXXXX%3A8080&scope=playlist-modify-private+playlist-modify-public+user-follow-read Enter the URL you were redirected to: http://XXXXXX/?code=XXXX-YYYY-ZZZZ-DDDD-WWWW Couldn't write token to cache at: .cache-XXXXXX **Environment:** - OS: Windows - Python version 3.10 - spotipy version 2.20.0 - your IDE PyCharm **Additional context** I know that there is already an issue #363 , but the workarounds in there didn't work for me
Author
Owner

@Peter-Schorn commented on GitHub (Oct 12, 2022):

Given that the script works when run directly, but not when run from the .bat file, this sounds like a permissions issue, just like in #363. You should modify this method to print the error received for more information.
github.com/plamere/spotipy@be27391461/spotipy/cache_handler.py (L88-L95)

<!-- gh-comment-id:1276771188 --> @Peter-Schorn commented on GitHub (Oct 12, 2022): Given that the script works when run directly, but not when run from the `.bat` file, this sounds like a permissions issue, just like in #363. You should modify this method to print the error received for more information. https://github.com/plamere/spotipy/blob/be2739146138a0d5717967cc62927c15ecc9a7c3/spotipy/cache_handler.py#L88-L95
Author
Owner

@SergiuPogor commented on GitHub (Oct 15, 2022):

I was getting a similar error on Linux, after enable logging the error detail I got this one:
[Errno 21] Is a directory: '.cache'
So, in my case, the script was looking for the file in "/.cache"
I've fixed the issue just by adding absolute file path cache_path=PROJECT_PATH + '/.cache'

sp = SpotifyOAuth(client_id=config.SPOTIFY_APP_CLIENT_ID, client_secret=config.SPOTIFY_APP_CLIENT_SECRET, redirect_uri=config.SPOTIFY_APP_REDIRECT_URL, cache_path=PROJECT_PATH + '/.cache')

<!-- gh-comment-id:1279698107 --> @SergiuPogor commented on GitHub (Oct 15, 2022): I was getting a similar error on Linux, after enable logging the error detail I got this one: `[Errno 21] Is a directory: '.cache'` So, in my case, the script was looking for the file in **"/.cache"** I've fixed the issue just by adding absolute file path **cache_path=PROJECT_PATH + '/.cache'** `sp = SpotifyOAuth(client_id=config.SPOTIFY_APP_CLIENT_ID, client_secret=config.SPOTIFY_APP_CLIENT_SECRET, redirect_uri=config.SPOTIFY_APP_REDIRECT_URL, cache_path=PROJECT_PATH + '/.cache') `
Author
Owner

@rebecca-riley commented on GitHub (Oct 15, 2022):

Same issue, same error. When I run my script on the command prompt directly, it works fine. When I use the Windows launcher, "couldn't write token to cache at: .cache-username." Error is originating from call spotipy.Spotify(auth=token), where token is similar to client_credentials_manager above.

Modified the save_token_to_cache as suggested by @Peter-Schorn and it does appear to be a permissions issue:
[Errno 13] Permission denied: '.cache-username'

I'll report back if I find a fix.

p.s. I also tried the fixes suggested on #363 -- including Windows Defender whitelisting, interactive mode, and changing cache_path -- with no success. I think it's important to note that the dotfiles themselves aren't inherently problematic. They are created and utilized just fine on direct execution. It's the execution method that seems to be the source of the problem.

Also of note: I initially built/tested this script on Linux and am now modifying for Windows compatibility. I never had this problem on Linux.

<!-- gh-comment-id:1279847286 --> @rebecca-riley commented on GitHub (Oct 15, 2022): Same issue, same error. When I run my script on the command prompt directly, it works fine. When I use the Windows launcher, "couldn't write token to cache at: .cache-username." Error is originating from call `spotipy.Spotify(auth=token)`, where `token` is similar to `client_credentials_manager` above. Modified the `save_token_to_cache` as suggested by @Peter-Schorn and it does appear to be a permissions issue: `[Errno 13] Permission denied: '.cache-username'` I'll report back if I find a fix. p.s. I also tried the fixes suggested on #363 -- including Windows Defender whitelisting, interactive mode, and changing cache_path -- with no success. I think it's important to note that the dotfiles themselves aren't inherently problematic. They are created and utilized just fine on direct execution. It's the execution method that seems to be the source of the problem. Also of note: I initially built/tested this script on Linux and am now modifying for Windows compatibility. I never had this problem on Linux.
Author
Owner

@Peter-Schorn commented on GitHub (Oct 16, 2022):

It's the execution method that seems to be the source of the problem.

How do you suggest we change it? The parent process needs to have write permission to the cache path. spotipy can't change that requirement. You must invoke the script with the proper permissions.

<!-- gh-comment-id:1279861163 --> @Peter-Schorn commented on GitHub (Oct 16, 2022): > It's the execution method that seems to be the source of the problem. How do you suggest we change it? The parent process needs to have write permission to the cache path. spotipy can't change that requirement. You must invoke the script with the proper permissions.
Author
Owner

@rebecca-riley commented on GitHub (Oct 17, 2022):

Source of the problem

The permissions issue is arising when using the launcher because cache_handler.py by default attempts to create a file in the current directory, i.e. the launcher directory, but it is protected in Windows (e.g. C:\WINDOWS\system32 in my case). This can be fixed by specifying a full cache_path in the authorization call; see below. (Note that this is not the cache_path fix suggested in #363, which just amounted to removing the dot.)

When executing a script directly from Windows command prompt, this will always (?) be done from a directory with read-write permissions, so no error.

Minimal example

import os
import errno

def main():
    print('Program started.')
    print('Current directory: ' + os.getcwd())

    try:
        # f = open(".cache-test", "w")  # problem line -- no error with direct execution in command prompt, error when using launcher
        # f = open(str(os.path.dirname(os.path.abspath(__file__))) + '\\' + '.cache-test', "w")  # solution line -- works with both direct execution and launcher
        f.write('test')
        f.close()
        print('Success.')
    except IOError as e:
        print(e)

    input('Press enter to exit.')

if __name__ == '__main__':
    main()

Uncommenting the problem line produces the error in question: [Errno 13] Permission denied: '.cache-test' when using the launcher. Uncommenting the solution line successfully writes .cache-test to the directory containing the test script. Both lines work on direct execution.

Solution using Spotipy

token = spotipy.util.prompt_for_user_token(username,scope,
 client_id=id,
 client_secret=secret,
 redirect_uri='http://localhost:8888/callback',
 cache_path=str(os.path.dirname(os.path.abspath(__file__))) + '\\' + '.cache-' + username)

spotify = spotipy.Spotify(auth=token)

Specifying a full cache_path to a writeable directory (in this case, the directory in which the script is located) resolves the issue. This fix must also be included anywhere else a file is opened in the script. (Otherwise you will get the same permission error with each open() call.)

<!-- gh-comment-id:1280148107 --> @rebecca-riley commented on GitHub (Oct 17, 2022): ### Source of the problem The permissions issue is arising when using the launcher because cache_handler.py by default attempts to create a file in the current directory, i.e. the launcher directory, but it is protected in Windows (e.g. C:\WINDOWS\system32 in my case). This can be fixed by specifying a full cache_path in the authorization call; see below. (Note that this is not the cache_path fix suggested in #363, which just amounted to removing the dot.) When executing a script directly from Windows command prompt, this will always (?) be done from a directory with read-write permissions, so no error. **Minimal example** ``` import os import errno def main(): print('Program started.') print('Current directory: ' + os.getcwd()) try: # f = open(".cache-test", "w") # problem line -- no error with direct execution in command prompt, error when using launcher # f = open(str(os.path.dirname(os.path.abspath(__file__))) + '\\' + '.cache-test', "w") # solution line -- works with both direct execution and launcher f.write('test') f.close() print('Success.') except IOError as e: print(e) input('Press enter to exit.') if __name__ == '__main__': main() ``` Uncommenting the problem line produces the error in question: `[Errno 13] Permission denied: '.cache-test'` when using the launcher. Uncommenting the solution line successfully writes .cache-test to the directory containing the test script. Both lines work on direct execution. ### Solution using Spotipy ``` token = spotipy.util.prompt_for_user_token(username,scope, client_id=id, client_secret=secret, redirect_uri='http://localhost:8888/callback', cache_path=str(os.path.dirname(os.path.abspath(__file__))) + '\\' + '.cache-' + username) spotify = spotipy.Spotify(auth=token) ``` Specifying a full cache_path to a writeable directory (in this case, the directory in which the script is located) resolves the issue. This fix must also be included anywhere else a file is opened in the script. (Otherwise you will get the same permission error with each open() call.)
Author
Owner

@rebecca-riley commented on GitHub (Oct 17, 2022):

@Peter-Schorn I agree with you -- this is a user/permissions issue, not actually a Spotipy issue. I don't think a change is necessary. It would be clunky and out of keeping with the rest of Spotipy and would probably lead to more unexpected behavior than helpful behavior.

The error is very specific. Hopefully this solution has enough keywords for people to find it upon Googling their similar problem.

You might consider including a warning about using the Windows Python launcher in the documentation and/or providing a more descriptive error message upon encountering a permissions error. It's not such a strange problem, but it was initially not at all clear that permissions were the reason for the failure.

<!-- gh-comment-id:1280151986 --> @rebecca-riley commented on GitHub (Oct 17, 2022): @Peter-Schorn I agree with you -- this is a user/permissions issue, not actually a Spotipy issue. I don't think a change is necessary. It would be clunky and out of keeping with the rest of Spotipy and would probably lead to more unexpected behavior than helpful behavior. The error is very specific. Hopefully this solution has enough keywords for people to find it upon Googling their similar problem. You might consider including a warning about using the Windows Python launcher in the documentation and/or providing a more descriptive error message upon encountering a permissions error. It's not such a strange problem, but it was initially not at all clear that permissions were the reason for the failure.
Author
Owner

@Peter-Schorn commented on GitHub (Oct 17, 2022):

I agree the error message should be displayed in the log message. I'm sure @stephanebruckert would welcome a PR with that change.

<!-- gh-comment-id:1280373128 --> @Peter-Schorn commented on GitHub (Oct 17, 2022): I agree the error message should be displayed in the log message. I'm sure @stephanebruckert would welcome a PR with that change.
Author
Owner

@rebecca-riley commented on GitHub (Oct 18, 2022):

Sure thing, I'll add one soon.

<!-- gh-comment-id:1282104120 --> @rebecca-riley commented on GitHub (Oct 18, 2022): Sure thing, I'll add one soon.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/spotipy#532
No description provided.