I am trying to make a stand-alone application in Python and there are some problems related to imports and the project's directory structure that I do not how to solve.
This is how the project is structured:
root/
app/
__init__.py
main.py
foo.py
tests/
__init__.py
main_tests.py
foo_tests.py
These are the two conflicting requirements which I don't know how to solve:
The tests are written using the Nose framework. When I run nosetests
from the root
directory, it requires all imports to be relative to the app
package.
# app/main.py
import app.foo # `import foo` will not work
On the other hand, if I want to run the application from root
(with a command like python app/main.py
), another problem occurs. It will rightly complain that it cannot find the app
package.
How can I fix these problems? Is there anything I need to change in how I organized my project?
You should have a setup.py
; in the setup.py
you should have:
setup(
...
scripts = ['bin/run_my_app']
...
)
and bin/run_my_app
then a script with content:
#!/usr/bin/env python
from app.main import main
main()
Now when you run python setup.py develop
or python setup.py install
, the setuptools
/distribute
will install the command line script run_my_app
into your path. The python setup.py develop
makes it possible to not need to reinstall the package to virtualenv after each change to the source code; you need to rerun setup.py develop
only after changes to the setup.py
itself, or any of the possible C language extension modules in your package.
Alternatively run your main module with
python -m app.main
Especially do not try to run an application from within the package with python app/main
, as it never was supposed to work like that.
For developing the code, you'd have a virtualenv, then you can use python setup.py develop
to link the code into the virtualenv; a special link is installed into the site-packages
that points to the source code of your application, thus you can develop it in place, but it behaves as if it was installed into the site-packages
.