Reputation:
I have a flask restful project with the following layout (file names changed for convenience)
myproject/
__init__.py
app.py
common/
__init__.py
util.py
foo/
__init__.py
main.py
utilities.py
foo/
is just a folder containing code for one of the API endpoints, I'm planning to add others in the future, for this reason I have common/util.py
file which contains reusable functions that I will use with other API endpoints.
foo/main.py
from flask_restful import Resource, request
from utilities import Analysis
class Foo(Resource):
def get(self):
pass
in foo/utilities.py
I have classes with methods that get some data, I import those classes to foo/main.py
to return JSON response
classes in foo/utilities.py
also uses some functions from common/util.py
but when I try to import something from common/util.py
to foo/utilities.py
I get import common.util
ModuleNotFoundError: No module named 'common'
What could be causing this? I tried importing various ways:
from common.util import my_func
from .common.util import my_func
from myproject.common.util import my_func
but none worked.
This is myproject/app.py
in case it matters:
from flask import Flask
from flask_restful import Api
from foo.main import Foo
app = Flask(__name__)
api = Api(app)
api.add_resource(Foo, '/Foo')
if __name__ == "__main__":
app.run()
I'm doing all of this in activated virtualenv if it matters
Upvotes: 3
Views: 8291
Reputation: 94755
from common.util import my_func
In Python 3 this is an absolute import, that is, the directory with common/
subdirectory must be in sys.path
. In your situation it's certainly a wrong approach.
from .common.util import my_func
This import expects common
to be a subdirectory of foo
which is also not the case.
from myproject.common.util import my_func
This is finally the best approach but for it to work the parent directory of myproject/
subdirectory must be in sys.path
. Either you install the entire myproject
or add the parent directory to $PYTHONPATH
environment variable or add the directory to sys.path
in foo/main.py
. Something like:
PYTHONPATH=/home/to/parentdir /home/to/parentdir/myproject/foo/main.py
or
import sys
sys.path.insert(0, '/home/to/parentdir')
/home/to/parentdir
is the directory where myproject/
is.
After installing myproject
or adding its parent directory to sys.path
you can also use relative import. You need to remember that common
is a sibling package comparing to foo
so the import must be not from .common
but from ..common
:
from ..common.util import my_func
Upvotes: 2