ModuleNotFound error shown when importing file from root on vscode - python

I have a vscode project with this structure
/app
/labor
config.py
functions.py
config.py
testing.py
Notice that there are two config files, one under the labor folder and one under the app folder.
In functions.py I'm trying to import config.py under the app folder.
# note I need to add app. before config because if I don't it will think that I'm referencing the file under labor folder
import app.config as app_config
In testing.py I'm importing both files
import config as app_config
import labor.config as labor_config
print("test")
This is giving me a ModuleNotFound error.
The crazy part is, if I hold my CTRL key and click on "config" in app.config in the functions.py file, it will take me to the folder. So it is recognizing it. But somehow, when running the code, python isn't.
I created a repo here if you'd like to try it out:
https://github.com/jadeid91/testproject

you running testing in wrong place
if you want testing in app directory you have to use import config instead of import app.config in labor directory .py files and add __init__.py to labor to make sure python dont confused and give you labor.config
testing.py
import config as app_config
import labor.config as labor_config
import labor.functions as labor_functions
print(app_config.MAIN_TABLE_ID)
print(labor_config.LABOR_TABLE_ID)
labor/functions.py
import config as app_config
# if I import config, it will take me to labor.config
# import config
def hello():
print(app_config.MAIN_TABLE_ID)
folder structure
/app
/labor
__init__.py
config.py
functions.py
config.py
testing.py

add __ init__.py file in your labor folder.
Adding this will make python consider as 1 of the directories. so when you import, it will know where to look for and finds the file.
You need not do this for the other file as it is in the same directory as your testing.py

Related

Cant import from file in python

I am running a Flask server in Docker and cannot import create_app from app.py into my integration tests. I've tried a variety of naming approaches but Python is unable to find app.py.
The directory structure is as follows
/server
/test/integration/test.py
app.py
test.py has this import
from app import create_app
I tried relative imports as well but there was a "parent" error. I then played around with empty __init__.py files in an attempt to use relative imports. That didn't work. I am not sure why this is so involved to do really. What is the solution for this?
In test.py add:
# some_file.py
import sys
# caution: path[0] is reserved for script path (or '' in REPL)
sys.path.insert(1, '/path/to/app/folder')
import app
from app import create_app
This add the directory of the source file to the system so Python will know to go there when searching the things to import. This is true when both files are local on your computer. If there is a server you need to see how you modify the in-server Python environment to know the folder of the app.py file.
See: Importing files from different folder
You can try with relative imports
from ..app import create_app

Import error using relative import syntax

I have a project structured like so:
/proj
main.py
config/
__init__.py
setup.py
gui/
__init__.py
app.py
The program is run by calling python main.py.
In main.py I have from gui import App.
In gui/__init__.py I have from .app import App.
Lastly, in app.py I have from ..config import configure; this throws a ValueError that reads attempted relative import beyond top-level package. To resolve this, I can alter the strucure:
/proj
main.py
proj/
config/
__init__.py
setup.py
gui/
__init__.py
app.py
But then I have to change the import statments to include proj (i.e. from proj.gui import App). Is it possible to use relative imports in the former case with the current structure? If not, how can I import what I need from the config subpackage?
As strange as it sounds, you can do :
from config import configure
in app.py, for your former case (current structure), because when you run python main.py, it interprets config as the next level package, and .. won't work.
(Btw, I think there is lots of room for Python imports to improve. The current PEP 328 is confusing at best).

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()

relative imports in python in flask app

I have read numerous SO questions and blogs. I am trying to structure my flask application. The current structure of my application is the following:
application
run_server.py
/config
__init__.py
production.py
staging.py
development.py
/app
__init__.py
/site
__init__.py
views.py
Now, inside app/__init__.py I want to access the config based on my environment( dev, staging, production).
from ..config import config
I am getting this error:
ValueError: Attempted relative import beyond toplevel package
I have tried using -m switch.
I have also tried to set PYTHONPATH as my root directory to tell interpreter what is top level package.
I think I am missing some fundamental in relative imports.
Try using absolute import. IMHO it makes things easier to grok
from __future__ import absolute_import
from application.config import production
This is absolute because you are specifying the exact path you are importing from which reduces ambiguity.
Also, you are missing __init__.py in the application folder
If you are running your application through run_server.py then there is no need of relative import in app/__init__.py. You can simply say,
from config import <production/staging/development>
This is because, when your interpreter interprets run_server.py, at the line say, from app import <something>, it will fetch app/__init__.py content and try to execute them at toplevel i.e. from directory application.
Now, assume you are running from ..config import config at toplevel. Obviously, it will throw an error.
Assume you have configin application/config/__init__.py.
You also need __init__.py under application directory, if not, then the application/app is your top level package, you can not access application/config.

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