简体   繁体   中英

How to share a flask-pymongo instance in the api routes handler

I am trying to design a simple api using flask, flask-restplus, and flask-pymongo but I'm facing one structural design, based on import and variables sharing, I cannot get access to the db in any way.

Here is my code in my main engine file:

app = Flask(__name__)
db = PyMongo(app)

api = Api(app)

from auth import namespace as ns1
api.add_namespace(registerNamespace.api)


if __name__ == '__main__':
     api.run()

But at the same time, I would like to get access to the db instance in actual api implementation:

from engine import engine

api = Namespace('register', description="Registration")

db = engine.db

@api.route('/whatever')
Class Whatever():
 def get(self):
    db.doSomething();
    return "Simple getter"

I get the following error.

ImportError: cannot import name engine

I've been trying to fix this in quite a long time, because I don't think it is that stupid of a structural decision but I probably am wrong. Which ways, either structural or import wise could help fixing this?

Thank you in advance!

There is myriad of approaches to architect your flask application for easy resource sharing. I however favor binding resources to a common package usually the application package such that other modules can import resources from that package.

Say we have a fictitious project named demo with the following structure:

.
├── api
│   ├── __init__.py
│   └── namespace1.py
└── demo
    ├── __init__.py
    ├── main.py
    └── setup.py

Notice that we have api separate as its own package.

Here is a brief description of the contents of individual module.

demo/__init__.py

db = None # initials package level name to None. 

demo/setup.py

from flask import Flask
from flask_pymongo import PyMongo

import demo

app = Flask('demo')
demo.db = PyMongo(app)  # Here is where we bind the shared resource to the package level name.

demo/main.py

from demo.setup import app
from api import register_api

register_api(app)

if __name__ == '__main__':
     app.run()

Our API can import from demo easily:

api/namespace1.py

from flask_restplus import Namespace, Resource, fields

from demo import db  # Look ma!, it's easy to share resources.
...

@ns.route('/')
class CatList(Resource):
    @ns.doc('list_cats')
    @ns.marshal_list_with(cat)
    def get(self):
        '''List all cats'''
        print(db)
        return CATS

You can view the complete sample here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM