moogar0880 / PyTrakt

A Pythonic interface to the Trakt.tv REST API
Other
65 stars 51 forks source link

Trouble with User API #134

Open pedrojvaz opened 3 years ago

pedrojvaz commented 3 years ago

Description

When I use the User API's, I get an error requesting OAuth.

I'm trying to use your module to play with my data on trakt.tv and while I can use use the People, Television and Movies API's, it fails with the User one, with the message: trakt.errors.OAuthException: Unauthorized - OAuth must be provided

Steps

>>> import trakt
>>> import trakt.core
>>> trakt.AUTH_METHOD = trakt.OAUTH_AUTH
>>> trakt.init('myuser')
If you do not have a client ID and secret. Please visit the following url to create them.
http://trakt.tv/oauth/applications
Please enter your client id: d24.....
Please enter your client secret: f8fc....
Please enter your application ID (None): 7XXXX
>>> from trakt.tv import TVShow
>>> it_crowd = TVShow('The IT Crowd')
>>> it_crowd.people
[<Person>: Chris O'Dowd, <Person>: Richard Ayoade, <Person>: Katherine Parkinson, <Person>: Matt Berry, <Person>: Derrin Schlesinger, <Person>: Richard Boden, <Person>: Ash Atalla, <Person>: Jamie Glazebrook, <Person>: Graham Linehan, <Person>: Graham Linehan, <Person>: Graham Linehan]
>>> from trakt.users import User
>>> my = User('muser')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/PyTrakt/trakt/users.py", line 222, in __init__
    self._get()
  File "/opt/PyTrakt/trakt/core.py", line 539, in inner
    json_data = self._handle_request('get', url)
  File "/opt/PyTrakt/trakt/core.py", line 516, in _handle_request
    raise self.error_map[response.status_code]()
trakt.errors.OAuthException: Unauthorized - OAuth must be provided

Am i not supposed to be already authenticated?

Thanks

moogar0880 commented 3 years ago

My hunch is that either something about the credentials is invalid and can't access that user or something has changed with how trakt is expecting client auth to work.

I'd suggest taking a crack at using this flow for authenticating as it's slightly newer, which may help:

>>> from trakt import init
>>> init('myusername', client_id=my_client_id, client_secret=my_client_secret)

There could be some nuggets that may be useful in the docs as well, but as @p0psicles and I were just discussing in #132 the docs have fallen a little behind so your mileage may vary there.

@p0psicles have you run into any issues related to the oauth workflow in PyTrakt?

p0psicles commented 3 years ago

I used device auth myself. But I did see some weird quirk. Where.. trakt.AUTH_METHOD = trakt.OAUTH_AUTH was not working.

But trakt.AUTH_METHOD = trakt.core.OAUTH_AUTH was. Or something like that. I can checkout tomorrow to be sure

pedrojvaz commented 3 years ago

My hunch is that either something about the credentials is invalid and can't access that user or something has changed with how trakt is expecting client auth to work.

I'd suggest taking a crack at using this flow for authenticating as it's slightly newer, which may help:

>>> from trakt import init
>>> init('myusername', client_id=my_client_id, client_secret=my_client_secret)

hmm... i'm getting a new error?

>>> from trakt import init
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'init' from 'trakt' (/home/XXXXXXXX/.local/lib/python3.8/site-packages/trakt/__init__.py)

@p0psicles, and on your recommendation, I also get an error:

trakt.AUTH_METHOD = trakt.core.OAUTH_AUTH
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'trakt.core' has no attribute 'OAUTH_AUTH'

It doesn't help that I'm new to python....

p0psicles commented 3 years ago

This is what I did. And that works for me.

import trakt
trakt.AUTH_METHOD = trakt.OAUTH_AUTH
trakt.init('username')
If you do not have a client ID and secret. Please visit the following url to create them.
http://trakt.tv/oauth/applications
Please enter your client id: my_client_id
Please enter your client secret: my_client_secret
Please enter your application ID (None): (leave empty)

from trakt.tv import TVShow
TVShow('The IT Crowd')
<TVShow> The IT Crowd
it = TVShow('The IT Crowd')
it.people
[<Person>: Chris O'Dowd, <Person>: Richard Ayoade, <Person>: Katherine Parkinson, <Person>: Matt Berry, <Person>: Derrin Schlesinger, <Person>: Richard Boden, <Person>: Ash Atalla, <Person>: Jamie Glazebrook, <Person>: Graham Linehan, <Person>: Graham Linehan, <Person>: Graham Linehan]
pedrojvaz commented 3 years ago

Indeed, this works, but not when I try to access the data of my user

[...]
>>> TVShow('The IT Crowd')
<TVShow> The IT Crowd
>>> it = TVShow('The IT Crowd')
>>> it.people
[<Person>: Chris O'Dowd, <Person>: Richard Ayoade, <Person>: Katherine Parkinson, <Person>: Matt Berry, <Person>: Derrin Schlesinger, <Person>: Richard Boden, <Person>: Ash Atalla, <Person>: Jamie Glazebrook, <Person>: Graham Linehan, <Person>: Graham Linehan, <Person>: Graham Linehan]
>>> from trakt.users import User
>>> my = User('username')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/trakt-2.14.1-py3.8.egg/trakt/users.py", line 222, in __init__
    self._get()
  File "/usr/local/lib/python3.8/dist-packages/trakt-2.14.1-py3.8.egg/trakt/core.py", line 539, in inner
    json_data = self._handle_request('get', url)
  File "/usr/local/lib/python3.8/dist-packages/trakt-2.14.1-py3.8.egg/trakt/core.py", line 516, in _handle_request
    raise self.error_map[response.status_code]()
trakt.errors.OAuthException: Unauthorized - OAuth must be provided
>>>

Does it work for you? Or am I using the API incorrectly?

p0psicles commented 3 years ago

Yes i get the same error. Which is weird. As I use device auth myself in my app. And that does work. I'll see if I can get to the root cause tomorrow

p0psicles commented 3 years ago

The issue is this. You can't do this:

import trakt
trakt.AUTH_METHOD = trakt.OAUTH_AUTH

As that will only set the AUTH_METHOD imported in init.py. But not that in trakt/core.py

This will work:

import trakt
trakt.core.AUTH_METHOD = trakt.OAUTH_AUTH

@moogar0880 We could add this method in core.py.

def set_auth(auth_method):
    global AUTH_METHOD
    AUTH_METHOD = auth_method

Which would allow users to just call it like:

import trakt
trakt.set_auth(trakt.OAUTH_AUTH)
p0psicles commented 3 years ago

@pedrojvaz btw you will get into the same issue when you try to set the .pytrakt.json location. Like this will not work: trakt.CONFIG_PATH = os.path.join(my_cache_location, '.pytrakt.json') but this will: trakt.core.CONFIG_PATH = os.path.join(my_cache_location, '.pytrakt.json')

moogar0880 commented 3 years ago

We could add this method in core.py.

def set_auth(auth_method):
    global AUTH_METHOD
    AUTH_METHOD = auth_method

That looks reasonable to me 👍

To your point about similar trickery being needed for setting the config path, do you think it would make sense to add setters for all of those config globals while we're at it?

p0psicles commented 3 years ago

Tbh. For me, as long as it's properly documented, using trakt.core.GLOBAL = ..., is also fine with me. Think it's more about what speaks to you?

pedrojvaz commented 3 years ago

Sorry, so what are the next steps? A new version will be released or should I adjust something the way I used the module?

p0psicles commented 3 years ago

For the current version you have a workaround. Rest is up to @moogar0880