python - Flask蓝图架构问题

标签 python flask

我是使用 Flask 的新手,所以我正在进行大量研究,以找出构建我的应用程序的最佳方法。我一直在关注应用程序工厂并使用蓝图,但我无法弄清楚如何使用应用程序范围的库并保留应用程序上下文。例如,这是我的应用程序结构:

├── app
│   ├── acuity
│   │   ├── handlers.py
│   │   ├── __init__.py
│   │   └── routes.py
│   ├── config.py
│   ├── __init__.py
│   ├── logs
│   ├── main
│   │   ├── __init__.py
│   │   └── routes.py
│   ├── slackapi.py
│   └── templates
│       └── acuity
│           └── acuity_slack.j2
├── gunicorn_config.py
├── slackbot.py
├── README.md
└── requirements.txt

Main 和 Acuity 是蓝图。 Main 不执行任何操作,唯一的端点是敏锐度。在 acuity.handlers 中,我在 app.slackapi 中导入,但无论我如何切片都无法使用 current_app 。我需要使用应用程序上下文才能访问日志记录和配置变量。

将 slackapi 和我制作的任何其他常用实用函数或常用库放入全局 Flask 上下文中以便我可以在任何蓝图中使用它们的最佳方法是什么?

编辑: 这就是我从 acuity.handlers 导入的方式

import dateutil.parser, datetime, os, json, requests
from jinja2 import Environment, FileSystemLoader
import app.slackapi as slack
from flask import current_app

如果我尝试在 app.slackapi 中 fromflask import current_app ,它不会出错。但是如果我尝试像这样使用和引用 current_app :

import time
from slackclient import SlackClient
from flask import current_app

# instantiate Slack client
slack_client = SlackClient(current_app['SLACK_API_TOKEN'])

出现这个错误

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/usr/local/lib/python3.5/dist-packages/gunicorn/workers/base.py", line 129, in init_process
    self.load_wsgi()
  File "/usr/local/lib/python3.5/dist-packages/gunicorn/workers/base.py", line 138, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/usr/local/lib/python3.5/dist-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/usr/local/lib/python3.5/dist-packages/gunicorn/app/wsgiapp.py", line 52, in load
    return self.load_wsgiapp()
  File "/usr/local/lib/python3.5/dist-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/usr/local/lib/python3.5/dist-packages/gunicorn/util.py", line 350, in import_app
    __import__(module)
  File "/opt/slackbot/slackbot/slackbot.py", line 3, in <module>
    app = create_app()
  File "/opt/slackbot/slackbot/app/__init__.py", line 22, in create_app
    from app.acuity import bp as acuity_bp
  File "/opt/slackbot/slackbot/app/acuity/__init__.py", line 5, in <module>
    from app.acuity import routes
  File "/opt/slackbot/slackbot/app/acuity/routes.py", line 4, in <module>
    from app.acuity import handlers
  File "/opt/slackbot/slackbot/app/acuity/handlers.py", line 3, in <module>
    import app.slackapi as slack
  File "/opt/slackbot/slackbot/app/slackapi.py", line 10, in <module>
    slack_client = SlackClient(current_app['SLACK_API_TOKEN'])
  File "/usr/local/lib/python3.5/dist-packages/werkzeug/local.py", line 377, in <lambda>
    __getitem__ = lambda x, i: x._get_current_object()[i]
  File "/usr/local/lib/python3.5/dist-packages/werkzeug/local.py", line 306, in _get_current_object
    return self.__local()
  File "/usr/local/lib/python3.5/dist-packages/flask/globals.py", line 51, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

编辑二: app/__init__.py

  import logging
  from logging.handlers import RotatingFileHandler
  import os
  from flask import Flask, request, current_app
  from config import Config


  def create_app(config_class=Config):
      app = Flask(__name__)
      app.config.from_object(config_class)

      from app.main import bp as main_bp
      app.register_blueprint(main_bp)

      from app.acuity import bp as acuity_bp
      app.register_blueprint(acuity_bp)

      if not app.debug and not app.testing:
          if app.config['LOG_TO_STDOUT'] == "True":
              stream_handler = logging.StreamHandler()
              stream_handler.setLevel(logging.INFO)
              app.logger.addHandler(stream_handler)
          else:
              if not os.path.exists(os.path.dirname(__file__) + '/logs'):
                  os.mkdir(os.path.dirname(__file__) + '/logs')
              file_handler = RotatingFileHandler(os.path.dirname(__file__) + '/logs/slackbot.log',
                                                 maxBytes=10240, backupCount=10)
              file_handler.setFormatter(logging.Formatter(
                  '%(asctime)s %(levelname)s: %(message)s '
                  '[in %(pathname)s:%(lineno)d]'))
              file_handler.setLevel(logging.INFO)
              app.logger.addHandler(file_handler)

          app.logger.setLevel(logging.INFO)
          app.logger.info('Slackbot startup')

      return app

app/acuity/__init__.py

from flask import Blueprint

bp = Blueprint('acuity', __name__)

from app.acuity import routes

最佳答案

为什么不能在应用程序包的 __init__.py 文件中添加 create_app() 函数并在此函数中注册您的蓝图?然后,您只需在所需的蓝图中导入 current_app 变量,并根据需要引用 current_app 变量即可。大致如下:

__init__.py:

 # .... other package initialization code

 def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(Config)

    # initialization of important app components
    # database, login_manager, mail, etc....
    db.init_app(app)

    # register blueprints
    from app.acuity.routes import <acuity_blueprint_variable>
    from app.main.routes import blueprint
    app.register_blueprint(<acuity_blueprint_variable>)
    app.register_blueprint(blueprint)

return app

ma​​in/routes.py:

   # import your flask dependencies then just reference current_app where necessary
   from flask import request, redirect, url_for, render_template, current_app, Response

   blueprint = flask.Blueprint('main', __name__)

   @blueprint.route("/api", methods=["GET"])
   def list_routes():
       result = []
       for rt in current_app.url_map.iter_rules():
           result.append({
               "methods": list(rt.methods),
               "route": str(rt)
        })

    return flask.jsonify({"routes": result, "total": len(result)})

在上面的示例中,我展示了在 main 蓝图 list_routes 端点中使用 current_app,它仅显示为您的应用程序定义的路由。请注意,在您的 create_app 函数中,我导入了在 main.routes 中创建的名为“blueprint”的蓝图变量,并将此蓝图注册到应用程序,以便引用 current_app 变量可以在此蓝图的路由内创建。

希望这是有道理的!

关于python - Flask蓝图架构问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54858978/

相关文章:

Python IMAP 在日期之前获取电子邮件,并且还未看到

python - 属性错误: object has no attribute 'title'

python - 你如何在 python 中列出所有可能的安排?

python - 在 Windows 上的线程中使用 Popen 进行交互时,socketio.emit() 不起作用

python - Flask-Login 不会将 cookie 设置为具 Angular 浏览器?

python - 在 Flask 服务器中禁用控制台消息

python - 在皇帝模式下在 uWSGI 下运行 Pyramid 应用程序时日志记录不起作用

python - 安装 PyQt 时出错

python - 如何压缩整个文件夹(带有子文件夹)并通过 Flask 提供它而不将任何内容保存到磁盘

python - Python Flask 中可插入 View 和蓝图的区别