P
P
ppxy2016-01-25 22:58:23
Flask
ppxy, 2016-01-25 22:58:23

Singleton for flask?

Good afternoon. I am writing a web application to work with the dropbox api, but there is little experience in such matters, so this is a problem.
For access, you need to get a token and after that you can create a client for dropbox. For now, I'm doing it this way:

@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())

It's annoying that at the moment I am constantly creating a client to access the api. I want some analogue of a singleton. How to do?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
B
bromzh, 2016-01-26
@bromzh

1) You can write a Flask extension, it's very easy. There is already something for dropbox , but I don’t know how efficient it is (the last commit was in 2013). This will probably be the best solution
2) Write a decorator (I took the tutorial as a basis ) :

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'

In this case, the client is stored in the global object g.
Most likely, the best option (from the point of view of threadsafe) is not to store the client in a global object, but to insert it into the function as a parameter using a decorator:
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) # это тоже можно вынести в декоратор
    ...

Well, move all the logic from the view-functions to the service layer.
PS Dropbox API with DropboxClient is now Deprecated, see the new API here .

D
Dmitry, 2016-01-26
@EvilsInterrupt

Perhaps the session object will help you? sessions

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question