ppxy
@ppxy

Синглтон для flask?

Добрый день. Пишу веб-приложение для работы с api dropbox, но опыта мало в таких делах, поэтому такая проблема.
Для доступа нужно получить токен и после этого можно создавать клиента для dropbox. Пока делаю вот таким образом:
@app.route('/')
def index():
    if 'access_token' in session:
        client = dropbox.Dropbox(session['access_token'])
        return render_template('index.html', user_info=client.users_get_current_account())
    else:
        return render_template('index.html', dropbox_login_url=get_dropbox_auth_flow(session).start())

Напрягает то, что на данный момент я постоянно создаю client для обращения к api. Хочется какого то аналога синглтона. Как сделать?
  • Вопрос задан
  • 557 просмотров
Пригласить эксперта
Ответы на вопрос 2
@bromzh
Drugs-driven development
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, смотри новое АПИ тут.
Ответ написан
EvilsInterrupt
@EvilsInterrupt
System programming, Reversing Engineering, C++
Возможно Вам поможет объект сессия ? sessions
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы