Skip to content
Advertisement

Azure + gunicorn + flask + Azure Web App Linux: ModuleNotFoundError: No module named ‘flaskr’

the use case

I have followed the flask tutorial on those pages: https://flask.palletsprojects.com/en/1.1.x/tutorial/

The project directory is the following :

/src
├── flaskr/
│   ├── __init__.py
│   ├── db.py
│   ├── schema.sql
│   ├── auth.py
│   ├── blog.py
│   ├── templates/
│   │   ├── base.html
│   │   ├── auth/
│   │   │   ├── login.html
│   │   │   └── register.html
│   │   └── blog/
│   │       ├── create.html
│   │       ├── index.html
│   │       └── update.html
│   └── static/
│       └── style.css
├── tests/
│   ├── conftest.py
│   ├── data.sql
│   ├── test_factory.py
│   ├── test_db.py
│   ├── test_auth.py
│   └── test_blog.py
├── venv/
├── setup.py
└── MANIFEST.in

run the web app

The web app works by running the script ‘run_app_prod.sh’.

the code works on my local machine (ubuntu 20.04) but not on azure web app for linux

run_app_prod.sh

#/bin/bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

echo current $DIR

python -m pip install -e src

./test_if_db_exists.sh

export FLASK_APP="flaskr:create_app()"
# export FLASK_ENV=development

# flask run --host=0.0.0.0
gunicorn --bind=0.0.0.0 --timeout 600 "flaskr:create_app()"

the flaskr/init.py files

# *-* coding:utf-8 *-*

import os

from flask import Flask
from flaskr.auth import ShowLoginPage, ShowLogoutPage, ShowRegisterPage
from flaskr.sca_tork_easycube_api import ShowActionsPage


def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    # a simple page that says hello
    @app.route('/hello')
    def hello():
        return 'Hello, World!'

    # https://flask.palletsprojects.com/en/1.1.x/tutorial/database/
    from . import db
    db.init_app(app)

    # https://flask.palletsprojects.com/en/1.1.x/tutorial/views/
    
    # /register /login /logout
    from . import auth
    app.register_blueprint(auth.bp)

    app.add_url_rule('/auth/login', view_func=ShowLoginPage.as_view('auth.login'))
    app.add_url_rule('/auth/logout', view_func=ShowLogoutPage.as_view('auth.logout'))
    app.add_url_rule('/auth/register', view_func=ShowRegisterPage.as_view('auth.register'))
    

    from . import sca_tork_easycube_api
    app.add_url_rule('/sca_tork_easycube_api/actions', view_func=ShowActionsPage.as_view('sca_tork_easycube_api.actions'))
    
    # index.html
    from . import index
    app.register_blueprint(index.bp)
    app.add_url_rule('/', endpoint='index')
    
    return app

the error message

  _____                               
  /  _   __________ _________   ____  
 /  /_  ___   /  |  _  __ _/ __  
/    |    /    /|  |  /|  | /  ___/ 
____|__  /_____ ____/ |__|    ___  >
        /      /                  / 

A P P   S E R V I C E   O N   L I N U X

Documentation: http://aka.ms/webapp-linux
Python 3.7.5
Note: Any data outside '/home' is not persisted
Starting OpenBSD Secure Shell server: sshd.
Site's appCommandLine: gunicorn --bind=0.0.0.0 --timeout 600 "flaskr:create_app()"
App will launch in debug mode
Launching oryx with: -debugAdapter ptvsd -debugPort 49494 -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite -bindPort 8000 -userStartupCommand 'gunicorn --bind=0.0.0.0 --timeout 600 "flaskr:create_app()"'
Oryx Version: 0.2.20200114.13, Commit: 204922f30f8e8d41f5241b8c218425ef89106d1d, ReleaseTagName: 20200114.13
Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it...
Build Operation ID: |4NuzYKKsZco=.40b8e078_
Writing output script to '/opt/startup/startup.sh'
Found virtual environment .tar.gz archive.
Removing existing virtual environment directory /antenv...
Extracting to directory /antenv...
Using packages from virtual environment antenv located at /antenv.
Updated PYTHONPATH to ':/antenv/lib/python3.7/site-packages'
[42] [INFO] Starting gunicorn 20.0.4
[42] [INFO] Listening at: http://0.0.0.0:8000 (42)
[42] [INFO] Using worker: sync
[45] [INFO] Booting worker with pid: 45
[45] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/opt/python/3.7.5/lib/python3.7/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/opt/python/3.7.5/lib/python3.7/site-packages/gunicorn/workers/base.py", line 119, in init_process
    self.load_wsgi()
  File "/opt/python/3.7.5/lib/python3.7/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/opt/python/3.7.5/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/opt/python/3.7.5/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
    return self.load_wsgiapp()
  File "/opt/python/3.7.5/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/opt/python/3.7.5/lib/python3.7/site-packages/gunicorn/util.py", line 358, in import_app
    mod = importlib.import_module(module)
  File "/opt/python/3.7.5/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 965, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'flaskr'
 [45] [INFO] Worker exiting (pid: 45)
 [42] [INFO] Shutting down: Master
 [42] [INFO] Reason: Worker failed to boot.

Advertisement

Answer

I had a similar error without Azure. Analyzing this issue, I suspected it was an importing issue related to Gunicorn. My solution was to append the missing directory path to the beginning of my entry application script (flaskr/init.py in your case):

import sys
sys.path.append('/src/flaskr')

I don’t know if it’s a good practice, but it worked for me. Hope it helps for you too.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement