折腾:
【未解决】用蓝图和工厂模式去优化现有Flask项目代码结构
期间,Flask中改造为create_app的工厂模式后,结果遇到了循环导入的问题:
File "/Users/crifan/dev/dev_root/company/xxx/projects/robotDemo/server/xxxRobotDemoServer/app.py", line 4, in <module> from factory import create_app File "/Users/crifan/dev/dev_root/company/xxx/projects/robotDemo/server/xxxRobotDemoServer/factory.py", line 8, in <module> from resources.tts import testAudioSynthesis, initAudioService File "/Users/crifan/dev/dev_root/company/xxx/projects/robotDemo/server/xxxRobotDemoServer/resources/tts.py", line 5, in <module> from app import app, log File "/Users/crifan/dev/dev_root/company/xxx/projects/robotDemo/server/xxxRobotDemoServer/app.py", line 4, in <module> from factory import create_app ImportError: cannot import name 'create_app'
不用贴代码,就可以看出是循环导入的问题。
此处的需求是:
在别的resources中,也需要导入当前的app(其实主要只用到了app.confg)以及其他变量(比如celery)
但是会导致循环调用
flask circular import create_app
有问题:别处初始化别的extension时,需要app.config的配置啊
怎么传递过去?
算了,把import的函数,放到初始化里面,避免递归调用吧
factory.py
import os from flask import Flask from flask_restful import Api 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 ################################################################################ # Global Variables ################################################################################ log = logging.getLogger() print("log=%" % log) # api = Api(app) api = Api() print("api=%" % api) ... ################################################################################ # Global Function ################################################################################ def create_app(config_object): app = Flask(__name__) CORS(app) # app.config.from_object('config.DevelopmentConfig') # # app.config.from_object('config.ProductionConfig') app.config.from_object(config_object) register_extensions(app) def register_extensions(app): global log, mongo, fsCollection, api, celery log = create_log(app) ... from resources.tts import testAudioSynthesis, initAudioService from resources.asr import initASR # testAudioSynthesis() initAudioService() log.info("inited for tts") initASR() log.info("inited for asr") api = create_rest_api(app) log.info("api=%s", 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 ...
不过,在factory.py中
create_app之后再去register_extensions中,
from resources.tts import testAudioSynthesis, initAudioService from resources.asr import initASR # testAudioSynthesis() initAudioService() log.info("inited for tts") initASR()
还是会去导入resources.tts
而tts.py中还是会:
from app import app, log
-》在app没有完全初始化之前,还是会调用到当前的app
-》还是无法避免循环导入的问题。
感觉是:
获取只要保证其他resources中能,在使用的时候,再去引用app,
以及确保使用current_app,或者全局的g中保存app或log或app.logger,或许就可以了?
【已解决】Flask中如何在其他模块中引入当前的app或者全局单一实例的app
转载请注明:在路上 » 【已解决】Flask中循环导入app和create_app的问题:ImportError: cannot import name ‘create_app’