Saya sedang membangun aplikasi Flask dan mengikuti tutorial/buku Miguel Grinberg yang luar biasa. Saya mencoba agar proses pekerja terpisah menjalankan beberapa tugas. Ketika saya menyertakan fungsi create_app dalam file tugas di bagian atas skrip sesuai struktur di bawah ini, saya mendapatkan pesan kesalahan:

ImportError: cannot import name 'refreshed_google_client' from partially initialized module 'app.tasks' (most likely due to a circular import) (/home/matthew/Documents/flask/artemis-34/app/tasks.py)

Namun ketika saya memindahkan fungsi create_app ke bagian bawah task.py saya tidak mendapatkan kesalahan dan fungsinya berfungsi. Saya bisa meninggalkannya di bagian bawah tetapi saya tidak berpikir ini benar-benar menyelesaikan masalah, dan itu juga masih bagus untuk memahami mengapa dependensi melingkar terjadi karena rasa ingin tahu umum.

Struktur aplikasi saya terlihat seperti:

-->app
   -->__init__.py
   -->decorators.py
   -->models.py
   -->tasks.py
   -->auth
      -->__init__.py
      -->errors.py
      -->forms.py
      -->views.py
   -->main
      -->__init__.py
      -->errors.py
      -->forms.py
      -->views.py
   -->static
   -->templates
-->migrations
config.py
flasky.py
Procfile
requirements.txt
worker.py

App/flasky.py

from flask import Flask,render_template, session, redirect, url_for, flash
import os
from app import create_app,db
from app.models import User,Role
from datetime import datetime
from flask_migrate import Migrate,upgrade

app = create_app(os.getenv('FLASK_CONFIG') or 'default')

App/_ init _.py

from flask import Flask, render_template
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from config import config
from flask_session import Session
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
import rq
from redis import Redis
from flask_login import LoginManager
from worker import conn
import os

bootstrap = Bootstrap()
moment = Moment()
db = SQLAlchemy()
scheduler = BackgroundScheduler()
migrate = Migrate()
session= Session()
login_manager = LoginManager()
login_manager.login_view = 'auth.login'

def create_app(config_name='default'):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    db.init_app(app)
    bootstrap.init_app(app)
    moment.init_app(app)
    migrate.init_app(app,db)
    session.init_app(app)
    login_manager.init_app(app)
    if not scheduler.running:
        scheduler.start()
        jobstore_url = os.environ.get('DATABASE_URL')
        scheduler.add_jobstore(SQLAlchemyJobStore(url=jobstore_url),'sqlalchemy')

    from .main import main as main_blueprint
    from .auth import auth as auth_blueprint

    app.register_blueprint(main_blueprint)
    app.register_blueprint(auth_blueprint,url_prefix='/auth')

    app.task_queue = rq.Queue(connection=conn) #Redis.from_url(os.environ.get(REDIS_URL))

    if app.config['SSL_REDIRECT']:
        from flask_sslify import SSLify
        sslify = SSLify(app)

    return app

App/tasks.py

from . import create_app,db
from .models import User,Tokens,Files
from .decorators import token_getter
from flask_login import current_user
import requests
import datetime as dt
import urllib
import os

app = create_app(os.getenv('FLASK_CONFIG') or 'default')

<FUNCTIONS HERE>

App/auth/views.py

from flask import render_template,url_for,redirect,request,flash,session,current_app,Response
from .. import db,scheduler
from . import auth
from ..models import User,Role,Tokens,Files
from flask_login import login_user, logout_user, login_required
from ..decorators import admin_required, token_setter, token_getter,permission_required
import requests
import urllib
from .forms import LoginForm, SubmitConnection, ScheduleJobForm
from app.tasks import refreshed_google_client,test_context

App/main/views.py

from flask import render_template, session, redirect, url_for, flash,current_app,request
from datetime import datetime
from . import main
from .. import db,scheduler
from ..models import User,Tokens
from .forms import NameForm,AnalyticsForm
from flask_login import login_required,current_user
from ..decorators import admin_required,permission_required
import requests
import rq
from redis import Redis
from app.tasks import refreshed_google_client,load_analytics
0
emvy03 18 Mei 2021, 12:36

1 menjawab

Jawaban Terbaik

Anda memiliki impor melingkar berikut: create_app -> from .main import main as main_blueprint -> from app.tasks import refreshed_google_client,load_analytics -> create_app

Coba gunakan flask.current_app di dalam app/tasks.py atau pindahkan from app.tasks import refreshed_google_client,load_analytics di dalam penangan permintaan Anda seperti ini:

@main_blueprint.route('/')
def get():
    from app.tasks import refreshed_google_client
    ...
1
Alexander Volkovsky 18 Mei 2021, 09:59