Forums

Import Error

.

2019-06-04 15:36:34,115: Error running WSGI application
2019-06-04 15:36:34,116: ImportError: cannot import name 'app' from 'run' (/home/zakton/Flask_Portfolio/run.py)
2019-06-04 15:36:34,116:   File "/var/www/www_zakton_com_wsgi.py", line 16, in <module>
2019-06-04 15:36:34,116:     from run import app as application  # noqa .  
2019-06-04 15:36:34,116: ***************************************************
2019-06-04 15:36:34,116: If you're seeing an import error and don't know why,
2019-06-04 15:36:34,116: we have a dedicated help page to help you debug: 
2019-06-04 15:36:34,116: https://help.pythonanywhere.com/pages/DebuggingImportError/

I have the above error. I have followed the debugging in https://help.../Debbugging/ImportError/. When entering python environment, I had the same error message 'cannot import name 'app' from 'run'. However, when I did 'from app import create_app' , it was ok. 'import app ... print('\n'.join(sys.path)) were also ok. 'python run.py' from bash with correct environment was also ok. Need help. Thank you.

[edit by admin: formatting]

Do you actually have something called 'app' in run.py? run.py will need to have a variable called app in it, defined at the top-level of the file for the import to be able to find it.

Yes, there is. Here's run.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env python
import os
from app import create_app, db
from app.models import User

if __name__ == '__main__':
    config_name = os.environ.get('FLASK_CONFIG') or 'development'
    print(' * Loading configuration "{0}"'.format(config_name))
    app = create_app(config_name)
    with app.app_context():
        db.create_all()
        if app.config['DEBUG'] and \
                User.query.filter_by(username='john').first() is None:
            User.register('john', 'cat')
    app.run()

The code inside that if statement will never be run on PythonAnywhere since that file is not run as a top level script. Have a look at our instruction here http://help.pythonanywhere.com/pages/Flask/ for using Flask on PythonAnywhere.

Added the following in run.py before if name == 'main'

from flask import Flask
app = Flask(__name__)

It still does not work with same error message in the log.

That sounds strange -- did you reload the website using the button on the "Web" page after making the code change to make it pick up the new code?

Either way, I'd suggest doing something like this in run.py instead, so that it's similar to your old code:

#!/usr/bin/env python
import os
from app import create_app, db
from app.models import User

config_name = os.environ.get('FLASK_CONFIG') or 'development'
print(' * Loading configuration "{0}"'.format(config_name))
app = create_app(config_name)

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        if app.config['DEBUG'] and \
                User.query.filter_by(username='john').first() is None:
            User.register('john', 'cat')
    app.run()

Hi, I made the change as suggested above, and now I am getting this error message:

2019-06-06 03:15:52,470: Error running WSGI application
2019-06-06 03:15:52,492: FileNotFoundError: [Errno 2] Unable to load configuration file (No such file or directory): '/home/zakton/config/development.py'
2019-06-06 03:15:52,493:   File "/var/www/www_zakton_com_wsgi.py", line 16, in <module>
2019-06-06 03:15:52,493:     from run import app as application  # noqa
2019-06-06 03:15:52,494: 
2019-06-06 03:15:52,494:   File "/home/zakton/Flask_Portfolio/run.py", line 8, in <module>
2019-06-06 03:15:52,495:     app = create_app(config_name)
2019-06-06 03:15:52,496: 
2019-06-06 03:15:52,496:   File "/home/zakton/Flask_Portfolio/app/__init__.py", line 19, in create_app
2019-06-06 03:15:52,496:     app.config.from_pyfile(cfg)
2019-06-06 03:15:52,496: 
2019-06-06 03:15:52,496:   File "/home/zakton/.virtualenvs/Flask_Portfolio/lib/python3.7/site-packages/flask/config.py", line 129, in from_pyfile
2019-06-06 03:15:52,497:     with open(filename, mode='rb') as config_file:
2019-06-06 03:15:52,497: ***************************************************
2019-06-06 03:15:52,497: If you're seeing an import error and don't know why,
2019-06-06 03:15:52,497: we have a dedicated help page to help you debug: 
2019-06-06 03:15:52,498: https://help.pythonanywhere.com/pages/DebuggingImportError/
2019-06-06 03:15:52,498: ***************************************************

I notice it's looking for '/home/zakton/config/development.py'. In my program the location of the py file is '/home/zakton/Flask_Portfolio/config/development.py'. I don't know what to change to make the program use the correct path. Please help.

What code are you using to set the value of the variable cfg before the line

app.config.from_pyfile(cfg)

...in /home/zakton/Flask_Portfolio/app/__init__.py?

Thanks for the guidance. I fixed the line setting up the value for cfg and it now works!

OK -- glad you worked it out! What was the solution, out of interest? It might be of value for other people with similar issues.

The line before:

app.config.from_pyfile(cfg):

previously, was:

cfg = os.path.join(os.getcwd(),  'config', config_name + '.py')

Then I changed it to:

cfg = os.path.join(os.getcwd(), 'Flask_Portfolio', 'config', config_name + '.py')

Flask_Portfolio is the folder name my project resides.

Thanks for the continuous support. I'm sticking with your service.

Ah, that would explain it. Another neat trick to use in things like that is to locate the file relative to the current Python script, rather than the current working directory (which is sometimes not what you might expect). The "magic" variable __file__ is always set to the filesystem location of the Python file it is in, so if you want to find a file relative to that, you can do something like this:

my_directory = os.path.dirname(os.path.abspath(__file__))
relative_config_file = os.path.join(my_directory, "config", config_name + ".py")

Using that, it will always locate the config file relative to your code.

Thanks for the suggestion, Giles. I tried your suggestion, however development.py resides in a path one level above the current path, i.e.

/home/zakton/Flask_Portfolio/config/development.py

Whereas with file, it gives the following:

/home/zakton/Flask_Portfolio/app/config/development.py

I would agree that it would have been better as it is not 'hardcoded' with the name of the project folder. I'm sticking with the hardcoded path assignment.

If you have something working, then yes, it's probably best not to change it :-)

But if you wanted, you could still use the non-hard-coded option, just adjusting it to go up one level like this:

my_directory = os.path.dirname(os.path.abspath(__file__))
relative_config_file = os.path.join(my_directory, "..", "config", config_name + ".py")

I followed your suggestion and it works! The non-hard-coded option is the right way. Thank you for patiently staying with me, Giles.