Why FileNotFound for method arguments inside main.py
I have this issue from the follow python project:
MyPackage
├──src
| ├──cust_function.py ----> class, functions
| ├──__init__.py
|
|--data --> folder where store raw or processed data
| |___init__.py
| |
|---config -> setup folder
| |-__init__.py
| |-config.json -> API parameters
|
└──main.py -> main file
So, in the cust_function.py I have some classes and methods, like with open(filepath)
def get_file(filepath):
with open(filepath, 'r') as file:
....
return ....
Now the issue come from main.py, if I send this request:
from src.cust_function import get_file
filepath = "config/config.json"
get_file(filepath)
The result is FileNotFoundError by config.json
I used os.path and sys.path in different ways and didn't work,
fpath = os.path.join(os.path.dirname(__file__), 'src', 'config')
sys.path.append(fpath)
and also I used
sys.path.append(project_name), and doesn't
Or I put same sys.path in __init__.py into config or src folder.
Of course, I tried directly in the same main.py and it works.
The idea is to understand how call methods and send arguments, like filepath, from main script and cust_function works fine.
Thanks.
Solution 1:
Adding non-python files to your packages is not that straight forward. You never know, from where your packages gets executed. Especially if you actually distribute the package later on. For local use, have a look at importlib. I use the following code:
from importlib import resources
import json
import config # your package
text = resources.read_text(config, "config.json")
conf = json.loads(text)
I assume you tweak sys.path to fix your imports? Is there a particular reason you use MyPackage
as a Namespace Package (no __init__.py
)? If you are working from the parent directory of MyPackage, you should be able to import all modules just fine using from MyPackage.src import cust_function
. No need to adjust sys.path
.
Else, if you want those sub packages to be separated (then MyPackage is a weird name for it not being a package), then being located in that directory should make all sub packages importable as is.
If you are located in an arbitrary location then you can export PYTHONPATH=PathToParentDirOfMyPackage
or export PYTHONPATH=PathToMyPackage
depending on the answer to the paragraphs above. Assuming you run on a Unix-based system (Linux, Mac) and in a shell.