【问题标题】:Heroku and Flask - ModuleNotFoundError: No module named 'fetch_data'Heroku 和 Flask - ModuleNotFoundError:没有名为 'fetch_data' 的模块
【发布时间】:2021-03-23 20:10:56
【问题描述】:

我正在尝试将我的 flask+react 应用程序部署到 heroku,但它崩溃并给我以下错误:

ModuleNotFoundError: 没有名为“fetch_data”的模块

这是日志的 sn-p:

2021-03-23T19:34:05.332761+00:00 app[web.1]: Traceback (most recent call last):
2021-03-23T19:34:05.332763+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/gunicorn/arbiter.py",
 line 583, in spawn_worker
2021-03-23T19:34:05.332764+00:00 app[web.1]: worker.init_process()
2021-03-23T19:34:05.332765+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/gunicorn/workers/base
.py", line 119, in init_process
2021-03-23T19:34:05.332765+00:00 app[web.1]: self.load_wsgi()
2021-03-23T19:34:05.332765+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/gunicorn/workers/base
.py", line 144, in load_wsgi
2021-03-23T19:34:05.332766+00:00 app[web.1]: self.wsgi = self.app.wsgi()
2021-03-23T19:34:05.332766+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/gunicorn/app/base.py"
, line 67, in wsgi
2021-03-23T19:34:05.332767+00:00 app[web.1]: self.callable = self.load()
2021-03-23T19:34:05.332767+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/gunicorn/app/wsgiapp.
py", line 49, in load
2021-03-23T19:34:05.332767+00:00 app[web.1]: return self.load_wsgiapp()
2021-03-23T19:34:05.332768+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/gunicorn/app/wsgiapp.
py", line 39, in load_wsgiapp
2021-03-23T19:34:05.332768+00:00 app[web.1]: return util.import_app(self.app_uri)
2021-03-23T19:34:05.332768+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/gunicorn/util.py", li
ne 358, in import_app
2021-03-23T19:34:05.332769+00:00 app[web.1]: mod = importlib.import_module(module)
2021-03-23T19:34:05.332769+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/importlib/__init__.py", line 127, i
n import_module
2021-03-23T19:34:05.332770+00:00 app[web.1]: return _bootstrap._gcd_import(name[level:], package, level)
2021-03-23T19:34:05.332771+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
2021-03-23T19:34:05.332771+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 983, in _find_and_load
2021-03-23T19:34:05.332771+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
2021-03-23T19:34:05.332772+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
2021-03-23T19:34:05.332772+00:00 app[web.1]: File "<frozen importlib._bootstrap_external>", line 728, in exec_module
2021-03-23T19:34:05.332772+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_remove
d
2021-03-23T19:34:05.332773+00:00 app[web.1]: File "/app/api/api.py", line 2, in <module>
2021-03-23T19:34:05.332773+00:00 app[web.1]: from fetch_data import fetch_data
2021-03-23T19:34:05.332773+00:00 app[web.1]: ModuleNotFoundError: No module named 'fetch_data'
2021-03-23T19:34:05.332985+00:00 app[web.1]: [2021-03-23 19:34:05 +0000] [9] [INFO] Worker exiting (pid: 9)
2021-03-23T19:34:05.391634+00:00 app[web.1]: [2021-03-23 19:34:05 +0000] [4] [INFO] Shutting down: Master
2021-03-23T19:34:05.392273+00:00 app[web.1]: [2021-03-23 19:34:05 +0000] [4] [INFO] Reason: Worker failed to boot.
2021-03-23T19:34:05.544193+00:00 heroku[web.1]: Process exited with status 3
2021-03-23T19:34:05.617532+00:00 heroku[web.1]: State changed from up to crashed

现在fetch_data 是我在api 文件夹中制作的一个包。下面是api文件夹的目录结构:

.
|-- __pycache__
|   |-- api.cpython-37.pyc
|   `-- fetch_data.cpython-37.pyc
|-- api.py
|-- fetch_data
|   |-- __init__.py
|   `-- fetch_data.py
|-- static
|   `-- react
|-- templates
|   `-- index.html
|-- test.py
`-- venv
    |-- Include
    |-- Lib
    |-- Scripts
    `-- pyvenv.cfg

fetch_data.py 是我在api.py. 中调用的烧瓶蓝图

this is a snippet of api.py:

from flask import Flask, jsonify, render_template
from fetch_data import fetch_data
from nsepy import get_history
from datetime import date,timedelta
import pandas as pd
import os
import json

app = Flask(__name__)
app.register_blueprint(fetch_data.fetch_api)

@app.route('/')
def index():
    return render_template("index.html", flask_token = "Hello World")
.
.
.

if __name__ == '__main__':
    port =int(os.environ['PORT'])
    app.run(host='0.0.0.0', debug=False, port= port)

这是fetch_data.py的代码:

from flask import Blueprint
from nsetools import Nse

fetch_api = Blueprint('fetch_api', __name__, url_prefix='/fetch')

@fetch_api.route('/api/<string:ticker>', methods = ['GET'])
def fetch_data(ticker):
    nse = Nse()

    return nse.get_quote(ticker, as_json = True)

@fetch_api.route('/gainers', methods = ['GET'])
def fetch_gainers():
    nse = Nse()
    return nse.get_top_gainers(as_json = True)

@fetch_api.route('/losers', methods = ['GET'])
def fetch_losers():
    nse = Nse()
    return nse.get_top_losers(as_json = True)

我看到一些答案提到Procfile 可能有问题,但我认为我的看起来不错。

web: gunicorn -w 1 -b 0.0.0.0:$PORT api.api:app

我对flask和heroku还是新手,所以如果这个问题的解决方案很明显,我深表歉意。提前感谢您的帮助。

【问题讨论】:

    标签: python flask heroku


    【解决方案1】:

    最好使用这种结构,每个关注点都是独立的:

    project
      |----- app.py
      |----- test.py
      |----- .flaskenv
      |----- app/
               |----- __init__.py
               |----- fetch_data/
                          |----- __init__.py
                          |----- routes.py
               |----- main/
                       |----- __init__.py
                       |----- routes.py
               |----- static/
                        |----- # <your-static-files>
               |----- templates/
                          |----- index.html
    

    app.py 是您的应用程序的入口点。它将具有:

    from app import create_app
    
    app = create_app()
    
    # ...
    

    您的 routes.py 将如下所示(将 fetch_api.py 重命名为 routes.py 以使其在 fetch api 包中的作用更加明显):

    # all your fetch_data.py code
    # ...
    
    @bp.route('/losers', methods = ['GET'])
    def fetch_losers():
        nse = Nse()
        return nse.get_top_losers(as_json = True)
    
    
    fetch_data 包中的

    __init__.py 将定义您的蓝图

    from flask import Blueprint
    
    bp = Blueprint('fetch_api', __name__)
    
    from app.fetch_data import routes
    
    

    main 包将包含有关应用程序的所有其他详细信息。在 main 的路线中,您将拥有:

    # Remember to initialize the main package appropriately 
    # so as to use Flask's Blueprint
    # ...
    
    @bp.route('/')
    def index():
        return render_template("index.html", flask_token = "Hello World")
    
    # ...
    

    __init__.py 文件是您的应用程序实例:

    from flask import Flask
    # all your other imports go here
    
    app = Flask(__name__)
    
    # ...
    
    def create_app(config_class=Config):
        app = Flask(__name__)
        app.config.from_object(config_class)
    
        from app.fetch_api import bp as fetch_bp
        app.register_blueprint(fetch_bp, url_prefix='/fetch')
    
        # ...
    
        return app
    
    from app import models  # add/remove if modules exist/don't exist in your app folder
    

    这将消除您在应用程序包中可能遇到的任何导入问题。

    【讨论】:

    • 所以如果我理解正确,我将不得不像我们为 fetch_data 所做的那样初始化 main,然后像 from app.home import bp as home_bp app.register_blueprint(home_bp, url_prefix='/') 这样注册蓝图。我的 app.run() 也将在app/__init.py__ 中。我说的对吗?
    • 是的,对于home 包。
    • 有了这个结构,就不用app.run()了。您的应用程序识别出app.py 已被设置为入口点。删除if '__main__' 部分。
    • 要运行它,您需要在一个名为.flaskenv 的新文件中创建环境变量,该文件位于顶级目录中并传递FLASK_APP=app.py 变量
    • 附带说明,flask 需要某些环境变量来启动服务器。这些变量传统上在终端中以$ export FLASK_APP=app.py 运行。 .flaskenv 避免了必须始终单独运行这些命令的麻烦。因此,要运行它们,您将使用python-dotenv 包。所以安装它pip3 install python-dotenv
    猜你喜欢
    • 2019-08-02
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2019-12-16
    • 2018-07-06
    • 1970-01-01
    相关资源
    最近更新 更多