我正在连接几个API(例如Twitter、GitHub等)。使用Flask-oauthlib。目前,我把每项服务都作为一个单独的蓝图。在每个服务的视图文件中,都有相同的三个视图:login、authorized和get_token。现在的代码不是很枯燥,但我很难理解如何集中这些视图(更多的概念)。
,我怎么才能把这个弄干呢?我希望从概念上更好地理解,而不是真正为我编写代码。
下面是一些可能有帮助的项目。这是应用程序结构:
- App
- Services
- FourSquare BP
- GitHub BP
- Twitter BP
- ...
- Other BPs泛型API视图可能在Services/api_views.py下。
下面是一个API Blueprint视图文件(Twitter)的示例。
twitter = Blueprint('twitter', __name__, url_prefix='/twitter')
bp = twitter
bp.api = TwitterAPI()
bp.oauth = bp.api.oauth_app
# Below here is the exact same for each file.
@bp.route('/')
@login_required
def login():
if current_user.get(bp.name, None):
return redirect(url_for('frontend.index'))
return bp.oauth.authorize(callback=url_for('.authorized', _external=True))
@bp.route('/authorized')
@bp.oauth.authorized_handler
def authorized(resp):
if resp is None:
flash(u'You denied the request to sign in.')
return redirect(url_for('frontend.index'))
if bp.oauth_type == 'oauth2':
resp['access_token'] = (resp['access_token'], '')
current_user[bp.name] = resp
current_user.save()
flash('You were signed in to %s' % bp.name.capitalize())
return redirect(url_for('frontend.index'))
@bp.oauth.tokengetter
def get_token(token=None):
if bp.oauth_type == 'oauth2':
return current_user.get(bp.name, None)['access_token']
return current_user.get(bp.name, None)['oauth_token']我试着把视图放在一个类中,然后导入这些视图,但是在不同的装饰器上遇到了麻烦( oauth装饰师给出了最大的麻烦)。
发布于 2013-12-05 01:38:32
我想出了一个解决上述问题的好办法。请让我知道这是否一个好的解决办法。
我决定使用基于烧瓶类的视图。这样我就可以为上面的每个主要API函数创建一个类视图了:
class APILoginView(View):
decorators = [login_required]
def __init__(self, blueprint):
self.blueprint = blueprint
def dispatch_request(self):
if current_user.get(self.blueprint.name, None):
return redirect(url_for('frontend.index'))
return self.blueprint.oauth.authorize(callback=url_for('.authorized', _external=True))
class APIAuthorizedView(View):
decorators = [login_required]
def __init__(self, blueprint):
self.blueprint = blueprint
def dispatch_request(self, resp):
if resp is None:
flash(u'You denied the request to sign in.')
return redirect(url_for('frontend.index'))
if self.blueprint.api.oauth_type == 'oauth2':
resp['access_token'] = (resp['access_token'], '') #need to make it a tuple for oauth2 requests
current_user[self.blueprint.name] = resp
current_user.save()
flash('You were signed in to %s' % self.blueprint.name.capitalize())
return redirect(url_for('frontend.index'))那是比较容易的部分。更棘手的事情是弄清楚如何泛化tokengetter,这是烧瓶OAuthLib库所必需的。以下是我最后得到的结果:
class APIToken():
def __init__(self, blueprint):
self.blueprint = blueprint
def get_token(self, token=None):
if self.blueprint.api.oauth_type == 'oauth2':
return current_user.get(self.blueprint.name, None)['access_token']
return current_user.get(self.blueprint.name, None)['oauth_token']最后,创建一个函数来在蓝图上注册这些视图:
def registerAPIViews(blueprint):
login_view = APILoginView.as_view('login', blueprint=blueprint)
auth_view = blueprint.oauth.authorized_handler(
APIAuthorizedView.as_view('authorized', blueprint=blueprint))
blueprint.add_url_rule('/', view_func=login_view)
blueprint.add_url_rule('/authorized', view_func=auth_view)
apiToken = APIToken(blueprint)
token_getter = blueprint.oauth.tokengetter(apiToken.get_token)
return blueprinthttps://stackoverflow.com/questions/20318812
复制相似问题