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.