ImportError: cannot import name 'foo' - python

I'm learning python and received my first error in line 3:
here is my code:
app.py
import logging.config
from flask import Flask, Blueprint
from platform import settings
app = Flask(__name__)
def main():
app.run(debug=settings.FLASK_DEBUG)
if __name__ == "__main__":
main()
and my file structure is like this:
project_name
|--platform
| |--api
| |--database
| |-- __init__.py
| |-- app.py
| |-- settings.py
|--logging.conf
|--requirements.txt
|--readme.md
|--setup.cfg
i use PyCharm IDE and execute in terminal: python platform\app.py
then i receive this error:
Traceback (most recent call last):
File "platform\app.py", line 4,
in
from platform import settings
ImportError: cannot import name 'settings'
any idea what's wrong here?
here is my settings.py
# Flask settings
FLASK_SERVER_NAME = 'localhost:5000'
FLASK_DEBUG = True # Do not use debug mode in production
# Flask-Restplus settings
RESTPLUS_SWAGGER_UI_DOC_EXPANSION = 'list'
RESTPLUS_VALIDATE = True
RESTPLUS_MASK_SWAGGER = False
RESTPLUS_ERROR_404_HELP = False
# MYSQL settings
MYSQL_DATABASE_URI = 'blablalba'
MYSQL_TRACK_MODIFICATIONS = False
PYMYSQL_CONNECTION = {
'host': '123.456.789.111',
'port': 3306,
'user': 'root',
'passwd': 'password',
'db': 'database'
}

You have a package named platform but you are attempting to execute a script in it. When you do that, the script is going to be run independently, with none of the package information because the script is not imported. To do a proper import and then run as a script, use the -m option:
python -m platform.app
This will import the script from the platform package, set up the dependencies correctly, etc.
Generally, you would want to place your executable script outside your main package for this exact reason. If you modify your folder structure to look like this, the command python app.py should run just fine because platform will be a recognized package:
project_name
|--platform
| |--api
| |--database
| |-- __init__.py
| |-- settings.py
|-- app.py
|--logging.conf
|--requirements.txt
|--readme.md
|--setup.cfg
Finally, as a minor nitpick, if you do decide to keep app.py at the package level rather than the project level, I would recommend using relative imports to get the settings:
from . import settings

You have everything setup fine, my guess is that you are using settings.py as a constants file. so instead of
from platform import settings
try to import the values from the file relatively (since both app.py and settings.py are in the same directory)
from settings import *
and then you can use them like
print(FLASK_SERVER_NAME)
Although this would work fine, but I like to do it a bit differently, so as to not end up scratching my head trying to figure out what constant or function comes from where. Here are my 2 cents
import settings.py as configs # or any variable name you want to use
print(configs.FLASK_SERVER_NAME)
# more understandable as now you know FLASK_SERVER_NAME is coming from configs

You can straight away use import settings instead

Related

Settings file reference is not found

I'm working on migrating an exsting Python 2.7 project to Python 3.9. I'm facing a directory structure-related issue in Python 3.
My current project directory structure is:
├───project
│ ├───core
| +--__init__.py
| +--main.py
| +--settings.py
│ ├───jobs
| +--job.py
main.py:
import settings
class Main:
def __init__(self, a=None, b=settings.B):
self.a = a
self.b = b
def start(self):
print(self.a, self.b)
job.py:
import sys
# sys.path.insert(0, '../core/')
from core.main import Main
from core import settings
main = Main(settings.A)
main.start()
There is no issues with this structure when Python 2.7 interpreter is used, but in Python 3.9 I see the following error when job.py is executed:
File "project\core\main.py", line 1, in <module>
import settings
ModuleNotFoundError: No module named 'settings'
The issue is fixable by uncommenting the code on line #2 of the job.py script, but I would like to avoid hardcoding folder values like that. I would appreciate if someone could provide an alternative approach and an explanation why it's behaving this way in the newer Python version.
Due to ambiguity absolute import was removed in python3 for such use case. (This explains it very well: Changes in import statement python3)
You can use relative import for this use case maybe - https://docs.python.org/3/reference/import.html#package-relative-imports

include file in python

I tried to include file detect_simple.py, but it doesn't work.
Capture screnshoot: https://imgur.com/a/Rku8O1f
My code: in file app.py
__import__("Face_recognition/detect_simple")
from flask import Flask
app = Flask(__name__)
#app.route("/")
def main():
return "OK";
#app.route('/api1')
def api1():
return "OK"
if __name__ == "__main__":
app.run()
run command: python app.py
return error: `Import by filename is not supported.`
So for instance if your app.py is in the top directory and you need to import a module thats in a folder below that directory just use the from subfolder import mymodule.
For example if your directory looks like this:
- FlaskApp
- app.py
- Face_recognition
- detect_simple.py
Then use:
from Face_recognition import detect_simple
To expand on #Jab's answer: your Face_recognition directory must contain a (potentially empty) __init__.py file (with two leading and two trailing underscores) to be recognized by the import system.
Once your tree looks like this:
FlaskApp
|_ app.py
|_ Face_detection/
|_ __init__.py
|_ detect_simple.py
You'll be able to do a
from Face_detection.detect_simple import <whatever>
# or
import Face_detection.detect_simple
# or
from Face_detecting import detect_simple
Keep in mind that the import system is case-sensitive.
On a separate note, please avoid using the __import__ function in almost any case. Prefer the import statement if you're just importing stuff normally, or use importlib.import_module if you have to do programmatic imports (although this shouldn't be the default in most cases).

How to import model in Python/Django

My project structure is as follows:
my_proj
---calculation
---cardata
---master
---my_proj
--- __init.py__
--- admin.py
--- settings.py
--- url.py
--- update_db_from_ftp.py ///// This is my custom file
In update_db_from_ftp.py I want to download an csv file from ftp and update the database(if necessary) once every day with cron.
But the problem is that I can't import model which I want to update. The model which I want to update is inside master folder in models.py file.
I try to import model as follows:
from master.models import ModelName
But I'm getting an error as follows:
Traceback (most recent call last):
File "update_db_from_ftp.py", line 6, in <module>
from master.models import ModelName
ImportError: No module named master.models
But I use the same model in cardata and calculation folder and I import it the same way as I try in update_db_from_ftp.py file, but there it works without problems.
Any idea how to solve it?
UDPATE
The structure of the master folder is as follows:
For using django code in an arbitrary external script, two things are needed:
Django should be setup (exactly what happens when you run django shell).
The root project should be in python path (not the inner folder with same name).
Here is sample code which will work irrespective of the location of the script (although if the script is not one-off, better to add it as management command):
import django
import os
import sys
sys.path.append("/path/to/my-proj/")
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my-proj.settings')
django.setup()
from master.models import ModelName
if __name__ == "__main__":
print(ModelName.objects.all())

Python import from parent package

I'm having some trouble with imports in Python.
Here is a simple example of what's going wrong.
I have a directory structure like this:
app
|---__init__.py
|---sub_app
|---__init__.py
The code:
app/__init__.py
shared_data = {
'data': 123
}
from sub_app import more_shared_data
print more_shared_data
app/sub_app/__init__.py
more_shared_data = {
'data': '12345'
}
from app import shared_data
print shared_data
However I get the error:
ImportError: No module named app
How do I import the shared_data dict, into app/sub_app/__init__.py?
You can use relative imports for this . Example -
In your app/sub_app/__init__.py -
more_shared_data = {
'data': '12345'
}
from .. import shared_data
print shared_data
This should work for the simple example you have provided , but it does lead to circular import , app is importing sub_app and sub_app is importing app .
For more complex usecases, you can end up with errors (If you import sub_app) before defining specific elements, and then in sub_app/__init__.py you try to import app and use those elements that are only defined after the import statement for sub_app . A very simple example where it would cause issue -
app/__init__.py -
from .sub_app import more_shared_data
print(more_shared_data)
shared_data = {
'data': 123
}
app/sub_app/__init__.py -
more_shared_data = {
'data': '12345'
}
from .. import shared_data
print(shared_data)
Now, if you try to import app , you will get the error -
>>> import app
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<some file>\__init__.py", line 1, in <module>
from .shared import more_shared_data
File "<some file>\sub_app\__init__.py", line 4, in <module>
from .. import shared_data
ImportError: cannot import name 'shared_data'
You should re-think if shared_data does belong to app/__init__.py , or it can be moved to sub_app/__init__.py and then imported from there in app .
You have a few problems here, one of which is hidden.
It looks like you are trying to invoke your program like:
python app/__init__.py
python app/sub_app/__init__.py
This causes problems in that the directory of the main file is considered to be the root directory of the program. That is, why sub_app cannot see app.
You can instead invoke your programs like such
python -m app.sub_app
This way python assumed the current directory is the root directory and looks for the module app.sub_app under this directory. This causes another problem though. To be able to run a package you need to provide a __main__.py in the package (as well as __init__.py). If the modules do not import each other, then order of invocation will be app/__init__.py, app/sub_app/__init__.py, and then app/sub_app/__main__.py
app
|---__init__.py
|---sub_app
|---__init__.py
|---__main__.py
app/sub_app/__main__.py can do stuff like:
from app import shared_data
from . import more_shared_data
# or
from app.sub_app import more_shared_data
Finally, the hidden problem is that you have circular imports. That is, app depends on sub_app and sub_app depends on app. That both app and sub_app need the other to be loaded, before they can load -- this is of course impossible. You should refactor your code to avoid circular imports.

How to divide Python code to modules with shared code?

I'm using Falcon framework. I want that all standalone classes store in their own dirs( class that serve for /module1/ was inside dir /module1/):
/app
./app.py
/modules
/__init__.py
/module1
...
/module2
...
....
In app.py I have initialization of application:
import falcon
# falcon.API instances are callable WSGI apps
app=falcon.API()
My problems:
how I must organize import of modules, that I can access from
module2 to module1?
How I can access to app variable of app.py from /module2:
I need do this code:
module2_mngr = Module2(CONFIG_FILE)
app.add_route('/module2', module2_mngr)
PS:
Sorry for my English
Simple example where I can use different configuration based on api.debug.DEBUG flag:
create some base path: /somepath/my_app/
create the folder sturcture:
/somepath/my_app/api
/somepath/my_app/api/debug
/somepath/my_app/conf
/somepath/my_app/conf/prod
/somepath/my_app/conf/dev
create empty files:
/somepath/my_app/__init__.py
/somepath/my_app/api/__init__.py
/somepath/my_app/conf/prod/__init__.py
/somepath/my_app/conf/dev/__init__.py
Example main.py (/somepath/my_app/main.py):
import api.debug
api.debug.DEBUG = False
import conf
Setup api.debug.DEBUG == False
/somepath/my_app/api/debug/__init__.py:
DEBUG = False
Create simple "router":
If api.debug.DEBUG is True - loads production configuration.
If api.debug.DEBUG is False - loads development configuration.
So we create
/somepath/my_app/conf/__init__.py:
import api.debug
if not api.debug.DEBUG:
from conf.prod import *
else:
from conf.dev import *

Categories

Resources