Relative Imports for two parents dir up - python-3.x

I have the following directory structure
code
|-----|--experiments
| |---v0
| |---agcnn.py
|-----|--pn
| |---bag
| |--run.py
run.py uses a module inside the agcnn.py. However when I try the import as following:
from experiments.v0.agccn import AG
it gives a relative import error saying no module. I'm using VScode and the the working dir is taken care by Vscode as root which is /code/ in this case.
How can I change the settings to accommodate the import ?

Related

Python ModuleNotFoundError while importing a module in conftest for Pytest framework

My project structure
mt-kart
|
--> src/data_kart
| |
| -->apis
| |
| -->__init__.py
| |
| -->main.py
--> tests
|
-->__init__.py
|
-->conftest.py
|
-->test_others.py
conftest.py has the following line.
from data_kart.main import fastapi_app
When run pytest from command line from project root(mt-kart). I get the following error
ModuleNotFoundError No module named 'data_kart'
How to make data_kart visible for conftest.py .
Option 1
Use relative imports:
from ..src.data_kart.main import fastapi_app
fastapi_app()
Please note, the above requires running conftest.py outside the project's directory, like this:
python -m mt-kart.tests.conftest
Option 2
Use the below in conftest.py (ref):
import sys
import os
# getting the name of the directory where the this file is present.
current = os.path.dirname(os.path.realpath(__file__))
# Getting the parent directory name where the current directory is present.
parent = os.path.dirname(current)
# adding the parent directory to the sys.path.
sys.path.append(parent)
# import the module
from src.data_kart.main import fastapi_app
# call the function
fastapi_app()
And if it happens for a module being outside the parent directory of tests, then you can get the parent of the parent direcory and add that one to the sys.path. For example:
parentparent = os.path.dirname(parent)
sys.path.append(parentparent)
Option 3
Same as Option 2, but shorter.
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from src.data_kart.main import fastapi_app
fastapi_app()
Option 4
Options 2 and 3 would work for smaller projects, where only a couple of files need to be updated with the code above. However, for larger projects, you may consider including the directory containing your package directory in PYTHONPATH, as described here (Option 3).

Acessing myclass defined in python file in different folder from jupyter notebook

I have following folder structure
|
|---notebook
| |
| --- MyNoteBook.ipnyb
|
|---python
| |
| --- image_rotation_utils.py
I have following content in python.image_rotation_utils.py
class ImageRotationUtils:
""" Utils for rotating images."""
def __init__(self, image_path=None, image_name=None, output_path=None, output_annotations_file=None ):
""" Initializes the class.
Args:
image_path: the relative path to the image
image_name: image file name
output_path: the relative path where rotated output file is stored.
output_annotations_file: annotations file where rotated anotations are stored.
"""
self.image_path = image_path
self.image_name = image_name
self.output_path = output_path
self.output_annotations_file = output_annotations_file
#other functions defined
Now in MyNoteBook.ipnyb I have following cells
Cell 1:
import sys
sys.path.insert(0, '..')
from python.image_rotation_utils import *
Above is executed successfully now in cell 2 I have below
myUtils = ImageRotationUtils()
I have getting below error
----> 1 ImageRotationUtils()
TypeError: __init__() missing 4 required positional arguments: 'image_path', 'image_name', 'output_path', and 'output_annotations_file'
whye I am getting this error when I have default values in constructor has None in class definition.
I am new to python and trying to put code in productive manner. What mistake I am making. Kindly provide inputs
What you pasted looks ok to me, and your code works for me without errors.
Perhaps something before or after that code is what is spoiling the class definition?
Perhaps you are running this in Jupyter or in IPython and you imported ImageRotationUtils previously, but then changed the code, and tried to reimport again -- and something was wrong with the new reimport so your definition did not get over-written? If that's the case, restart the environment (or the kernel in Jupyter) and rerun the code.
I would suggest putting a simple initialization code, like that constructor line, into the same source file and executing it as a separate process to test if that is the code or the environment issue.
As a matter of convenience and to avoid tweaking sys.path in your code, I would suggest adding your python directory to the PYTHONPATH environment variable before you load your environment, so you can just import.

How to get a real path of a Python file in Project Directory

I am using an Automation project with following structure
C:\Project_Name\Scripts
Under script folder, I have my python automation modules, libraries and other required data folders.
But I want this project not only restricted to C: drive. I should seamlessly able to execute by scripts from any drive, any parent directory of "Project_Name" folder.
I have tried the following. But it is always not true if I try to trigger my test from jenkins.
os.path.join(os.path.dirname(os.path.abspath(__file__)))
Think about this tree:
Project
|
|--Scripts
| |
| |--__init__.py
| |--use_text.py
| |--text.txt
|
|--run_me.py
and imagine we have to get text.txt path in use_text.py
Step 1. in run_me.py get the path of project directory, and save it as a environ using os. (example:)
import os
from pathlib import Path
path = Path(__file__).parent # replace it with your preferred library's version
os.environ['PROJECT_BASE_DIR'] = str(path)
from Scripts.use_text import use
use()
now in use_text.py
import os
text_path = 'Scripts/text.txt'
project_path = os.getenv('PROJECT_BASE_DIR')
text_real_path = os.path.join(project_path, text_path)
def use():
# do whatever you want with text_real_path
I got a way to get the real path of the file no matter where the project directory been placed.
import os
os.path.join((os.path.realpath(__file__)).split("<Base Directory Name>")[0], "<relative path till the file>")
this worked as well, with simple path.

Unable to use module in local folder

I am attempting to create an API wrapper but I am unable to use the wrapper. My __init__.py
from .sb import Skyblock
The folder that contains the module is called skyblock and the file with the Skyblock class is called sb.py
The file I'm trying to use the module in contains this code
from skyblock import *
set_api_key('49baa0d9-ecf3-430d-8669-c08495664889')
uuid = uname_resolver('Metasploitable')
print(get_news())
I am getting an undefined error
Here's the directory structure
C:.
| requirements.txt
| testing.py
|
\---skyblock
| sb.py
| __init__.py
|
\---__pycache__
sb.cpython-37.pyc
__init__.cpython-37.pyc
You are using relative import, so you need to import as
from .skyblock import *
You can refer to this site for more information: PEP-328

using relative paths without packages

Several questions have been posted on the topic of relative paths in python, and it looks like this continues to be a fairly confusing topic, and no final word mentioned on it. I had found the most illustrative example in https://github.com/wweiradio/pkg-relative-import
However, when I made a few changes to those files, I ended up again with some error messages. After some amount of debugging, I came up with the following files and directory structure which works. (In the hierarchy mentioned below, I have mentioned the imports in each file, and which imports work and which dont.)
NOTE: (1) the code works, whether or not __init__.py files exist. So I have deleted all those files. (2) the files mentioned contain only the mentioned import lines, and maybe some print statements, and nothing else.
I run the code as:
cd top_level; python3 start1.py --> this works
cd top_level/src; python3 start2.py --> this does not work, as expected
I learnt the following lessons from this exercise:
(1) no relative paths on the invocation directory is allowed, or anywhere outside it.
(2) any further imports should be explicitly relative (eg .sub3, and not sub3),
or absolute with reference to the top level (eg src.sub2.sub3)
(3) relative paths have nothing to do with packages, nor the presence or absence of __init__.py.
eg, in the below code I have deleted all init.py, and it still works
(4) current dir is ., its parent is .., its grandparent is ..., etc
Can you confirm if these lessons are correct, and are there some other factors that I need to remember while using relative paths?
directory structure:
- top_level/
- top.py
- start1.py --> import src.sub.relative
- src/
- parent.py
- start2.py --> import sub.relative
- sub/
- relative.py --> from .. import parent
from ..sub2 import relative2
# these imports give error if start2.py is called
# this is understood, so we call only start1.py
- sub2/
- relative2.py --> import top
from .. import parent
#from sub3 import relative3 # --> doesnt work
from .sub3 import relative3 # --> works
from src.sub2.sub3 import relative3 # --> works
#import sub3.relative3 # --> doesnt work
import src.sub2.sub3.relative3 # --> works
- sub3/
- relative3.py --> import top
from ... import parent

Resources