praw-dev / praw

PRAW, an acronym for "Python Reddit API Wrapper", is a python package that allows for simple access to Reddit's API.
http://praw.readthedocs.io/
BSD 2-Clause "Simplified" License
3.53k stars 462 forks source link

Add ability to instantiate praw with access_token #2012

Closed JaneJeon closed 5 months ago

JaneJeon commented 10 months ago

Describe the solution you'd like

Currently, we can instantiate Reddit instance with the refresh_token, but for when you need to handle potentially multiple users/accounts (such as in a web application), or when you need to run praw stuff in an isolated context (e.g. in a worker as part of a job - we cannot 'persist' the Reddit instance), you necessarily need a new "instance" of Reddit (as a thin layer - Reddit API client) for each request/worker context.

And having to re-instantiate with refresh_token only means we necessarily need to make an extra call in each "context" to get the access token from the Reddit API.

Can we add the ability to instantiate it with access token (and refresh token) as well (so that when access token isn't expired, praw can just use it to make API requests directly without having to make that extra call)?

Thanks.

Describe alternatives you've considered

No response

Additional context

No response

JaneJeon commented 10 months ago

In the same vein, it would be nice to be able to "listen" to refreshing access_token, so I can save them and inject the updated access_token to praw when instantiating later so it doesn't have to exchange refresh_token to get new access_token every single time.

github-actions[bot] commented 9 months ago

This issue is stale because it has been open for 30 days with no activity.

Remove the Stale label or comment or this will be closed in 30 days.

JaneJeon commented 9 months ago

not stale

LilSpazJoekp commented 9 months ago

Could you provide some more insight on why you would want to prevent PRAW from making an extra request to fetch a new access token?

This seems like a niche case that could be accomplished (at a minimum) by subclassing the Authorizer class to accept a predetermined access_token and by overriding a method in the Reddit class:

https://github.com/praw-dev/praw/blob/b9a91797990d1adb2894d68484bcb24af86f6928/praw/reddit.py#L622-L638

Access tokens are only valid for 10 minutes. After that you'll have to fetch a new access token anyway so I'm not really seeing the benefit of saving this info since it is only valid for 10 minutes just to save one request that doesn't count against your rate limit.

JaneJeon commented 9 months ago

Basically I have a use case where there is a need to reduce the amount of requests to be retried in case of failure, and the TL;DR is that I call these APIs from distributed jobs (think Celery, Temporal.io, and the like).

And in those environments, I cannot have a reddit = Praw(...) variable that I can pass around between jobs (they may run across different machines for reliability) which means I do need to reliably instantiate praw whenever these jobs start.

As you say, it'd be the easiest to just throw out the access token and always instantiate with new access token from the refresh token. However, there are several challenges with that in this environment:

  1. the jobs run fairly frequently (every 5 minutes), so jobs could use the previous job's access token (for the account)
  2. the jobs may fail and be retried immediately afterwards, so the retried job could use the failed job's access token for the account (since it was just issued)

And in these cases, it would be useful for access token to be reused, to prevent API calls, to reduce the delay, etc, given how frequently these praw instantiations are expected to happen (and how often we can save on those unneeded access_token exchange).

The idea is that if any instantiation ends up having to fetch a new access token, if we can be notified of it, save the new access token, and then give it to the next instantiation (which happens frequently), we can reduce the amount of token exchanges by half or more.

github-actions[bot] commented 8 months ago

This issue is stale because it has been open for 30 days with no activity.

Remove the Stale label or comment or this will be closed in 30 days.

JaneJeon commented 8 months ago

not stale

bboe commented 7 months ago

Hi @JaneJeon. If you'd like to do the work to expose this functionality we'd be open to it. Generally, however, this is a pretty narrow use case that I don't want to put effort into supporting. You can accomplish manually setting the access token yourself by working with praw and prawcore internals. I'd actually recommend going that route if you haven't already. If you are interested in doing the work we can keep this open, otherwise, we'll close this out.

JaneJeon commented 7 months ago

You can accomplish manually setting the access token yourself by working with praw and prawcore internals

Is there a guideline/some pointers for where I can start with this myself? It would help very much

bboe commented 7 months ago

I don't have the time at the moment to do a deep dive on this approach, however, try following how the authorize method works to set a session's access_token.

https://github.com/praw-dev/praw/blob/master/praw/models/auth.py#L43

JaneJeon commented 7 months ago

No worries. I'll see if I can figure it out - I'm still unsure how exactly to even "instantiate" a praw instance with the internals at the moment 😓

And in the interest of discoverability, rather than closing, I'd recommend converting to a discussion (but I see that you do not have discussions enabled on this repo).

github-actions[bot] commented 6 months ago

This issue is stale because it has been open for 30 days with no activity.

Remove the Stale label or comment or this will be closed in 30 days.

github-actions[bot] commented 5 months ago

This issue was closed because it has been stale for 30 days with no activity.