最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Flask中循环导入app和create_app的问题:ImportError: cannot import name ‘create_app’

Flask crifan 1497浏览 0评论
折腾:
【未解决】用蓝图和工厂模式去优化现有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
python – Can I avoid circular imports in Flask and SQLAlchemy – Stack Overflow
有问题:别处初始化别的extension时,需要app.config的配置啊
怎么传递过去?
flask – Avoiding circular imports Python – Stack Overflow
python – Flask circular dependency – Stack Overflow
python – Flask circular imports with multiple model files – Stack Overflow
flask-sqlalchemy-circular-imports/app.py at master · ltalirz/flask-sqlalchemy-circular-imports
Larger Applications — Flask 0.12.4 documentation
Becoming Big — Flask 0.12.4 documentation
Flask web dev: Always use application factories – tobywf
算了,把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’

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.164 seconds, using 22.10MB memory