1

Consider the following file structure:

root
|- app
|  |- api { ... }
|  |- logic { ... }
|  |- models { ... }
|  |- schema { ... }
|  |- __init__.py
|  |- config.py
|  |- sql_alchemy.py
|  |- utils.py
|- docker-compose.yml
|- Dockerfile
|- main.py
|- Pipfile
|- Pipfile.lock
|- README.md
|- uwsgi.ini

docker-compose.yml:

version: '3'

services:
    app:
        restart: always
        build: .
        depends_on:
            - db
        expose:
            - "5000"
        ports:
            - "5000:5000"
    db:
        restart: always
        image: "mysql:5.7.22"
        expose:
            - "3306"
        ports:
            - "3306:3306"
        environment:
            - MYSQL_ALLOW_EMPTY_PASSWORD=yes
            - MYSQL_DATABASE=philipsonska
        volumes:
            - ./data:/var/lib/mysql

Dockerfile:

FROM tiangolo/uwsgi-nginx-flask:python3.7

COPY ./app /app/app
COPY main.py uwsgi.ini /app/
COPY Pipfile Pipfile.lock /

RUN pip3 install pipenv==10.1.2
RUN pipenv install --three --system

main.py:

from app import create_app

if __name__ == '__main__':
    app = create_app()

    app.run('0.0.0.0', 5000, False)

uwsgi.ini:

[uwsgi]
module = main
callable = app

app/__init__.py:

from flask import Flask
from flask_cors import CORS
from flask_jwt import JWT

from app.api import Api
from app.config import Config
from app.sql_alchemy import SQLAlchemy


db = SQLAlchemy()
jwt = JWT()
cors = CORS(supports_credentials=True)
api = Api()


def create_app(arg1,arg2) -> Flask:
    from app.logic import AuthLogic

    app = Flask(__name__)
    app.config.from_object(Config)

    jwt.identity_callback = AuthLogic.identity
    jwt.authentication_callback = AuthLogic.auth
    jwt.request_callback = AuthLogic.request
    jwt.auth_response_callback = AuthLogic.response

    api.init_app(app)
    db.init_app(app)
    jwt.init_app(app)
    cors.init_app(app)

    return app

My problem is that when I run docker-compose up --build I get the following error: unable to load app 0 (mountpoint='') (callable not found or import error)

The full output:

app_1  | /usr/lib/python2.7/dist-packages/supervisor/options.py:298: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
app_1  |   'Supervisord is running as root and it is searching '
app_1  | 2019-06-26 13:06:09,439 CRIT Supervisor running as root (no user in config file)
app_1  | 2019-06-26 13:06:09,439 INFO Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
app_1  | 2019-06-26 13:06:09,451 INFO RPC interface 'supervisor' initialized
app_1  | 2019-06-26 13:06:09,451 CRIT Server 'unix_http_server' running without any HTTP authentication checking
app_1  | 2019-06-26 13:06:09,452 INFO supervisord started with pid 1
app_1  | 2019-06-26 13:06:10,454 INFO spawned: 'nginx' with pid 9
app_1  | 2019-06-26 13:06:10,458 INFO spawned: 'uwsgi' with pid 10
app_1  | [uWSGI] getting INI configuration from /app/uwsgi.ini
app_1  | [uWSGI] getting INI configuration from /etc/uwsgi/uwsgi.ini
app_1  |
app_1  | ;uWSGI instance configuration
app_1  | [uwsgi]
app_1  | cheaper = 2
app_1  | processes = 16
app_1  | ini = /app/uwsgi.ini
app_1  | module = main
app_1  | callable = app
app_1  | ini = /etc/uwsgi/uwsgi.ini
app_1  | socket = /tmp/uwsgi.sock
app_1  | chown-socket = nginx:nginx
app_1  | chmod-socket = 664
app_1  | hook-master-start = unix_signal:15 gracefully_kill_them_all
app_1  | need-app = true
app_1  | die-on-term = true
app_1  | show-config = true
app_1  | ;end of configuration
app_1  |
app_1  | *** Starting uWSGI 2.0.18 (64bit) on [Wed Jun 26 13:06:10 2019] ***
app_1  | compiled with version: 6.3.0 20170516 on 16 May 2019 04:09:50
app_1  | os: Linux-4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018
app_1  | nodename: 8119f4e0b5b1
app_1  | machine: x86_64
app_1  | clock source: unix
app_1  | pcre jit disabled
app_1  | detected number of CPU cores: 2
app_1  | current working directory: /app
app_1  | detected binary path: /usr/local/bin/uwsgi
app_1  | your memory page size is 4096 bytes
app_1  | detected max file descriptor number: 1048576
app_1  | lock engine: pthread robust mutexes
app_1  | thunder lock: disabled (you can enable it with --thunder-lock)
app_1  | uwsgi socket 0 bound to UNIX address /tmp/uwsgi.sock fd 3
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | Python version: 3.7.3 (default, May  8 2019, 05:28:42)  [GCC 6.3.0 20170516]
app_1  | *** Python threads support is disabled. You can enable it with --enable-threads ***
app_1  | Python main interpreter initialized at 0x55dbdc52de70
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | your server socket listen backlog is limited to 100 connections
app_1  | your mercy for graceful operations on workers is 60 seconds
app_1  | mapped 1239640 bytes (1210 KB) for 16 cores
app_1  | *** Operational MODE: preforking ***
app_1  | unable to load app 0 (mountpoint='') (callable not found or import error)
app_1  | *** no app loaded. GAME OVER ***
app_1  | 2019-06-26 13:06:10,983 INFO exited: uwsgi (exit status 22; not expected)
app_1  | 2019-06-26 13:06:11,985 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
app_1  | 2019-06-26 13:06:11,987 INFO spawned: 'uwsgi' with pid 12
app_1  | [uWSGI] getting INI configuration from /app/uwsgi.ini
app_1  | [uWSGI] getting INI configuration from /etc/uwsgi/uwsgi.ini
app_1  |
app_1  | ;uWSGI instance configuration
app_1  | [uwsgi]
app_1  | cheaper = 2
app_1  | processes = 16
app_1  | ini = /app/uwsgi.ini
app_1  | module = main
app_1  | callable = app
app_1  | ini = /etc/uwsgi/uwsgi.ini
app_1  | socket = /tmp/uwsgi.sock
app_1  | chown-socket = nginx:nginx
app_1  | chmod-socket = 664
app_1  | hook-master-start = unix_signal:15 gracefully_kill_them_all
app_1  | need-app = true
app_1  | die-on-term = true
app_1  | show-config = true
app_1  | ;end of configuration
app_1  |
app_1  | *** Starting uWSGI 2.0.18 (64bit) on [Wed Jun 26 13:06:11 2019] ***
app_1  | compiled with version: 6.3.0 20170516 on 16 May 2019 04:09:50
app_1  | os: Linux-4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018
app_1  | nodename: 8119f4e0b5b1
app_1  | machine: x86_64
app_1  | clock source: unix
app_1  | pcre jit disabled
app_1  | detected number of CPU cores: 2
app_1  | current working directory: /app
app_1  | detected binary path: /usr/local/bin/uwsgi
app_1  | your memory page size is 4096 bytes
app_1  | detected max file descriptor number: 1048576
app_1  | lock engine: pthread robust mutexes
app_1  | thunder lock: disabled (you can enable it with --thunder-lock)
app_1  | uwsgi socket 0 bound to UNIX address /tmp/uwsgi.sock fd 3
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | Python version: 3.7.3 (default, May  8 2019, 05:28:42)  [GCC 6.3.0 20170516]
app_1  | *** Python threads support is disabled. You can enable it with --enable-threads ***
app_1  | Python main interpreter initialized at 0x556f78d61e70
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | your server socket listen backlog is limited to 100 connections
app_1  | your mercy for graceful operations on workers is 60 seconds
app_1  | mapped 1239640 bytes (1210 KB) for 16 cores
app_1  | *** Operational MODE: preforking ***
app_1  | unable to load app 0 (mountpoint='') (callable not found or import error)
app_1  | *** no app loaded. GAME OVER ***
app_1  | 2019-06-26 13:06:12,496 INFO exited: uwsgi (exit status 22; not expected)
app_1  | 2019-06-26 13:06:14,501 INFO spawned: 'uwsgi' with pid 13
app_1  | [uWSGI] getting INI configuration from /app/uwsgi.ini
app_1  | [uWSGI] getting INI configuration from /etc/uwsgi/uwsgi.ini
app_1  |
app_1  | ;uWSGI instance configuration
app_1  | [uwsgi]
app_1  | cheaper = 2
app_1  | processes = 16
app_1  | ini = /app/uwsgi.ini
app_1  | module = main
app_1  | callable = app
app_1  | ini = /etc/uwsgi/uwsgi.ini
app_1  | socket = /tmp/uwsgi.sock
app_1  | chown-socket = nginx:nginx
app_1  | chmod-socket = 664
app_1  | hook-master-start = unix_signal:15 gracefully_kill_them_all
app_1  | need-app = true
app_1  | die-on-term = true
app_1  | show-config = true
app_1  | ;end of configuration
app_1  |
app_1  | *** Starting uWSGI 2.0.18 (64bit) on [Wed Jun 26 13:06:14 2019] ***
app_1  | compiled with version: 6.3.0 20170516 on 16 May 2019 04:09:50
app_1  | os: Linux-4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018
app_1  | nodename: 8119f4e0b5b1
app_1  | machine: x86_64
app_1  | clock source: unix
app_1  | pcre jit disabled
app_1  | detected number of CPU cores: 2
app_1  | current working directory: /app
app_1  | detected binary path: /usr/local/bin/uwsgi
app_1  | your memory page size is 4096 bytes
app_1  | detected max file descriptor number: 1048576
app_1  | lock engine: pthread robust mutexes
app_1  | thunder lock: disabled (you can enable it with --thunder-lock)
app_1  | uwsgi socket 0 bound to UNIX address /tmp/uwsgi.sock fd 3
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | Python version: 3.7.3 (default, May  8 2019, 05:28:42)  [GCC 6.3.0 20170516]
app_1  | *** Python threads support is disabled. You can enable it with --enable-threads ***
app_1  | Python main interpreter initialized at 0x55d7a1bc2e70
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | your server socket listen backlog is limited to 100 connections
app_1  | your mercy for graceful operations on workers is 60 seconds
app_1  | mapped 1239640 bytes (1210 KB) for 16 cores
app_1  | *** Operational MODE: preforking ***
app_1  | unable to load app 0 (mountpoint='') (callable not found or import error)
app_1  | *** no app loaded. GAME OVER ***
app_1  | 2019-06-26 13:06:14,848 INFO exited: uwsgi (exit status 22; not expected)
app_1  | 2019-06-26 13:06:17,856 INFO spawned: 'uwsgi' with pid 14
app_1  | [uWSGI] getting INI configuration from /app/uwsgi.ini
app_1  | [uWSGI] getting INI configuration from /etc/uwsgi/uwsgi.ini
app_1  |
app_1  | ;uWSGI instance configuration
app_1  | [uwsgi]
app_1  | cheaper = 2
app_1  | processes = 16
app_1  | ini = /app/uwsgi.ini
app_1  | module = main
app_1  | callable = app
app_1  | ini = /etc/uwsgi/uwsgi.ini
app_1  | socket = /tmp/uwsgi.sock
app_1  | chown-socket = nginx:nginx
app_1  | chmod-socket = 664
app_1  | hook-master-start = unix_signal:15 gracefully_kill_them_all
app_1  | need-app = true
app_1  | die-on-term = true
app_1  | show-config = true
app_1  | ;end of configuration
app_1  |
app_1  | *** Starting uWSGI 2.0.18 (64bit) on [Wed Jun 26 13:06:17 2019] ***
app_1  | compiled with version: 6.3.0 20170516 on 16 May 2019 04:09:50
app_1  | os: Linux-4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018
app_1  | nodename: 8119f4e0b5b1
app_1  | machine: x86_64
app_1  | clock source: unix
app_1  | pcre jit disabled
app_1  | detected number of CPU cores: 2
app_1  | current working directory: /app
app_1  | detected binary path: /usr/local/bin/uwsgi
app_1  | your memory page size is 4096 bytes
app_1  | detected max file descriptor number: 1048576
app_1  | lock engine: pthread robust mutexes
app_1  | thunder lock: disabled (you can enable it with --thunder-lock)
app_1  | uwsgi socket 0 bound to UNIX address /tmp/uwsgi.sock fd 3
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | Python version: 3.7.3 (default, May  8 2019, 05:28:42)  [GCC 6.3.0 20170516]
app_1  | *** Python threads support is disabled. You can enable it with --enable-threads ***
app_1  | Python main interpreter initialized at 0x561dc7635e70
app_1  | uWSGI running as root, you can use --uid/--gid/--chroot options
app_1  | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
app_1  | your server socket listen backlog is limited to 100 connections
app_1  | your mercy for graceful operations on workers is 60 seconds
app_1  | mapped 1239640 bytes (1210 KB) for 16 cores
app_1  | *** Operational MODE: preforking ***
app_1  | unable to load app 0 (mountpoint='') (callable not found or import error)
app_1  | *** no app loaded. GAME OVER ***
app_1  | 2019-06-26 13:06:18,201 INFO exited: uwsgi (exit status 22; not expected)
app_1  | 2019-06-26 13:06:19,202 INFO gave up: uwsgi entered FATAL state, too many start retries too quickly

According to Flask and uWSGI - unable to load app 0 (mountpoint='') (callable not found or import error) I should change from app import create_app to from app import create_app as application, remove callable = app from uwsgi.ini and change to application().run(...). I tried that, and it worked so far as the server was able to start. I did the following in main.py:

from app import create_app as application

if __name__ == '__main__':
    application = application()

    application.run('0.0.0.0', 5000, True)

Now I get another error when trying to use an endpoint, TypeError: create_app() takes 0 positional arguments but 2 were given

I don't know how to proceed. Any ideas?

BluePrint
  • 1,926
  • 4
  • 28
  • 49

3 Answers3

4

With

[uwsgi]
module = main
callable = app

uwsgi will import main, extract app from within it, expecting app to be an instance of a WSGI application. An instance of Flask is a WSGI application. A standard way of doing this within the structure you're using is

from app import create_app

app = create_app()

The code you posted isn't calling create_app() when using uwsgi, because main.py is being imported. And when you are actually calling create_app(), you'll need to remove the unused arg1 and arg arguments from the definition.

Doing

from app import create_app as application

confuses things, especially if at one point you'd tried callable = application.

Dave W. Smith
  • 24,318
  • 4
  • 40
  • 46
  • From your solution I was able to figure out that I should move `app = create_app()` outside (above) `if __name__ == '__main__':`, and then it worked (when I removed `arg1,arg2`). Many thanks. – BluePrint Jun 27 '19 at 08:14
0

can you try changing uwsgi.ini to

[uwsgi]
module = main
callable = app.app
gCoh
  • 2,719
  • 1
  • 22
  • 46
  • 1
    That didn't work unfortunately, I still got `unable to load app 0 (mountpoint='') (callable not found or import error)` – BluePrint Jun 26 '19 at 14:30
  • uwsgi is looking for 'app' object not 'application', it is created in your main.py file, try changing it to main.app – gCoh Jun 26 '19 at 14:39
  • `main.py` looks like it did originally, `app = create_app()` and `app.run('0.0.0.0', 5000, False)`. Where should I change to `main.app`? I tried changing to `callable = main.app` but it didn't work. – BluePrint Jun 26 '19 at 14:49
0

For people that are running uwsgi + Docker and have run into the unable to load app 0 callable not found error, try changing the "app" folder name to "application" if it's not absolutely critical to have the folder name as "app"

I've just spent 2 days trying to reorganise our code repo structure and our internal Docker structure. This was the last issue I had to tackle and it was pretty frustrating one to resolve.

uWSGI is looking for a folder called "application" by default, as per documentation here:

I messed around with uwsgi.ini settings (callable, chdir), but none worked for me. I've also tried some of the suggestions above but it didn't work for me either.

In case changing the name to application doesn't work, try setting the PYTHONPATH environment variable as well. Depending on your directory structure of your project, you may need to give Python's Loading mechnaism some help in determining where to look for files. This was the other major issue that I had to resolve earlier in the process.

I had mine set in docker-compose.yml. I couldn't get it to work in dockerfile. I believe you can set in uwsgi.ini but I never tried it myself.

I've listed my configurations. Hopefully there's enough in here to steer people in the right direction.

Example Configuration:

    Our Directory structure (Docker):
    application/
       {Component}/
       Common/

    uwsgi.ini:
    [uwsgi]
        module = main
        callable = application/{Component}

    docker-compose.yml:
        {Component}:
            environment:
               PYTHONPATH: /application/{Component}:/application/Common:/application             

    main.py:
        if __name__ == '__main__':
           app.run(<Your App Run Arguments>)
        else:
           application = app
Francis
  • 1,798
  • 1
  • 26
  • 32