Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

warning:couldn't write token cache to .cache- #870

Open
F-Wer opened this issue Oct 12, 2022 · 8 comments
Open

warning:couldn't write token cache to .cache- #870

F-Wer opened this issue Oct 12, 2022 · 8 comments
Labels

Comments

@F-Wer
Copy link

F-Wer commented Oct 12, 2022

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

@F-Wer F-Wer added the bug label Oct 12, 2022
@Peter-Schorn
Copy link
Contributor

Peter-Schorn commented 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

@SergiuPogor
Copy link

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')

@rebecca-riley
Copy link

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.

@Peter-Schorn
Copy link
Contributor

Peter-Schorn commented 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.

@rebecca-riley
Copy link

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.)

@rebecca-riley
Copy link

@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.

@Peter-Schorn
Copy link
Contributor

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

@rebecca-riley
Copy link

Sure thing, I'll add one soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants