-
Notifications
You must be signed in to change notification settings - Fork 1
Creates stateless OAuth2 Tumblr functions #37
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
Conversation
| from typing import Any, Iterable, Optional | ||
|
|
||
| from pardner.services import BaseTransferService | ||
| from pardner.stateless.tumblr import URLs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might get confusing if stateless/ and services/ are importing form each other, but I think it's fine as long as only services/ is pulling from stateless/ and not vice-versa.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it that makes sense
| :returns: the authorization URL and state, respectively. | ||
| """ | ||
| return generic_construct_authorization_url( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do a lot of these services wouldn't it be clean to use class inheritance to automatically inherit the construct_authorization_url, and then wrap it and call super()... if the method even needs to be overridden?
This is just meant as food for thought, one often wants to do things 3 times before abstracting or generalizing... we might want to see how the data methods interact before rearchictecting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what you're suggesting is more or less how I set things up in the "stateful" model (e.g., BaseTransferService.fetch_token and TumblrTransferService.fetch_token).
Maybe it's not worth creating stateless versions of those methods after all and just use the classes + methods that already exists for the stateless case as well. If we are using classes even in the stateless mode, the work is pretty much already done (see below)! The reason I was hesitant to use classes for the stateless case is that the ___TransferService object would be used just one time to call a method on it. But now that I'm thinking about it, we could reuse that same object after getting back the token to make the transfer requests.
What I propose: revert #34, close this PR, and use the existing classes (BaseTransferService and TumblrTransferService) for the stateless use case. It reduces code duplication and achieves the same thing in a slightly different way as the functions in this PR and #34 .
UX with classes
initiate oauth2
from pardner.services import TumblrTransferService
tumblr = TumblrTransferService('client_id', 'client_secret', 'https://redirect.com', [Vertical.FeedPost])
auth_url, state = tumblr.authorization_url()
# forward user to auth_urlcallback url
from pardner.services import TumblrTransferService
# need to create new instance because the other one is in a completely different scope
tumblr = TumblrTransferService('client_id', 'client_secret', 'https://redirect.com', [Vertical.FeedPost])
token = tumblr.authorization_url(code = '39040239402')UX without classes
initiate oauth2
from pardner.stateless.tumblr import construct_authorization_url
auth_url, state = construct_authorization_url('client_id', 'https://redirect.com', scope = {'base'))
# forward user to auth_urlcallback url
from pardner.stateless.tumblr import fetch_token
token = fetch_token('client_id', 'https://redirect.com', client_secret = 'client_secret', code = '39040239402')There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is very good and I love the thinking - but also I think about continuing it just a little further, and calling the methods to fetch comments, or fetch block list
Editing to pull the tumblr context out of storage since this gets triggered AFTER initial setup... and I realize I might not be thinking enough about what parts of this happen in different segments of the process separated by different triggers and server contexts. We might not want the OAuth setup that gets triggered by the first click of the "donate my data" button, to be the same object that gets triggered when the callback URL receives a go-ahead token.
tumblr = TumblrTransferService(token=TokenStorage.get(username=username))
tumblr.fetch_block_list()
tumblr.fetch_comments(since=timezone.now() - relativedelta(days=1))
tumblr.fetch_user_profile()
vs
TumblrTransferService.fetch_block_list(token, username, etc)
TumblrTransferService.fetch_comments(token, username, since=etc)
TumblrTransferService.fetch_user_profile(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're on the same page about definiting the data-specific methods; what you've laid out is pretty much exactly what I was thinking of doing!
So in addition to defining traditional methods that can be called on instances of the TumblrTransferService class, I'll also define static class methods that do pretty much the same thing but without using any instance attributes. → I don't think this is necessary, it would involve some strange antipatterns (like writing the same method twice: as a classmethod and a normal method).
…e" (#38) Reverts #34 See discussion: #37 (comment)
Closes #33
I think this may be a case where we don't want to re-export these functions in the top-level init file because we'd want to keep the
from pardner.tumblr import construct_authorization_url(in response to #34 (comment)). Either that or we could rename these to include the word "Tumblr", or put them in a dummy class or something!