global/app lib folders import in Django - python

I have a Django structure like this (only showing libs):
project/lib/ # Global libraries that will be used cross apps
project/lib/global_stuff.py
project/apps/app1/lib/special_for_app1.py
project/apps/app2/lib/special_for_app2.py
Some apps don't have a lib folder.
from apps.app1.lib import special_for_app1 works fine. But how can I import from the global lib folder when I am inside a folder already containing a local lib folder?
From inside the apps views.py file on one of the apps:
from lib import global_stuff
Gives me ImportError: cannot import name global_stuff
from .lib import global_stuff
Gives me ImportError: cannot import name global_stuff
from ..lib import global_stuff
Gives me ImportError: No module named lib
from ...lib import global_stuff
Gives me ValueError: Attempted relative import beyond toplevel package
from project.lib import global_stuff
Works, but I really dont want to be stuck with using the project name itself in the import.
Is there any way to solve this, not using the project name in the import, or changing the whole lib idea.
Or is there any other good practice to store the main part of the code?

You are correct for not wanting to associate the project name with the imports, so there is a common pattern for this:
project/
|__/source/
| |__/lib/
| |__/app/
|__/deployment/ # code for your production deployment maybe
|
|__/docs/
|__/tests/
|__README
|__requirements.txt
and put /path/to/project inside your paths on your virtualenv(you use virtualenv right?).
Then you can do inside your code
from source.lib.blah import foo
from source.app.baz import bar
EDIT: This is only optimal if you don't release your code as open source of course. Only when you have an internal project where the management keeps changing the name of the project :D

I really dont want to be stuck with using the project name itself in the import
Why not? It's the best way. Note that 'relative imports for intra-package imports are highly discouraged', - as said in PEP-8.

Related

import module in Django

I have a project with structure like on this picture.
Folders structure
Where 'backend' folder is Django project folder.
I need to import module from another folder 'main' inside Django app file, i.e. import main.Text_Generator in backend.app.views file.
I tried: from ...main.Text_Generator import *. This raise an error while running a server: "attempted relative import beyond top-level package"
And from main.Text_Generator import *, also error "No module named 'main'"
What is the correct way to do such import?
Add this:
import sys
sys.path.append("..")
And then you should be able to get it with:
from main.Text_Generator import *
You're using a module outside your Django project. I would recommend moving the folder inside your project directory [or app directory] rather than messing with your PATH. If you move main inside backend your existing stuff will work.

Cannot import package from a different folder

I am working on a project based on Python 2.7 and I am trying to import a module which is in a package folder that contains __init__.py and the file that I want to import called package1.py, but I am unable to do so. This is my folder structure: main_project/Tools/common/package1.py
Note that my project files are in the folder main_project. So, I am trying to call the package1.py by using an import statement in my script:
from Tools.common.package1 import variable
But I am getting an ImportError: No module named Tools.common.package1.
What is the solution to solving this error as I want to use the package feature for my project?
Maybe use the solution i found here :
# some_file.py
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, '/path/to/application/app/folder')
import file
or verify your module has a __init__.py
Importing files from different folder
Ok I have found the answer. I also had to insert an init.py in the folder Tools as well. Initially I only inserted init.py in common but not in Tools as we should also make Tools a package if we want to access common

Cannot Solve "ValueError: attempted relative import beyond top-level package"

I am running the project and shows this error. I have googled and tried some of the solutions but doesn't seem to work.
File "/home/bs-094/Dev/backend/busgroup-backend/src/bus_portal_backend/apps/inquiry/forms/inquiry_details.py", line 2, in <module>
from ..models.inquiry import Inquiry
ValueError: attempted relative import beyond top-level package
My folder structure is
busgroup-backend
src
bus_portal_backend
apps
inquiry
models
_init_.py
inquiry.py
forms
inquiry_details.py
It would be great help is anyone helps me solve the problem. I am fairly new to django. Thanks
EDIT:
Here's what solved my problem, I had to import in this way
from bus_portal_backend.apps.inquiry.models import Inquiry
Also, I was running with debugger. My script path was busgroup-backend/src/manage.py, I changed it to /home/bs-094/Dev/backend/busgroup-backend/src/manage.py, which made me run the project successfully.
forms does not appear to contain an __init__.py file, and so Python doesn't think it's a package. Therefore an attempt to import from ..models is an attempt to ascend above the current package's root (because ...busgroup-backend/src/bus_portal_backend/apps/inquiry/forms/inquiry_details.py is actually a standalone module).
Relative imports only work within a package. Therefore you should make both forms and models subpackages of inquiry by creating inquiry__init__.py as well.
If you import from ..models.inquiry import Inquiry then .. refers to
busgroup-backend
src
bus_portal_backend
apps
Which does not have an __init__.py and thusly is not considered a package by python.

Import custom module to Django

I'm making a django app and cannot import a custom module inside the views.py file.
I'm trying to import class "Integrate" from auth.py inside modules folder from integrations/views.py
I tried placing init.py inside the app folder and modules folder but still doesn't work.
views.py:
from ..modules.auth import Integrate
Powershell:
from ..modules.auth import Integrate
ValueError: Attempted relative import beyond toplevel package
I do this a lot in my projects. Creating custom modules and importing them.
Try this:
from modules.auth import Integrate
You can use this :
from .models import Integrate
It will be work for use models
I am pretty certain I had this exact problem.
It helps if you make the directory holding the module a 'Sources Root'
You right click on the directory and down the bottom of the pop-up is 'Mark Directory As' option.
AFAIK this adds that directory to the PythonPath so the module in there will be found.

Better approach to use script inside nested directory PYTHONPATH

Sorry for asking my own question 2nd time, but i am totally stuck in import file in python.
I have a directory structure below:
|--test/foo.py
|--library #This is my PYTHONPATH
|--|--script1.py
|--|--library_1
|--|--|--script2.py
|--|--library_2
|--|--library_3
I am accessing library/library_1/script2.py from test/foo.py.
Here i am confused about what is the better approach. Generally all library folders or utility functions should be added to pythonpath.
This is a folder structure i am maintaining to differentiate utility functions and test scripts.
I tried putting __init__.py in library and library1 & then imported like from library1 import script2, but getting error as No module named script.
I have tried appending that path to system path as well.
Working: if i add another pythonpath like path/to/library/libray_1/. So should i do this for all folders which are inside library folder to make it work ?
Here's what you need to do:
|--test/foo.py
|--library #This is my PYTHONPATH
|--__init__.py
|--|--script1.py
|--|--library_1
|--|--|--__init__.py
|--|--|--script2.py
|--|--library_2
|--|--|--__init__.py
|--|--library_3
|--|--|--__init__.py
And inside the first __init__.py below library you need to do:
import library1
import library2
import script
Then, if library is your python path, you can do this within test/foo.py with no errors:
import library
library.library1.bar()
library.script.foo()

Categories