sybrenstuvel / flickrapi

Python Flickr API implementation
https://stuvel.eu/flickrapi
Other
155 stars 33 forks source link

`token_valid()` will always fail (and bin your token in the process) #123

Open optilude opened 5 years ago

optilude commented 5 years ago

I followed the "out-of-band" example for getting a token:

import flickrapi
import webbrowser

api_key = u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
api_secret = u'YYYYYYYYYYYYYYYY'

flickr = flickrapi.FlickrAPI(api_key, api_secret)

if not flickr.token_valid(perms='read'):
    flickr.get_request_token(oauth_callback='oob')
    authorize_url = flickr.auth_url(perms='read')

    # ...

    verifier = str(input('Verifier code: '))
    flickr.get_access_token(verifier)
resp = flickr.photos.getInfo(photo_id='7658567128')

I then noticed that this requires a new authorization every time, i.e. flickr.token_valid() always returned false. Moreover, I found that after this function call, the token was erased from the sqlite database.

I believe the problem is this line:

https://github.com/sybrenstuvel/flickrapi/blob/a4a9670dfbafcd0fad8044c363e5ff1780269253/flickrapi/core.py#L564

This uses this API call, presumably: https://www.flickr.com/services/api/flickr.auth.oauth.checkToken.html

However, that takes two arguments: api_key and oauth_token, neither of which appears to be passed. It therefore fails each time with status code 200 and body:

<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="fail">
        <err code="98" msg="Invalid token" />
</rsp>

Annoyingly, the token_valid() call then deletes your cached token as well.

optilude commented 5 years ago

That said, I just tried to hack that code and put oauth_token=token.token into the call signature and it fails with a 401, so I may be wrong. But it definitely always gets an "invalid token" fail.

oPromessa commented 5 years ago

Hi @optilude In case it helps I have this small gist with the piece of code required for login into flickr just in case you want to test it out to compare: flickrapi login example

optilude commented 5 years ago

I am not sure what the deal is with flickr.auth.oauth.checkToken(), but I have some slightly different code that seems more robust, using flickr.test.login() instead:

        flickr_api = flickrapi.FlickrAPI(FLICKR_API_KEY, FLICKR_API_SECRET)

        # Make sure the token is still valid if we have one
        if flickr_api.token_cache.token:
            try:
                flickr_api.test.login()
            except flickrapi.exceptions.FlickrError:
                flickr_api.flickr_oauth.token = None
                del flickr_api.token_cache.token

        # Get a new token via the user if we don't have one
        if not flickr_api.token_cache.token:
            flickr_api.get_request_token(oauth_callback='oob')
            authorize_url = flickr_api.auth_url(perms='read')

            print("No token found. You must visit this URL and get the verifier code: %s" % authorize_url)
            verifier = input('Enter code: ')
            flickr_api.get_access_token(verifier)