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.
Related
I know there are dozens of Python package import questions, but I can't seem to find an answer that works. Most answers seem to be about the missing __init__.py to make a package, but I've got one in the base of the project (and I've tried in the sub-folders as well).
I have a project of the form
package
+-- __init__.py
+-- weasel.py
+-- badgers
| +-- __init__.py
| +-- a.py
where weasel.py just contains a test function
def test_function():
return "HELLO"
and I want to be able to call test_function from a.py, I've attempted (all with and without the init.py in the folder badgers) and none of which seem to work.
import weasel -> ModuleNotFoundError: No module named 'weasel'
from . import weasel -> ImportError: attempted relative import with no known parent package
import package.weasel -> ModuleNotFoundError: No module named 'package'
from package import weasel
The hack I've managed to employ thus far, which works fine in Spyder and in my production environment; project is a Dash App (so Flask) deployed to render.
import sys
sys.path.append("..")
import weasel
But this just throws ModuleNotFoundError in VS Code.
I'm not adverse to a hack :S but the needs of the current project kinda make life much, much, easier if I could build the project in VS Code.
Please, I implore the stackoverflow community could someone please let me know what I'm doing wrong? Or a hack that will work in VS Code?
Thank you,
This is caused by the path. The path of vscode running file is not the current file path. You need to add it manually.
import sys
sys.path.append("your package's Path") #for example, my path is "C:/my_python/package"
import weasel
Here is my directory structure.
Tips:
Do not use "..", it will really adds two commas to path instead of parent directory.
I have a package with this structure
framework/
__init__.py
file0.py
file1.py
file2.py
file3.py
I want to able to import it as import framework, but I'm not able to do it that way, only from framework import * works, and that too without autocomplete. file0.py and file1.py are classes, and the others have only functions.
Autocomplete works, however, when I manually do this on the file I'm working on in an external directory
from framework import file0
from file0 import *
# and so on for the others
This is my __init.py__
from framework.file0 import file0
from framework.file1 import file1
from framework.file2 import *
from framework.file3 import *
I've tried putting
from framework import file0
from file0 import *
# and so on for the others
on __init.py__ but it doesn't solve the issue, autocomplete still doesn't work unless I put them in the actual file I'm working on in another directory. I want it to able to work on import framework
Is there a way?
Thanks in advance. I'm new to this, so any advice is appreciated.
What you want for your __init__.py is from .file0 import file0, or whatever content from file0.py you want to import.
See Package relative imports in Python docs.
However, I think it's ill adviced to import everything in a package to __init__.py. If you do that, it will be loaded into python every time you try to import anything from that package. Say you want to do from framework.file0 import SomeClass into some other package, and that class is all you need from framework. If you import everything in __init__py, you will be loading all that every time you touch that package, since __init__.py is always loaded when accessing the package.
If you want a way to import everything from the package, maybe you should put that in another file, say all.py, and then do from framework import all as framework?
Conventionally, __init__.py is to be left blank.
Then in the script file where you need to import the complete package (with all the files), put this at the top and you should be good to go.
import framework
And if you want to import only one module for some reason, say framework.file0, you can use
import framework.file0
As far as autocompletion is concerned, this approach worked for me, in JupyterLab Notebook as well as the console.
#Background and Problem#
I'm trying to build a web-scraper to back up my social media accounts (summer project, I know it's useless).
I'm trying to create a nice class structure, so I've come up with the following structure (I accept critique, I'm pretty new to programming):
\social-media-backup
\Files
__init__.py
File.py
Image.py
Video.py
\SocialMedia
SocialMediaFeed.py
SocialMediaPost.py
\Instagram
__init__.py
\MediaTypes
__init__.py
GraphImage.py
GraphVideo.py
\SearchTypes
__init__.py
InstagramUser.py
\Twitter
\VSCO
(Twitter and VSCO are, for now, empty. Anything without extension and starting with , is a folder. Every file has a class with the same name as the file inside)
#Questions#
Where can I learn Python's packaging system definitively? Any book or web-site recommendation?
How would I import Image into GraphImage? How would I import File into SocialMediaPost?
What do I need to write in __init__.py so as to import SOME_PACKAGE and have it import every module? (e.g.: import Files and have Files.Image and File.Video accessible).
(I know there are a lot of questions. They're written in order of importance)
#To accomplish importing File into SocialMediaPost I've tried:#
from Files.File import File
from ...Files.File import File
import File
from File import File
And almost any combination you can imagine.
I always get an Unable to import, No module named '__main__.Files' or Attempted relative import beyond top-level package.
#Expected behavior#
I'm used to Java's way of doing this, and I cannot figure out how to do this in Python. It seems so messed up. I really miss just adding a package and a folder tree from where the compiler would run.
knocks desk THERE MUST BE A BETTER WAY
##THANKS!!##
Lots of stuff is written about this... however most guides focus on how you do it, not what to do.
How I do it (for small to medium-sized projects):
Do not mess with sys.path.
Have one "project root" directory with your modules / packages underneath (as you already do).
Use absolute imports always, except for "sister" modules.
Always run as module, i.e. using python -m foo.bar
Concrete example using your structure. Assuming that your entry point might be in \SocialMedia\SocialMediaFeed.py, use import statements:
from . import SocialMediaPost (sister module)
import Instagram (child module)
from Files import Image (other module)
and run using: python -m SocialMedia.SocialMediaFeed
By running as module, you always have the project root (social-media-backup) added as "search path". This way absolute imports refering to its subfolders always work. By the way, you can print out the module search path using import sys; print(sys.path).
Some of this might seem overcomplicated, but I found that following the above points pays out greatly as soon as you try to package up stuff for installation (keyword setup.py).
Edit: to answer 3rd question: Have __init__.py contain:
from . import File
from . import Image
from . import Video
I would second the comments by Damian and user2357112 - try to avoid name collisions between folder, file and class/function when creating modules.
You probably won't be able to import anything outside of the current working directory without adding it to your PYTHONPATH. Adding a folder to your PYTHONPATH environment variable means that python will always check that folder when importing modules, so you'll be able to import it from anywhere.
There is a good thread on this already that will put you in the right direction:
Permanently add a directory to PYTHONPATH?
(It's a lot to cover in one post)
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.
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.