Importing class from another package - python

I have the following directory structure:
F:.
│ .gitignore
│
└───Tests
│ main.py
│ __init__.py
│
├───compare
│ │ __init__.py
│ │
│ └───process
│ process.py
│ __init__.py
│
├───lookup
│ User.py
│ __init__.py
│
├───requestor
│ Requestor.py
│ __init__.py
│
├───search
│ UserSearch.py
│ ProductSearch.py
│ __init__.py
│
└───utils
constants.py
__init__.py
I am able to import any file/class from main.py like
from search.UsersSearch import UsersSearchPayLoad
from search.ProductSearch import ProductSearchPayLoad
from utils.constants import *
but I cannot do any import from any other package like, from search.UserSearch:
from ..utils.constants import *
from Tests.utils.constants import *
I was referring this for understanding the correct way to use relative imports.
I am using Python 2.7.11

Try adding:
import os
import sys
sys.path.append(os.path.realpath(os.getcwd()))
In:
Tests/__init__.py

For the latest phython Version e.g 3.7.0
from directory import class-name
A directory is your folder structure. It could be subDirectory\directory

Related

Why main.py folder works well when importing modules but others folders don't and throw errors? (Directory provided)

I'm facing some issues concerning with the project directory. I had some more before, but resolved them at flask importerror no module named flask fyi.
Please note that I'm using flask, flask-wtf, and wtforms.
After *** is the error thrown by console when that module is executed.
Below every python module, are every other modules imported. Something is happening with the register_ig folder apparently.
This is my current directory:
.
└── flask_app
├── __pycache__
│
├── .vscode
│
├── data
│ └── transactions.sqlite
│ |
├── flask <--- venv
│ │
├── register_ig
│ ├── __pycache__
│ |
│ └── static
│ | |
│ | ├── css
│ | | ├── pico.min.css
│ | | └── style.css
│ | |
│ | └── images
│ | | ├── picture.svg
│ | | ├── Logo.svg
│ | | ├── Favicon.ico
│ | | └── transparent.png
│ | |
│ ├── templates
│ | ├── base.html
│ | ├── index.html
│ | ├── purchase.html
│ | └── status.html
│ |
│ ├── __init__.py *** ModuleNotFoundError: No module named 'register_ig'
│ │ from flask import Flask
│ │
│ ├── connection.py
│ │ import sqlite3 as sql
│ │ from config import *
│ │
│ ├── forms.py *** ModuleNotFoundError: No module named 'register_ig'
│ │ from flask_wtf import FlaskForm
│ │ from wtforms import SelectField, StringField, SubmitField, DateField
│ │ from wtforms.validators import DataRequired
│ │ from register_ig.models import Exchange
│ │
│ ├── models.py *** ModuleNotFoundError: No module named 'register_ig'
│ │ from connection import *
│ │ import requests
│ │ from flask import redirect, url_for
│ │
│ └── routes.py *** ModuleNotFoundError: No module named 'register_ig'
│ from register_ig import app
│ from flask import render_template, request, redirect, url_for
│ from register_ig.models import *
│ from register_ig.forms import PurchaseForm
│ from config import *
│ from datetime import datetime
│
├── .env
├── .gitignore
│
├── config.py
│ ORIGIN_DATA
│ SECRET_KEY
│ API_KEY
│
├── main.py
│ from register_ig import app
│
├── readme.md
│
└── requirements.txt
pip freeze:
certifi==2022.12.7
charset-normalizer==3.0.1
click==8.1.3
colorama==0.4.6
config==0.5.1
Flask==2.2.2
Flask-WTF==1.1.1
idna==3.4
importlib-metadata==6.0.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.2
python-dotenv==0.21.1
requests==2.28.2
urllib3==1.26.14
Werkzeug==2.2.2
WTForms==3.0.1
zipp==3.12.0
What is happening? and why? Thanks for your help.
Python has built in modules and opensource modules that you can install via the pip package manager. These packages are normally stored in a location on the operating system that python can find/access. You have created an application with your own personal code stored in modules that python doesn't know the location of. That's why when it goes to import your modules it cannot find them because it doesn't know what directory to look in. That is why you have to use the PATH functionality so that python can find your modules. If you are on linux you can use the following command below:
export PYTHONPATH=$PYTHONPATH:<path_of_root_directory_of_application>

How to import a file from another folder in Python

I have the following folder structure:
...
│
├── src
│ ├── folder_A
│ │ └── file_A.py
│ │ └── __init__.py
│ │
│ ├── folder_B
│ │ └── file_B.py
│ │ └── __init__.py
│ │
│ └── __init__.py
│
│
└── something else
In the file file_A.py I put from folder_B import file_B as fb. But file_A.py works only in debug mode (meaning that the code produces the expected results). If I run file_A.py in the standard way I get the error ModuleNotFoundError: No module named 'folder_B'.
I also changed the configuration before running the code, putting C:\Users\***\***\***\src as the working directory of file_A.py but it still doesn't work.
What can be a solution?
If your current directory is src, then folder_B is in the path because of that. If you want to make a package with sub-packages that can access each other, place everything into a root package:
│
├── src
│ └── root_package
│ ├── folder_A
│ │ ├── file_A.py
│ │ └── __init__.py
│ │
│ ├── folder_B
│ │ ├── file_B.py
│ │ └── __init__.py
│ │
│ └── __init__.py
│
└── something else
Now in file_A, you can do
from ..folder_B import file_B as fb
Since src is not a package, you can't do a relative import through it. By adding root_package, you make it possible to find folder_B in the same package hierarchy (albeit a different branch) as the module doing the import.

Python: 'ModuleNotFoundError' when trying to import module from files

i want to access config/cache.py from test.py And ,I need internal access like from config/env.py to database/modules/game.py but i get this error always:
ModuleNotFoundError: No module named 'modules'
my project tree:
project
├─ modules
│ ├─ cache
│ │ ├─ playtime.py
│ │ └─ __init__.py
│ ├─ config
│ │ ├─ cache.py
│ │ ├─ database.py
│ │ ├─ env.py
│ │ ├─ yaml.py
│ │ └─ __init__.py
│ ├─ database
│ │ └─ models
│ │ ├─ game.py
│ │ ├─ member.py
│ │ ├─ room.py
│ │ ├─ wiki.py
│ │ └─ __init__.py
│ ├─ room
│ ├─ utils
│ │ ├─ functions.py
│ │ ├─ logger.py
│ │ └─ __init__.py
│ └─ __init__.py
├─ run.py
└─ test
└─ test.py
and inits file are like that:
from .config import *
from .utils import *
from .database import *
from .cache import *
Python automatically insert the folder in which the main script resides to sys.path, which is a list containing folders where to find packages and modules.
So, if test.py were in folder project, that folder would be in sys.path and then you could import the modules package and any of its subpackages or modules.
import module # main package module
from module import config # subpackage config
from module.config import env # module env
(Just in case, a module is a file ending in .py, and a package is a folder with a file called __init__.py inside and optionally subpackages and/or modules.)
So one solution wood be to move the file test.py to projects
Another alternative is to add the folder projects (as a str) manually to sys.path which is a simple python list before importing.
import sys
sys.append('.../projects')
from modules.config import env

Python import failure in script

I have a project structure, like so:
└──  auto/
│ ├────  __init__.py
│ └────  __pycache__/
│ ├────  deploy
│ ├────  destroy
│ └────  helpers/
│ │ ├────  __init__.py
│ │ ├────  cli.py
│ │ └────  zip.py
│ └────  synth
└──  src/
│ ├────  __init__.py
│ ├────  main.py
│ └────  models/
│ │ ├────  __init__.py
│ │ ├────  filter.py
│ │ └────  json_extract_config.py
│ └────  utils/
│ │ ├────  __init__.py
│ │ └────  json_extractor.py
I am trying to call the script synth in the ./auto/synth location.
The synth file is a script with a shebang at the top #!/usr/bin/env python3
It imports a function from the ./auto/helpers/zip.py file.
When I run, ./auto/synth from the root folder it throws an error:
from auto.helpers.zip import zip_folder
ModuleNotFoundError: No module named 'auto'
Although when I run PYTHONPATH="$PWD" ./auto/synth the script executes successfully.
Can someone help me understand this behaviour and how to avoid it so that my scripts can be run normally without having to change the PYTHONOPATH?
Thanks in advance.
If you are using python version 3.3+ you do not need to use the __init__.py files anymore, as the namespacing is built into the modules now. link --> Is __init__.py not required for packages in Python 3.3+
I believe you will have to add the {full path}/src and {full path}/auto directories to the PYTHONPATH to provide python scripts the proper pathing, or you can use the python sys module and use sys.path inside your modules to set your pathing for the module you would like to import link --> https://docs.python.org/3/tutorial/modules.html#the-module-search-path
import sys
# example path could be "C:/Users/Bob/Desktop/project/auto"
sys.path.append("{full path to your auto directory}/auto")

Python import module/function from below subdirectory or anywhere

I would like to load in a function/module with my working directory as project main directory but the function file is store below the a subdirectory level so the normal
from function_file import function_name
does not work.
This is what the project directory set up looks like:
└───project_main_directory
│ .gitattributes
│ .gitignore
│ README.txt
│
├───code
│ ├───exploration
│ └───scripts
│ │ script1.py
│ │ script2.py
│ │ script3.py
│ │
│ └───functions
│ │ function1.py
│ │ function2.py
│ └───__init__.py
│
├───data
│ └───example_data
│ data.csv
└───documents
So I tried to import functions via
import code.scripts.function.function1 from function1
and that doesn't work. I know it's because the other subdirectories aren't modules, but I want to ask if there is away around that?
-- EDIT
I'm working from .py file in code/scripts/script1.py but working directory is project_main_directory/
Add an empty file __init__.py to every subdirectories to make them as modules.
.
├── code
│ ├── __init__.py
│ └── scripts
│ ├── __init__.py
│ └── script1.py
└── main.py
Then if you have a function called hello in code/scripts/script1.py you can import that function by:
from code.scripts.script1 import hello
hello("yo")
If your current directory is project_main_directory, you can use:
from code.scripts.functions.function1 import function1
Directory of your script doesn't matter. Only your current directory matters (refer top of the IDE)
To import function/module from another python file, you have to do something like below -
from code.scripts.functions.function1 import function1
Above we are loading function1 from function1.py file which is stored in functions directory which is stored in scripts directory and finally in code directory.
EDIT - so you are saying, you want to load a function from function1.py in script1.py? In that case from .functions.function1 import function should work.

Categories