Flask suggests the following file layout:
runflaskapp.py
flaskapp/
__init__.py
runflaskapp.py contains:
from flaskapp import app
app.run(debug=True)
flaskapp/init.py contains:
from flask import Flask
app = Flask(__name__)
Running this with 'python3 runflaskapp.py' works fine. However it
seems to me that a more Python3onic way of doing this would be to
rename 'runflaskapp.py' as 'flaskapp/main.py' and then run
the whole thing as 'python3 -m flaskapp'. Unfortunately this doesn't
work:
$ python3 -m flaskapp
* Running on http://127.0.0.1:5000/
* Restarting with reloader
Traceback (most recent call last):
File "/home/username/src/flaskapp/__main__.py", line 1, in <module>
from flaskapp import app
ImportError: No module named 'flaskapp'
Does anyone know why and how to fix it?
The -m flag does this:
Search sys.path for the named module and execute its contents as the __main__ module… When a package name is supplied instead of a normal module, the interpreter will execute <pkg>.__main__ as the main module.
In other words, flaskapp is not imported as flaskapp, but as __main__, just like a script would be, and then its __main__ module gets executed.
This means from flaskapp import app will not work, because there is nothing named flaskapp.
But the relative import from . import app will. So, as long as there are no absolute imports anywhere in flaskapp except in your new __main__.py file, that one-liner should do it.
Related
I thought I had understood the import system, however I'm struggling to understand an apparently trivial case: I have a very simple Python application with the following structure:
.
└── myapp
├── __init__.py
├── lib.py
└── myapp.py
The content of lib.py is a trivial function:
def funct():
print("hello from function in lib")
myapp.py is supposed to be the entrance point of the application:
import lib
def main():
lib.funct()
if __name__ == "__main__":
print("calling main")
main()
When I run the main script it works:
> python myapp/myapp.py
calling main
hello from function in lib
However, when I just import the package from IPython for instance, it fails:
In [2]: import myapp
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-2-cabddf3cb27d> in <module>
----> 1 import myapp
~/test/myapp/__init__.py in <module>
----> 1 import myapp.myapp
~/test/myapp/myapp.py in <module>
----> 1 import lib
2
3
4 def main():
5 lib.funct()
ModuleNotFoundError: No module named 'lib'
Why is this happening? Eventually, I'd like that my application is executable with python -m myapp, but also importable.
By default the import searches for module on the paths present in sys.path and one of the path present there is of current directory so
when you executed the main script:
python myapp/myapp.py
The import in myapp.py file searched for lib module in its current directory i.e "myapp" and as lib.py is in same directory, it executed perfectly
But when you imported myapp as a package in IPython,
The import in myapp.py file searches from IPython's path, where Lib.py is not present hence the classic no module found.
There are few things you can do here
use relevant path in myapp.py like
from . import lib
Note: This will generate error if you executed myapp.py directly as a script so handle accordingly
update the sys.path by appending lib.py's path (Not Recommended)
sys.path.append("....../lib.py")
watch this for clear understanding.
Also just to point out, __name__=="__main__" is only true when you execute the file directly. so the code inside if in myapp.py will not work when you'll use it as a module in package.
I hope this was helpful :)
My directory structure is:
project_folder/
..my_project/
....server/
......server.py
......api.py
When I'm in the project_folder and run python3 my_project/server/server.py, I get ModuleNotFoundError: No module named 'my_project' with the line of code:
from my_project.server.api import app as application
Weirdly, when I run my tests with Pytest everything passes. I've been trying to solve my problem without using this code snippet, which I always see recommended to solve these problems:
import sys
from os import path
sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
Any tips?
The module you try to call is already in the same package, so just do
from api import app as application
Add an empty __init__.py file in my_project and server folders.
run this cd my_project/server/ and then python server.py
Or remove this line from server.py import my_project
And if you are trying to make a module add __init__.py to your server dir
I am having trouble running my run.py file. My file structure looks like this:
With another python file called 'run.py' located in flask/bin along with python3. My run.py file is simply:
#!flask/bin/python3
from app import app
app.run(debug=True)
However running 'python3 run.py' throws the error:
$ python3 run.py
Traceback (most recent call last):
File "run.py", line 2, in <module>
from app import app
ModuleNotFoundError: No module named 'app'
app.py looks like:
from flask import Flask
app = Flask(__name__)
from app import views
I am confused about how to solve this as I have been messing with the directories such as putting app.py into the flask/bin folder and putting it outside of all folders shown in my directory above, but these methods have not worked for me.
your run.py is not able to import app as it can not see app within the bin folder, what happens with python is that all python files are treated as modules and the folders with an init.py file are treated as packages so run.py will start looking for the app package to import the app module however it will search within the bin directory. Read through Python documentation to fully understand the modules and packages. for now you might want to reorganize your application directory to look like this:
dir app
file app.py
dir flask
file run.py
By ensuring that run.py and app directory are at the same level in the directory run.py will be able to import from app now.
I hope that helps
I'm trying to restructure a flask app to a package based on http://flask.pocoo.org/docs/0.10/patterns/packages/. My app is based on http://code.tutsplus.com/tutorials/intro-to-flask-signing-in-and-out--net-29982 . I've now changed it to the screenshot above and am trying to run at command line.
runserver.py:
from app import intro_to_flask
if __name__ == '__main__':
intro_to_flask.routes.run(debug=True)
At the command line:
/mini/app (master) $ python runserver.py
Traceback (most recent call last):
File "runserver.py", line 1, in <module>
from app import intro_to_flask
ImportError: No module named app
What am I doing wrong?
Since the Flask documentation mentions only one __init__.py file in the subdirectory with the Flask application and you have two of them, I think you're confused by the __init__.py file and the usage of imports. In your case the subdirectory with the Flask application is intro_to_flask.
Basically it works like this: from <module> import <object>
The module is a .py file and the object is defined inside the module. In this special case there is a __init__.py file so the module you have to reference to has the name of the directory that contains the __init__.py file.
Assuming your app/intro_to_flask/__init__.py looks like this:
from flask import Flask
app = Flask(__name__)
import intro_to_flask.routes
Your app/runserver.py should look like this:
from intro_to_flask import app
app.run(debug=True)
intro_to_flask is the imported module, app is a public object defined inside the imported module.
I believe you're looking for from intro_to_flask import app if I read the links you posted correctly, and assuming you've setup __init__.py correctly inside the intro_to_flask folder.
I have the project structure:
/hdfs-archiver
/logs
/qe
__init__.py
/tests
__init__.py
archiver.py
/utils
__init__.py
HdfsConnector.py
I am trying to run archiver.py but I am getting this error:
Traceback (most recent call last):
File "qe/tests/HdfsArchiver.py", line 8, in <module>
from qe.utils import HdfsConnector
ImportError: No module named qe.utils
I read around and it seemed like most people that come across this issue fixed it with __init__.py
when I pwd:
$ pwd
/Users/bli1/Development/QE/idea/hdfs-archiver
my PYTHONPATH in .bashrc
export PYTHONPATH=$PYTHONPATH:/Users/bli1/Development/QE/idea/hdfs-archiver
I also tried having my PYTHONPATH as
/Users/bli1/Development/QE/idea/hdfs-archiver/qe
You're trying to import HdfsConnector as a function or class. Include the HdfsConnector module as part of your absolute import:
from qe.utils.HdfsConnector import my_function
You can also import the module:
import qe.utils.HdfsConnector
# or
import qe.utils.HdfsConnector as HdfsConnector
Firstly, you could try a relative import such as
from ..utils import HdfsConnector
You'd also need to run the script as a module and not as a simple python script due to the __name__ being different. This wouldn't require you to modify the path.
You can find more info here.