Как разделить файлы фляг, когда два файла зависят друг от друга?

Я пытаюсь разработать фляжное приложение, управляемое базой данных. У меня есть файл api.py, в котором есть приложение flask, объекты API и SQLAlchemy db, а также файл users.py, который содержит маршруты и код для создания таблицы базы данных.

В файле users.py есть ресурс UserManager с маршрутами. Я должен добавить этот ресурс в API из этого файла.

Таким образом, users.py необходимо импортировать базу данных и API из файла api.py, а api.py необходимо обслуживать приложение фляги, чтобы оно имело все необходимые users.py переменные, но api.py также необходимо импортировать users.py, чтобы использовать его в качестве плана фляги.

api.py:

...
from user import user

app = Flask(__name__)
app.register_blueprint(user)
api = Api(app)
...
db = SQLAlchemy(app)
ma = Marshmallow(app)
...
if __name__ == '__main__':
    app.run(debug=True)

users.py:

from api import api

user = Blueprint('user', __name__, template_folder='templates')

db = SQLAlchemy(api.app)
ma = Marshmallow(api.app)

class User(db.Model):
    user_id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True, nullable=False)
    username = db.Column(db.String(32), unique=True, nullable=False)
    password = db.Column(db.String(32))
    first_name = db.Column(db.String(32))
    last_name = db.Column(db.String(32))
    ...
...

class UserManager(Resource):
    @user.route('/get/<user_id>', methods = ['GET'])
    def get_user(user_id):
        ...

Это, конечно, приводит к ошибкам из-за циклического импорта. Вопрос в том, как мне отделить файлы flask с маршрутами от файла API, когда план имеет зависимости от API (объекты db и API)

Я также каким-то образом должен сделать что-то вроде api.add_resource(UserManager, '/api/users'), но я не уверен, куда это пойдет, учитывая циклический импорт.

Пытался уменьшить зависимости между двумя файлами, но не смог достичь описанной цели без двустороннего импорта.

Либо пытаться заставить работать двухсторонний импорт, либо иметь ту же структуру отдельных файлов с маршрутами, но с использованием одностороннего импорта.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
172
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это хорошо известная проблема в flask. Решение — использовать фабрики приложений.

Cookiecutter Flask отлично с этим справляется и предлагает хороший шаблон. Стоит проверить их репо и попытаться понять, что они делают.

Предположим, у вас есть папка app, и эта папка содержит файл __init__.py и другие ваши файлы user.py и т. д.

  1. Создайте файл app/extensions.py с этим содержимым и любым другим расширением, которое вам нужно инициализировать.
...
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
...
  1. Импортируйте объект db (который был создан, но не инициализирован) в нужные вам файлы.
from app.extensions import db
  1. В вашем файле app/api.py
from flask import Flask
from app.extensions import db
from app.user import user as user_bp

def create_app():
    app = Flask(__name__)
    register_extensions(app)
    register_blueprints(app)
    return app

def register_extensions(app):
    """Register Flask extensions."""
    db.init_app(app)
    return None

def register_blueprints(app):
    """Register Flask blueprints."""
    app.register_blueprint(user_bp)
    return None

if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

Добавляйте материалы, основанные на этом подходе, по мере необходимости.

Другие вопросы по теме