折腾:
【未解决】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’