attempted relative import with no known parent package (python) - python

I'm trying to import the db module from the __init__ file, after comand from . import db, gets attempted relative import with no known parent package
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
My catalog structure:
Procjet
├── __init__.py
├── auth.py
└── templates
i tried it:
from . import db
from .. import db
from project import db
from .project import db
and always i gets attempted relative import with no known parent package

Opening the project folder directly in an IDE should fix the issue.
You could check if the correct path is in sys.path in debug mode for example.

You could try my new import library: ultraimport
It gives the programmer more control over their imports and lets you do file system based relative and absolute imports.
To import the db object relatively, your auth.py could look like this:
import ultraimport
db = ultraimport('__dir__/__init__.py', 'db')
This will always work, no matter how you run your program and independent of your sys.path.

Related

Python can't import module from package

I have a flask restful project with the following layout (file names changed for convenience)
myproject/
__init__.py
app.py
common/
__init__.py
util.py
foo/
__init__.py
main.py
utilities.py
foo/ is just a folder containing code for one of the API endpoints, I'm planning to add others in the future, for this reason I have common/util.py file which contains reusable functions that I will use with other API endpoints.
foo/main.py
from flask_restful import Resource, request
from utilities import Analysis
class Foo(Resource):
def get(self):
pass
in foo/utilities.py I have classes with methods that get some data, I import those classes to foo/main.py to return JSON response
classes in foo/utilities.py also uses some functions from common/util.py but when I try to import something from common/util.py to foo/utilities.py I get import common.util
ModuleNotFoundError: No module named 'common'
What could be causing this? I tried importing various ways:
from common.util import my_func
from .common.util import my_func
from myproject.common.util import my_func
but none worked.
This is myproject/app.py in case it matters:
from flask import Flask
from flask_restful import Api
from foo.main import Foo
app = Flask(__name__)
api = Api(app)
api.add_resource(Foo, '/Foo')
if __name__ == "__main__":
app.run()
I'm doing all of this in activated virtualenv if it matters
from common.util import my_func
In Python 3 this is an absolute import, that is, the directory with common/ subdirectory must be in sys.path. In your situation it's certainly a wrong approach.
from .common.util import my_func
This import expects common to be a subdirectory of foo which is also not the case.
from myproject.common.util import my_func
This is finally the best approach but for it to work the parent directory of myproject/ subdirectory must be in sys.path. Either you install the entire myproject or add the parent directory to $PYTHONPATH environment variable or add the directory to sys.path in foo/main.py. Something like:
PYTHONPATH=/home/to/parentdir /home/to/parentdir/myproject/foo/main.py
or
import sys
sys.path.insert(0, '/home/to/parentdir')
/home/to/parentdir is the directory where myproject/ is.
After installing myproject or adding its parent directory to sys.path you can also use relative import. You need to remember that common is a sibling package comparing to foo so the import must be not from .common but from ..common:
from ..common.util import my_func

How to import models from outside Django BASE_DIR

I am working on a Django app in which I want to import some class/function from generator.py into my views.py to process an user-submitted input. My folder structure looks like this:
project/
models/
__init__.py
generator.py
web/
django/
__init__.py
settings.py
urls.py
wsgi.py
django_app
__init__.py
views.py
etc.
Inside views.py, I have
from ...models.generator import Generator
When I try to run server, what I get is:
ValueError: attempted relative import beyond top-level package
I've seen many answers, but most are about manipulating sys.path or changing PYTHONPATH. I'm not sure how and where to do either cause I'm rather new to Django.
Can someone tell me exactly which commands to run to allow the import to be done?
Import of python is based on sys.path and cannot be outside the top-level dir. More information.
That's mean, if you append top of BASE_DIR path in sys.path you can import. But it's a tricky way.
def import_function():
import sys
sys.path.append(os.path.dirname(BASE_DIR))
module = __import__('models.generator') # import code
sys.path.pop()
return module
g_module = import_function()
g_module.Generator

Cannot import app modules implementing Flask CLI

For some reason when I try to execute my custom command:
flask create_user
I get an error whenever I try import anything from my src folder:
File "/app/backend/flask_app/command.py", line 17, in seed_db
import src.models
ModuleNotFoundError: No module named 'src'
/
__init__.py
command.py
run.py
src/
__init__.py
models/
__init__.py
user_model.py
command.py
import click
from flask import Flask
from flask.cli import with_appcontext
app = Flask(__name__)
#app.cli.command()
#with_appcontext
def create_user():
import src.models as models
print("hello")
app.cli.add_command(seed_db)
I found the solution.
I had to delete the root dir __init__.py file.
I found this answer from the famous Miguel Grinberg:
https://github.com/miguelgrinberg/flasky/issues/310#issuecomment-340641813
These files (__init__.py) make python believe the main directory of the package is one directory above, so that is the directory that is added to the Python path. Usually you want your top-level directory to not be a Python package, so that the current directory goes to the path.
__
It is a matter of python way of import modules, not about Flask command.
Since command.py file is at the same level of the models folder you can just write:
import models.user_models as users
After that you can acces the user_models module from users reference:
import models.user_models as users
users.some_function_name()

Why won't my class import in Python?

Edit: __init__.py files are included, but I'm using Python 3 - I don't think it matters.
Another edit: Anything in config.py will import with no problem. If I simply omit from cache import Cache then no errors. Interestingly, no errors occur when importing Config in config.py
I cannot figure out what's wrong here. I'm getting an error whenever I try to import a specific class. Here's what my project layout looks like:
app/
dir1/
config.py
cache.py
manager.py
__init__.py
test/
test.py
__init__.py
cache.py:
import sys
import os
sys.path.append(os.path.dirname(__file__))
from manager import Manager, AnotherClass
from config import Config
manager.py
import sys
import os
sys.path.append(os.path.dirname(__file__))
from config import Config
from cache import Cache
test.py
cwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.abspath(os.path.join(cwd, os.pardir)) + '/dir1')
from cache import Cache, AnotherClass
from manager import Manager
test = Cache()
...
So when I run test.py I get this:
File "/path/to/project/app/dir1/<module>
from cache import Cache
ImportError: cannot import name 'Cache'
from manager import Manager line 5,
Even though config.Config loads just fine, no errors there, but as soon as I try to import cache.Cache it suddenly can't find or import any class in cache.py. All files have the same permissions. Can someone tell me what's wrong here?
You are missing the __init__.py file in your module
app/
__init__.py
dir1/
__init__.py
config.py
cache.py
manager.py
test/
test.py
and instead of messing with sys.path should do a relative import like
from .config import Config
from .cache import Cache
Python 2 may also need a line
from __future__ import absolute_import
before those imports.

import python class into another folder in a package

I'm trying to import a python class from another folder of my python package but I this error "No module named models".
It's a Flask project.
-app
|-run.py
|-myapp
|- libs
|- updateto
|- __init__.py (empty)
|- connection.py
|- removeto
|- __init__.py (empty)
|- static
|- templates
|- __init__.py (NOT empty)
|- routes.py
|- models.py
My init.py:
from flask import Flask
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///maindb.db'
from models import db
db.init_app(app)
import myapp.routes
In my models.py I've a class named: application
And in connection.py I want import my class "application".
I've try with "from models import application" but I've this error "no modules named models".
I think it's possible to reach this goal with the modification of the init.py in the "updateto" folder but I'm no sure because I don't clearly understand the functioning of the init.py file...
Thanks
EDIT:
Which is weird, it's if under connection.py I add "import myapp" and "print(help(myapp))", I've this output:
Help on package myapp:
NAME
myapp
FILE
c:\app\myapp\__init__.py
PACKAGE CONTENTS
libs (package)
models
routes
DATA
app = <Flask 'myapp'>
But if I try "from myapp import models" I've this error "ImportError: cannot import name models"
EDIT2:
If I try to add in connection.py "from myapp import app", it works but not if I try to import models... I'm very surprised. I've try to add in myapp/init.py:
__all__ = ["models", "routes]
But same error...
EDIT3:
hummmm I've move all my modules under the libs folder into myapp and when I try to put in connection.py "from model import application" I've always the same error "ImportError: cannot import name application"
Other test in connection.py:
import models
print(models)
Output:
<module 'myapp.models' from 'C:\app\myapp\models.pyc'>
I can import my module named models but I can't import the class under models.py
EDIT4:
Ok, I think I found the problem. It's my ini.py in myapp, because if I comment this file content, the connection.py can now import my class application in models. I run the file run.py which uses routes.py and it's him that calls operation.py
With some tests, I've find the lines who create my error:
from models import db
db.init_app(app)
import myapp.routes
But why????
I don't know about Flask specifically, but in Python you should generally include a __init__.py in every folder and subfolder for them to be recognised as modules and/or packages.
In the diagram you provide, there is no __init__.py in the app folder. Try putting one and re-post if that resolves your problem.
If it doesn't work, try:
import os
print(os.getcwd())
If the current working directory isn't the app directory, you'll have to work around this. One way would be:
import sys
sys.path.append('/path/to/app')
import myapp.models
You can always see what directories are in your search path for modules by checking sys.path.
Update: Sorry I just realized that maybe you' re trying to run connections.py as a script. That would change you working directory to that of connections.py. Try importing connections.py from your main script with import models inside connections.py and see if you get an error.
Update (in reply to Edit 4): (I don't have enough reputation points to comment yet, so I reply here)
from models import db
db.init_app(app)
import myapp.routes
The problem in this piece of code is the import myapp.routes. Change that to import routes and it should work. As a rule of thumb, your main script's directory is your root directory. You can import any module located in your root directory from inside any other module (even modules inside a sub-folder!) with a simple import module.

Categories