I am in the midst of releasing a python package, and am confused about every aspect of packaging.
To start, my directory structure is as follows:
SamplePackage/
- setup.py
- README.rst
- LICENSE.rst
- sampledir/
-__init__.py
-sample.py
-utils.py
currently __init__ and setup are unpopulated. sample.py is the file that any user of the package would want to import. It contains the api in the form of different functions: foo1, foo2.
utils.py contains helper fictions for smaple.py. The latter contains a statement import utils
Any scripts placed under the sampledir directory can easily import sampleand use the fictions as sample.foo1(). Stepping out of this directory, I can call import sampledir, but not import sample, which is expected. So I need to do from sampledir import sample. This results in an error on the import utils line in sample.py
ImportError: No module named 'utils'
In some places I have seen import .utils for files in the same directory. But when I try that, it results in a syntax error.
Why can I not import sample.py from outside sampledir?
Also, what directory structure would allow users who have installed the package to simply be able to call import sample followed by sample.foo1(), and not have to do from sampledir import sample or import sampeldir.sample. For example, in using the HTTP library requests, one simply has to import it and call requests.get(url). requests.requests.get('url') is not required, like it is in urllib. What is the correct directory naming and arrangement to achieve that, if I want the package to be named sample?
First of all, I thing you've misunderstood what is difference between package and project. You directory structure should be something like this
Python package is "marked" by a presence of file
__init__.py. Python search on hisPYTHONPATHand seeks for all directories with file__init__.py(simply put, it's actually much more complicated). Those are packages that you can import during run-time.In our case, only
package_namedirectory will be installed somewhere toPYTHONPATH. Therefore, once installed (viasetup.pyanddisutilsorsetuptools), you can typeNow, you can call arbitrary class or function or whatever from any module in this package like
If you want to avoid typing
package_name.samplein you call, you can place this line in__init__.pyThe function
func1will be then put in your global name space during "import time". This happens whenimport package_nameis executed in your program. This mystery can be resolved by the fact that__init__.pyfile are executed every time package is imported.It is sometimes necessary to spit the structure even more. You can have "nested" packages (i.e. packages in package that you need to import). There are also namespace packages, where you can "spit" one package among more directories. The world is diverse. :)
Disclaimer
I wrote that without testing the code I provided. There might be small typos but I hope the story is more or less correct. Please, correct me if I'm wrong.