Search code examples
pythonmongodbflaskpymongovercel

How to share/ensure connections are closed in Flask + mongo (pymongo) in Vercel serverless functions?


I am currently using vercel as my api with python serverless functions. I have serveral functions defined.

An example file could look something like...

import pymongo
from flask import Flask, jsonify


MONGO_URL = os.environ["MONGO_URL"]
CLIENT = pymongo.MongoClient(MONGO_URL)
DB = pymongo.database.Database(CLIENT, os.environ.get("DB") or "test")

app = Flask(__name__)

@app.route("/api/sample_route", methods=["GET"])
def sample_route(path=""):
    COLLECTION = DB.sample_collection
    if request.method == "GET":
        query = {}
        data = list(COLLECTION.find(query, {"_id": 0}))
        return jsonify(data)

However I notice that I quickly hit the 500 connection pool working on the site on my local dev without any users. I believe there is no connection pooling going on and that they are not adequately getting closed. Any idea why?


Solution

  • There can be better ways to do this, but in my experience I have seen people define functions that return a db client object which is further used in functions doing CRUD operations

    def get_db_client(host=MONGO_URL, port=27017):
            client = MongoClient(host=host
            return client
    

    An example of a flask function performing CRUD would look like:

    @app.route('/orders')
    def get_orders():
        client = None
        try:
            client = get_db_client()
            db = client["orders_database"]
            order_id = int(request.args.get('order_id'))
            cursor = db.orders_tb.find({"order_id": order_id})
        except:
            # Some exception handling
            pass
        finally:
            if type(client)==MongoClient:
                client.close()
            return jsonify({"result": list(cursor)})
    

    The main motivation is to close a connection every time you are done with it. You can find better design patterns than the try-except-finally I have shown here, but it is essential to close connections.