объект модуля, который нельзя вызывать с помощью официантки

Я пытаюсь развернуть свое приложение на Heroku. Я должен использовать Windows, и пушка не будет работать. Я попробовал официантку, которая продолжает выдавать мне ошибку «модуль не вызывается» всякий раз, когда я пытаюсь загрузить любую страницу.

Примечание. Я пока не развертывал его в Интернете, пытался heroku local, прежде чем создать общедоступный. Он работает на localhost при использовании PyCharm.

организация файлов

/myapp
     requirements.txt
     Procfile
     /myapp
         /static
         /templates
         __init__.py

__init __.py:

# encoding=utf-8
import click

from myapp.application import create_app
from myapp.application import db, login_manager

app = create_app()

from myapp.config import SQLALCHEMY_TRACK_MODIFICATIONS
from myapp.models import User
from myapp.views import *

app.add_url_rule('/home', HomePage.endpoint, 
      view_func=HomePage.as_view(HomePage.endpoint), methods=['GET','POST'])
# pages are defined in views.py

#other code

if __name__ == '__main__':
    # set debug to false when moving to production
    app.run()

Procfile:

web: waitress-serve --port=5000 myapp:application

проследить:

\myapp>heroku local
[WARN] No ENV file found
14:58:51 web.1   |  ERROR:waitress:Exception when serving /home
14:58:51 web.1   |  Traceback (most recent call last):
14:58:51 web.1   |    File "c:\python34\lib\site-packages\waitress\channel.py",
line 338, in service
14:58:51 web.1   |      task.service()
14:58:51 web.1   |    File "c:\python34\lib\site-packages\waitress\task.py", lin
e 169, in service
14:58:51 web.1   |      self.execute()
14:58:51 web.1   |    File "c:\python34\lib\site-packages\waitress\task.py", lin
e 399, in execute
14:58:51 web.1   |      app_iter = self.channel.server.application(env, start_re
sponse)
14:58:51 web.1   |  TypeError: 'module' object is not callable
14:58:51 web.1   |  ERROR:waitress:Exception when serving /favicon.ico
14:58:51 web.1   |  Traceback (most recent call last):
14:58:51 web.1   |    File "c:\python34\lib\site-packages\waitress\channel.py",
line 338, in service
14:58:51 web.1   |      task.service()
14:58:51 web.1   |    File "c:\python34\lib\site-packages\waitress\task.py", lin
e 169, in service
14:58:51 web.1   |      self.execute()
14:58:51 web.1   |    File "c:\python34\lib\site-packages\waitress\task.py", lin
e 399, in execute
14:58:51 web.1   |      app_iter = self.channel.server.application(env, start_re
sponse)
14:58:51 web.1   |  TypeError: 'module' object is not callable

Есть идеи, как это решить?


person hungryhippo    schedule 09.05.2018    source источник


Ответы (2)


В своем Procfile попробуйте изменить

web: waitress-serve --port=5000 myapp:application

to

web: waitress-serve --port=5000 myapp:app

Последний аргумент waitress-serve равен MODULE:OBJECT, где OBJECT это объект приложения в MODULE. Здесь вы назвали свое приложение app:

app = create_app()

(Вы не показываете нам весь свой код, но похоже, что myapp.application на самом деле является модулем, а не объектом. Вы импортируете из него create_app, db и login_manager в свой пример кода.)

person Chris    schedule 09.05.2018
comment
Правильно ли я говорю, что ОБЪЕКТ также может быть фабричным методом? - person variable; 12.11.2019
comment
@variable, фабричный метод немного загружен, но если эти строки up вам следует добавить флаг --call: ряд фреймворков, например web.py, имеют фабричные методы в своих объектах приложения, которые при вызове возвращают используемые функции WSGI. Для таких случаев waitress-serve имеет флаг --call. Таким образом: waitress-serve --call myapp.mymodule.app.wsgi_factory загрузит модуль myapp.mymodule и вызовет app.wsgi_factory, чтобы получить функцию приложения WSGI, которая будет передана waitress.server. - person Chris; 13.11.2019

У официантки свой app, поэтому нужно правильно различать app. Ответ @Chris показывает, как это сделать через Procfile. Вот еще один способ для тех, кто использует Flask:

app/init.py:

from flask import Flask

app = Flask(__name__, template_folder="some path", static_folder="another path")

main.py

from waitress import serve
from app import app as my_app  # renamed to distinguish from waitress' 'app'

if __name__ == "__main__":
    serve(my_app, host="localhost", port=5005)

Это позволяет вам сохранить ваше приложение с именем app в файле маршрутов, поскольку оно изолировано от официантки.

app/routes.py:

@app.route('/dothing1', methods=['POST', 'GET'])
def dothing1():
  pass
person Ty Hitzeman    schedule 24.07.2020