1) Можешь написать расширение для фласка, это очень просто. Для дропбокса уже есть
что-то, но не знаю на сколько оно работоспособное (последний коммит в 2013 был). Это, наверное, будет самым лучшим решением
2) Напиши декоратор (за основу я взял
оф. тутор):
from functools import wraps
from flask import g, request, redirect, url_for
def dropbox_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not 'access_token' in session:
g.client = None
return redirect(url_for('dropbox_auth_start'))
if g.client is None:
g.client = DropboxClient(access_token)
return f(*args, **kwargs)
return decorated_function
# Usage
@app.route('foo')
@dropbox_required
def foo():
return 'foo'
В данном случае, клиент хранится в глобальном объекте g.
Скорее всего более лучший вариант (с точки зрения threadsafe) - не хранить клиент в глобальном объекте, а с помощью декоратора вставлять в функцию в качестве параметра:
def provide_dropbox_client(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not 'access_token' in session:
return redirect(url_for('dropbox_auth_start'))
client = DropboxClient(session['access_token'])
return f(client, *args, **kwargs)
return decorated_function
@provide_dropbox_client
def foo_service(client, bar, baz=42):
print(client, bar, baz)
manager = DatastoreManager(client) # это тоже можно вынести в декоратор
...
Ну и всю логику вынести из view-функций в сервисный слой.
PS API дропбокса с DropboxClient нынче Deprecated, смотри новое АПИ
тут.