Handling multiple connections in Flask API

I am writing a simple internal REST API for our solution using Flask, serving JSON objects through calls (including authentication). We have several backends for fetching data. From what I understand, they should be associated with a function decorated @app.before_request

and assigned globally g

for use in the specific requested route. This is not a template that I am used to.

Here's an example of a game I'm making:

@app.before_request
def before_request():
    g.some_conn_a = create_connection('a')
    g.some_conn_b = create_connection('b')
    g.some_client = create_client()


@app.route('/get_some_data')
@requires_auth
def get_some_data():
    # Fetch something from all connections in g
    payload = ... # Construct payload using above connections
    return jsonify(payload)


@app.route('/get_some_other_data')
@requires_auth
def get_some_other_data():
    # Fetch something from maybe just g.some_conn_b
    payload = ... # Construct payload using g.some_conn_b
    return jsonify(payload)

      

It seems wasteful to me if the user makes a request for data that is only in one or two of these connections / clients, such as in the example route get_some_other_data

.

I am considering just making connections / clients in route functions or loading them lazily. What's the "correct" way? I hope this is not a new module that seems extreme for what I am doing.

+3


source to share


1 answer


Riffing on example checkbox docs Database Connections you can modify get_db () to accept an argument for each of your multiple connections.

def get_db(conn):
    """Open specificied connection if none yet for the current app context. """
    if conn == 'some_conn_a':
        if not hasattr(g, 'some_conn_a'):
            g.some_conn_a = create_connection('a')
        db = g.some_conn_a
    elif conn == 'some_conn_b':
        if not hasattr(g, 'some_conn_b'):
            g.some_conn_b = create_connection('b')
        db = g.some_conn_b 
    elif conn == 'some_client':
        if not hasattr(g, 'some_client'):
            g.some_client = create_client()
        db = g.some_client
    else:
        raise Exception("Unknown connection: %s" % conn)

    return db

@app.teardown_appcontext
def close_db(error):
    """Closes the db connections. """
    if hasattr(g, 'some_conn_a'):
        g.some_conn_a.close()
    if hasattr(g, 'some_conn_b'):
        g.some_conn_b.close()
    if hasattr(g, 'some_client'):
        g.some_client.close()

      

Then you can query each connection as needed:



@app.route('/get_some_data')
def get_some_data():
    data_a = get_db('some_conn_a').query().something()
    data_b = get_db('some_conn_b').query().something()
    data_c = get_db('some_client').query().something()
    payload = {'a': data_a, 'b': data_b, 'c': data_c}
    return jsonify(payload)

      

The get_db () pattern is preferred over the before_request pattern for lazy connections to the download database. The sample docs for Flask 0.11 and up use the get_db () pattern to a greater extent.

+1


source







All Articles