Short version
Change it to:
sys.path.insert(0, os.path.realpath('./'))
from text_analysis.text_refinement import camel_case_split
Or:
sys.path.insert(0, os.path.realpath('./text_analysis'))
from text_refinement import camel_case_split
Long version
I have recreated your project structure on my machine and managed to make it work. Let's go step by step, so that we can figure out what's happening.
First of all, I see you're working on your project in PyCharm. It automatically adds a project root to PYTHONPATH
. You can read about this in detail in this thread. Since PyCharm takes care of path business for you, you do not really need
sys.path.insert(0, os.path.realpath('../text_analysis'))
for your code to run. The path will still be added, but it will not be used to locate the package. Try it on your machine. I think you will find it to be true. You can easily check out paths by running
for path in sys.path:
print(path)
While this is interesting information, it does not answer your question how to run it from a terminal. To understand why it is not run from the script, lets see what Python paths you would have upon executing the (slightly modified) commands in method-1:
sys.path.insert(0, os.path.realpath('../text_analysis'))
try:
from text_analysis.text_refinement import camel_case_split
camel_case_split()
except:
for path in sys.path:
print(path)
# output:
# ~/text_analysis (where ../text_analysis path points to)
# ~/social-network-interest-engine/social_networks (where your file is)
# ... (several other irrelevant paths) ...
We can see that '../text_analysis'
points one directory above what you need. What would happen if we deleted one of the full stops, and instead wrote './text_analysis'
? Output seems to be what we need:
# output:
# ~/social-network-interest-engine/text_analysis
# ~/social-network-interest-engine/social_networks
But we still have not imported the function. We know this because we reach the except
part, which prints the paths. Looking at import, we can see that we have text_analysis.text_refinement
. Do we really need to state the directory name if we already added it to the path? No, we do not. If we write
from text_refinement import camel_case_split
instead, we find that the function has finally been imported. Following this logic, and assuming we wanted to leave text_analysis.text_refinement
in import statement (for whatever reason), we could add path differently, too:
sys.path.insert(0, os.path.realpath('./'))
Note, however, that this way of inserting the path is somewhat brittle. The starting location is the path from which you call python python_file.py
If you navigated to different directory, you would need to adjust os.path.realpath
accordingly. What you can do instead:
sys.path.insert(0, 'full/path/to/application/app/folder')
Though this assumes that the directory/structure of your project will not change.
For a more in-depth overview of paths and imports, you can read more about importing stuff from different folders here, and if you prefer relative path imports, this is a useful thread. Of course, official documentation is also a good place to start.