Имя flask-ask «ask» не определено при использовании Blueprints и отдельного views.py

При следовании руководствам декоратор @ask работает, когда он находится в том же файле, что и ask = Ask(app, "/someroute") и после app = Flask(name). Если я хочу поместить декораторы @ask в файл представления в своей собственной папке, используя Blueprints, независимо от того, что я пытаюсь, я получаю «имя« спросить »не определено» с помощью декоратора.

Я должен сказать, что я новичок в flask, но теперь у меня есть базовое приложение, работающее с такими вещами, как flask-principal, работающее с flask-login и flask-navigation, способное отображать пункты меню, только если это разрешено.

Я следовал многим руководствам по flask-ask, и все работает (пока), но я бы предпочел иметь код представления в отдельном views.py в своей собственной папке и использовать Blueprints. Я использую create_app(config_name) вместо app = Flask(name), как это предлагается во многих руководствах по flask. Я хочу сделать это, так как хочу, чтобы мой основной __init__.py был как можно более чистым.

Моя новизна в flask не позволяет мне делать что-то вроде использования alexa-skills-kit-sdk-for-python в flask, как это было предложено некоторыми людьми на Gitter (поскольку flask-ask, похоже, больше не поддерживается), и я до сих пор не не понимаю flask достаточно, чтобы понять, почему объект ask недоступен в отдельном views.py

По правде говоря, у меня есть соблазн просто иметь все в app/__init__.py, так как это всего лишь приложение для хобби, но я пытаюсь структурировать свои фляжные приложения, как это предлагается во многих блогах, т.е. если для этого нет очевидного решения, тогда я прибегаю к тому, как это работает, но я не могу отделаться от ощущения, что это что-то, что я сделал неправильно с точки зрения фляги, а не фляги.

Возможно, стоит добавить, что у меня были некоторые проблемы с установкой (задыхался от PyYAML, поэтому я скачал пакет и вручную установил требования, а затем запустил setup.py (на всякий случай, если это повлияло на проблему)

#app/__init__.py
#Pytho 3

from flask_ask import Ask, statement, question, session

....

def create_app(config_name):
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_object(app_config[config_name])
    app.config.from_pyfile('config.py')

    Bootstrap(app)
    db.init_app(app)
    nav.init_app(app)
    toolbar.init_app(app)

    login_manager.init_app(app)
    login_manager.login_message = "You must be logged in to access this page."
    login_manager.login_view = "auth.login"    

    principals = Principal(app)

    ask = Ask(app, "/alexa")
    ask.init_app(app) #have also done it without this as some of the tutorials don't mention it

    from .auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint)

    from .home import home as home_blueprint
    app.register_blueprint(home_blueprint)

    from .alexa import alexa as alexa_blueprint
    app.register_blueprint(alexa_blueprint,url_prefix='/alexa')



    # This loads fine 
    @ask.launch
    def start_skill():
        welcome_message = 'Hello there, would you like the news?'
        return question(welcome_message)

Если я удалю код декоратора @ask и поставлю его, как показано ниже....

#app/alexa/views.py
from flask_ask import Ask, statement, question, session
import json
import requests
import time
import unidecode

from . import alexa

    @alexa.route('/')
    def alexa_route():
     return('alexa')

    #this doesn't work
    @ask.launch # this is on line 33 (as below error)
    def start_skill():
        welcome_message = 'Hello there, would you like the news?'
        return question(welcome_message)

Я получаю (я использую venv, поэтому пути к виртуальной среде)

Файл "/Users/username/Documents/Personal/Pi/template/lib/python3.7/site-packages/flask/app.py", строка 2309, в call return self.wsgi_app(environ , start_response) Файл "/Users/username/Documents/Personal/Pi/template/lib/python3.7/site-packages/flask/app.py", строка 2295, в ответе wsgi_app = self.handle_exception(e) File " /Users/username/Documents/Personal/Pi/template/lib/python3.7/site-packages/flask/app.py", строка 1741, в handle_exception reraise(exc_type, exc_value, tb) File "/Users/username/ Documents/Personal/Pi/template/lib/python3.7/site-packages/flask/_compat.py", строка 35, при повторном повышении значения File "/Users/username/Documents/Personal/Pi/template/lib/python3 .7/site-packages/flask/app.py", строка 2292, в wsgi_app response = self.full_dispatch_request() File "/Users/username/Documents/Personal/Pi/template/lib/python3.7/site-packages /flask/app.py", строка 1815, в файле full_dispatch_request rv = self.handle_user_exception(e) "/Users/username/Documents/Personal/Pi/templ ate/lib/python3.7/site-packages/flask/app.py", строка 1718, в handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/username/Documents/Personal/Pi/template/lib/python3 .7/site-packages/flask/_compat.py", строка 35, при повторном повышении значения File "/Users/username/Documents/Personal/Pi/template/lib/python3.7/site-packages/flask/app. py", строка 1813, в файле full_dispatch_request rv = self.dispatch_request() "/Users/username/Documents/Personal/Pi/template/lib/python3.7/site-packages/flask_debugtoolbar/init .py", строка 125, в dispatch_request return view_func(**req.view_args) File "/Users/username/Documents/Personal/Pi/baseapp/app/alexa/views.py", строка 33, в alexa_route return(ask ) NameError: имя «аск» не определено


person Simon F    schedule 05.02.2019    source источник


Ответы (1)


При использовании фабрики приложений фляги вы должны создать объект модуля вне create_app :

#my_app/__init__.py

from flask_ask import Ask, statement, question, session
...
ask = Ask()

def create_app(config_name):
    app = Flask(...)
    ...

    ask.init_app(app)

Затем вы можете импортировать объект, когда вам это нужно:

#my_app/alexa/views.py
from my_app import ask
...

@ask.launch
def start_skill():
    welcome_message = 'Hello there, would you like the news?'
    return question(welcome_message)

Остерегайтесь называть свое приложение «приложением», так как это может сбивать с толку. Я взял на себя смелость изменить его на «my_app» для большей ясности.

person Roch    schedule 05.02.2019