importing an attribute from parent directory - python

This is how my folder and files looks like:
/app
__init__.py
/admin
__init__.py
models.py
and app/__init__.py file:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from app.admin.models import *
app = Flask('app')
#app.route('/users', methods=['GET'])
def show_users():
return "list of all Users:\n" + User.query.limit(5).all()
and app/admin/models.py :
from datetime import datetime
from sqlalchemy.orm import relationship
from flask_sqlalchemy import SQLAlchemy
from app import app
db = SQLAlchemy(app)
class User(db.Model):
pass
I want have access to my User model in init file,from Import from parent directory and import script from a parenet directory I have tried from app import * or from .. import app or also put db = SQLAlchemy(app) in __init__ file and import it in models.py with from app import db or from .. import db but I'm keep getting app and db are not defined and also I think it's weird that I should import both file in each other.

The error is about Flask extensions, while your app created sqlalchemy extension didn't initialize, therefore it cause error. The best practice is to keep extensions initializes in same place:
#app/__init__.py
...
db = SQLAlchemy(app)
from app.admin.models import *
#app/admin/models.py
...
from app import db
If you do this changes, it will work.

Related

I am getting import errors when trying to import my database into my own module

I have a module called crop.py in my flask application. Everything works great until I want to import database parts from models.py. I'm guessing it has something to do with initializing the module into the app and then trying to import models into it, but I'm not sure.
Here is the error:
flask.cli.NoAppException: While importing 'test', an ImportError was raised.
Here is my basic app construction.
-app
models.py
crop.py
crop.py
from app import current_app
from flask import url_for, Markup
import PIL
from PIL import Image
from uuid import uuid4
import os
#Adding these below causes an importerror------------------------------------
#from app import db
#from app.models import Upload
class _Avatars(object):
#code here
class Avatars(object):
def __init__(self, app=None):
if app is not None:
self.init_app(app)
#code here
__init.py
from flask import Flask, request, current_app _l
from elasticsearch import Elasticsearch
from redis import Redis
import rq
from config import Config
#This is my module-----------------------------------------------------
from .crop import Avatars
db = SQLAlchemy()
migrate = Migrate()
avatars = Avatars()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
avatars.init_app(app)
I think it is causing a circular import error, since you're importing your crop model in your __init.py file and you're import db from __init.py into crop model file. Python does not allow this kind of scenario. Either you'll have to define your DB connections elsewhere in a separate file or add them manually everywhere you need to use the DB.

Python: unable to import classes from higher directory

I am learning flask. I have a directory structure that looks something like this.
project
- controllers
-- auth.py
-- main.py
- db
-- setup.py
- models
-- models.py
- templates
-- base.html
-- index.html
-- login.html
-- signup.html
-- 404.html
-__init__.py
The file init.py looks like this
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# init SQLAlchemy so we can use it later in our models
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = '9OLWxND4o83j4K4iuopO'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:#localhost/mission_to_mars'
db.init_app(app)
# blueprint for auth routes in our app
from .controllers.auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
# blueprint for non-auth parts of app
from .controllers.main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
I'm trying to import the db variable and create_app() function in controllers/auth.py, controllers/main.py, models/models.py, db/setup.py
I have tried the below syntaxes
from .. import db, create_app
which gives the error:
ImportError: attempted relative import with no known parent package
I have also tried
from project import db, create_app
which gives the error
ModuleNotFoundError: No module named 'project'
I want to know how I can import classes from different directories so that I can use them further in the project.
Thanks in advance

Possible circular import issue in Flask app

Trying a simple rest api in flask and basic stuff works. When I try to introduce DB, it's failing on imports for model
app.py
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
import redis from rq import Queue
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db)
from models import OcrText
models.py
from app import db
class OcrText(db.Model):
# schema
Error
Traceback (most recent call last):
File "app.py", line 21, in <module> from models import OcrText
File "/Users/anibara/Learn/Flask/ml_ocr/models.py", line 1, in <module> from app import db
File "/Users/anibara/Learn/Flask/ml_ocr/app.py", line 21, in <module> from models import OcrText
ImportError: cannot import name 'OcrText'
Yes, you are correct, it is a circular import issue. Just move the DB initialization to a new file like db.py and import this file from app.py and models.py. This way it will work fine.
Example db.py
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
db = None
def init_db(app):
global db
db = SQLAlchemy(app)
Migrate(app, db)
return db
Example app.py
from db import init_db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
init_db(app)
from models import OcrText
Example models.py
from db import db
class OcrText(db.Model):
# schema

ImportError: cannot import name 'variable' from 'module'

I am using Flask for my web framework. I am having an issue with imports. I am not understanding why can't I import my variable when I declare it within my my_app/__init__.py:
from flask import Flask
from flask_login import LoginManager
from my_app.some_module.my_class.py import auth
app = Flask(__name__)
login_manager = LoginManager()
class Config:
def __init__(self):
pass
config = Config()
My conflictuous imports are present in my_app/some_module/my_class.py:
from flask import Blueprint
from my_app import login_manager # this one works fine
from my_app import config
auth = Blueprint('auth', __name__)
I run the app with run.py:
from my_app import app
app.run(debug=True)
I then get the error:
Traceback (most recent call last):
...
File ".../my_app/some_module/my_class.py", line 1, in <module>
from my_app import login_manager, config
ImportError: cannot import name 'config' from 'my_app' (.../my_app/__init__.py)
Project structure is:
my_app
+ __init__.py
some_module
+ __init__.py
+ my_class.py
+ run.py
You have a cyclic import: my_app.some_module -> my_app.some_module.my_class -> my_app.some_module.
You can fix this by moving both Config and config to a separate module my_app.some_module.config.
# my_app.some_module.my_config
class Config:
pass
config = Config()
# my_app.some_module.my_class
from .my_config import config
# my_app.some_module.__init__
from .my_config import config
from .my_class import MyClass
This means that every import does not depend on previous imports:
my_app.some_module
|-> my_app.some_module.my_class -> my_app.some_module.config
\-> my_app.some_module.my_config
Doing imports this way instead of moving the import for .my_class to the end of __init__.py is more robust. You can freely reorder the imports of .my_class and .my_config at the top of files.
The problem is that you have a cyclic dependency. By the time you import auth from my_app.some_module.my_class.py your config is not set yet. Try moving that import to the end of the my_app/__init__.py file like:
from flask import Flask
from flask_login import LoginManager
app = Flask(__name__)
login_manager = LoginManager()
class Config:
pass
config = Config()
from my_app.some_module.my_class.py import auth

Importing Views

My app layout
my_app
__init__.py
my_app
__init__.py
startup
create_app.py
create_users.py
common_settings.py
core
models.py
views.py
Inner __init__.py
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) # The WSGI compliant web application object
db = SQLAlchemy(app) # Setup Flask-SQLAlchemy
manager = Manager(app) # Setup Flask-Script
from my_app.startup.create_app import create_app
create_app()
create_app.py
from native_linguist_server import app, db
#app.before_first_request
def initialize_app_on_first_request():
""" Create users and roles tables on first HTTP request """
from .create_users import create_users
create_users()
def create_app(extra_config_settings={}):
app.config.from_envvar('ENV_SETTINGS_FILE')
# Load all blueprints with their manager commands, models and views
from my_app import core
return app
When I run my app like this and try to load a view in my browser, I get a 404 error.
However if I change:
from my_app import core
to
from my_app.core import views
it works fine.
Could someone please explain to me the difference between these two calls? I would have thought from my_app import core would also import views.py and hence there wouldn't be an issue.
Thank you.
from my_app import core
will load and execute my_app/core/__init__.py (if it exists). You will then have access to any identifiers defined inside or imported into __init__.py.
from my_app.core import views
will load and execute my_app/core/views.py. You'll then have access to any identifiers defined inside or imported into views.py.
To get the behavior you're expecting, you'll need to import views inside __init__.py:
from . import views

Categories

Resources