折腾:
【未解决】Flask中如何在其他模块中引入当前的app或者全局单一实例的app
期间,给app.py中用了:
def create_rest_api(app): from resources.qa import RobotQaAPI from resources.asr import RobotAsrAPI from resources.files import GridfsAPI, TmpAudioAPI rest_api = Api() rest_api.add_resource(RobotQaAPI, '/qa', endpoint='qa') rest_api.add_resource(RobotAsrAPI, '/asr/language/<string:language>', endpoint='asr') rest_api.add_resource(GridfsAPI, '/files/<fileId>', '/files/<fileId>/<fileName>', endpoint='gridfs') rest_api.add_resource(TmpAudioAPI, '/tmp/audio/<filename>', endpoint='TmpAudio') rest_api.init_app(app) return rest_api ################################################################################ # Global Init App ################################################################################ print("in flask app: settings=%s" % (settings)) app = create_app(settings) # register_extensions(app) log = app.logger log.debug("app=%s", app) log.debug("log=%s", log) log.debug("settings.FLASK_ENV=%s", settings.FLASK_ENV) log.debug("settings.DEBUG=%s, settings.MONGODB_HOST=%s, settings.FILE_URL_HOST=%s", settings.DEBUG, settings.MONGODB_HOST, settings.FILE_URL_HOST) with app.app_context(): # api = Api(app) api = Api() # <flask_restful.Api object at 0x1064e5438> log.debug("api=%s", api) api = create_rest_api(app) log.debug("api=%s", api)
其中create_rest_api中,为了后续给api中挂上对应的其他模块的类,则需要去引入其他模块:
from resources.qa import RobotQaAPI
而对应的qa.py中是:
from flask import g app = g.app log = g.log
然后报错:
Traceback (most recent call last): File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1664, in <module> main() File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1658, in main globals = debugger.run(setup['file'], None, None, is_module) File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1068, in run pydev_imports.execfile(file, globals, locals) # execute the script File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile exec(compile(contents+"\n", file, 'exec'), glob, loc) File "/Users/crifan/dev/dev_root/company/xxx/projects/robotDemo/server/xxxRobotDemoServer/app.py", line 55, in <module> api = create_rest_api(app) File "/Users/crifan/dev/dev_root/company/xxx/projects/robotDemo/server/xxxRobotDemoServer/app.py", line 23, in create_rest_api from resources.qa import RobotQaAPI File "/Users/crifan/dev/dev_root/company/xxx/projects/robotDemo/server/xxxRobotDemoServer/resources/qa.py", line 14, in <module> app = g.app File "/Users/crifan/.virtualenvs/xxxRobotDemoServer-SCpLPEyZ/lib/python3.6/site-packages/werkzeug/local.py", line 347, in __getattr__ return getattr(self._get_current_object(), name) AttributeError: '_AppCtxGlobals' object has no attribute 'app'
现在:
希望解决这个问题
能实现:
app.py中,可以正常调用其他的模块
flask g AttributeError: ‘_AppCtxGlobals’ object has no attribute
突然想到:
尝试去把app.py中的api的创建,还是放到之前的factory中
此处,调用之前,g是
<flask.g of ‘factory’>
然后进入qa.py时,果然有值了:
【总结】
此处是把之前
flask-restful的Api()的初始化部分,从app.py中,换到(最早就是放在)factory.py中的extension中,即可。
因为本身之前factory中extension部分,就加上了:
with app.app_context()
完整代码如下:
app.py
from conf.app import settings from factory import create_app # from factory import log print("in flask app: settings=%s" % (settings)) app = create_app(settings) # register_extensions(app) log = app.logger log.debug("app=%s", app) log.debug("log=%s", log) log.debug("settings.FLASK_ENV=%s", settings.FLASK_ENV) log.debug("settings.DEBUG=%s, settings.MONGODB_HOST=%s, settings.FILE_URL_HOST=%s", settings.DEBUG, settings.MONGODB_HOST, settings.FILE_URL_HOST) if __name__ == "__main__": app.run( host=app.config["FLASK_HOST"], port=app.config["FLASK_PORT"], debug=app.config["DEBUG"] )
和
factory.py
import os from flask import Flask import logging from logging.handlers import RotatingFileHandler # from flask_pymongo import PyMongo from gridfs import GridFS from pymongo import MongoClient from flask_restful import Api from flask_cors import CORS from celery import Celery from flask import g def create_app(config_object): # global log # app = Flask(__name__) #<Flask 'factory'> app = Flask(config_object.FLASK_APP_NAME) #<Flask 'RobotQA'> CORS(app) # app.config.from_object('config.DevelopmentConfig') # # app.config.from_object('config.ProductionConfig') app.config.from_object(config_object) with app.app_context(): g.app = app log = create_log(app) g.log = log log.debug("after load from object: app.config=%s", app.config) log.debug('app.config["DEBUG"]=%s, app.config["MONGODB_HOST"]=%s, app.config["FILE_URL_HOST"]=%s', app.config["DEBUG"], app.config["MONGODB_HOST"], app.config["FILE_URL_HOST"]) register_extensions(app) log.info("flask app extensions init completed") return app def register_extensions(app): # global log, mongo, fsCollection, api, celery log = g.log mongo = create_mongo(app) g.mongo = mongo log.info("mongo=%s", mongo) mongoServerInfo = mongo.server_info() log.debug("mongoServerInfo=%s", mongoServerInfo) fsCollection = create_gridfs_fs_collection(mongo) g.fsCollection = fsCollection log.info("fsCollection=%s", fsCollection) celery = create_celery(app) g.celery = celery log.info("celery=%s", celery) # api = Api(app) api = create_rest_api(app) log.debug("api=%s", api) g.api = api return app def create_rest_api(app): from resources.qa import RobotQaAPI from resources.asr import RobotAsrAPI from resources.files import GridfsAPI, TmpAudioAPI rest_api = Api() rest_api.add_resource(RobotQaAPI, '/qa', endpoint='qa') rest_api.add_resource(RobotAsrAPI, '/asr/language/<string:language>', endpoint='asr') rest_api.add_resource(GridfsAPI, '/files/<fileId>', '/files/<fileId>/<fileName>', endpoint='gridfs') rest_api.add_resource(TmpAudioAPI, '/tmp/audio/<filename>', endpoint='TmpAudio') rest_api.init_app(app) return rest_api
转载请注明:在路上 » 【已解决】Flask中已经用了with app.app_context()调用其他模块时g出错:AttributeError: ‘_AppCtxGlobals’ object has no attribute ‘app’