2

I am trying to convert a Flask app to a Quart app to add async module and gain some performance as discussed in this article. For this, I am connecting to a Couchbase bucket using the acouchbase.Bucket object. The problem is quart is slower and it crashes during the load test. Here is the code I am trying:

import asyncio
from quart import Quart, jsonify, g
from quart_openapi import Pint, Resource
import couchbase.experimental
couchbase.experimental.enable()
from acouchbase.bucket import Bucket

app = Pint(__name__, title = 'SomeTitle')

async def get_db():
    """
    Helper function to initialize and retrive the Bucket object if not 
    already present.
    """
    if not hasattr(g, 'cb_bucket'):
        g.cb_bucket = Bucket('couchbase://localhost/bucketname', 'username', 'password')
        await g.cb_bucket.connect()
    return g.cb_bucket

@app.route("/apiname/<string:xId>")
class apiname(Resource):
    async def get(self, xId):  
        cb = await get_db()
        pickle_in = open('mlmodel', 'rb')
        model = pickle.load(pickle_in)
        y_pred_proba = model.predict_proba(Member).tolist()
    return jsonify(y_pred_proba)

if __name__ == '__main__':  
app.run(port = 5000, debug = True)

App compiles without a problem though during the load test it performs bad and crashes after a while. A very similar flask app (with out any async module) is faster than the quart app but you would expect quart with async module to be faster than the flask app:

Flask equivalent looks like this:

from flask import Flask, jsonify  
from flask_restplus import Api, Resource
from couchbase.cluster import Cluster
from couchbase.cluster import PasswordAuthenticator
# Coucbase connections
cluster = Cluster('couchbase://localhost/')
authenticator = PasswordAuthenticator('username', 'password')
cluster.authenticate(authenticator)
cb = cluster.open_bucket('bucketname')

app = Flask(__name__) 
api = Api(app=app)

@api.route("/apiname/<string:xId>")
class apiname(Resource):
    def get(self, xId):
        Member = cb.get(xId)
        pickle_in = open('mlmodel', 'rb')
        model = pickle.load(pickle_in)
        y_pred_proba = model.predict_proba(Member).tolist()
    return jsonify(y_pred_proba)


if __name__ == '__main__':  
    app.run(port = 5000, debug = True)

Here is a comparison of quart app vs flask app. Flask looks like 10 times faster than the Quart app, which stops after the test with this error _ 96930 segmentation fault_.

Quart: Quart APP Flask: Flask

Any answer/recommendation appreciated.

e_kapti
  • 61
  • 5

1 Answers1

1

I think that you're mixing Bucket with Cluster.

From the CouchBase documentation:

To connect to a Couchbase bucket, you must use Couchbase Role-Based Access Control (RBAC). This is fully described in the section Authorization. An authenticator, containing username and password, should be defined, and then passed to the cluster. Following successful authentication, the bucket can be opened.

from couchbase.cluster import Cluster
from couchbase.cluster import PasswordAuthenticator
cluster = Cluster('couchbase://localhost')
authenticator = PasswordAuthenticator('username', 'password')
cluster.authenticate(authenticator)
bucket = cluster.open_bucket('bucket-name')

So, for your case, it should be something like:

if not hasattr(g, 'cb_bucket'):
  cluster = Cluster('couchbase://localhost')
  authenticator = PasswordAuthenticator('username', 'password')
  cluster.authenticate(authenticator)
  bucket = await cluster.open_bucket('bucket-name')
return bucket
juanlumn
  • 6,155
  • 2
  • 30
  • 39
  • 1
    [According to this CouchBase documentation:](https://docs.couchbase.com/python-sdk/2.5/async-programming.html) you need to use _acoucbase.Bucket_ object which directly connects to a bucket. – e_kapti Feb 15 '19 at 15:28