I have the following code:
init.py:
"""Initialize app."""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
"""Construct the core application."""
app = Flask(__name__, instance_relative_config=False)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
app.config['RECAPTCHA_PUBLIC_KEY'] = '6LcmEeoUAAAAAIbdhgkFBvz676UCRJMjnSx8H6zy'
app.config['RECAPTCHA_PARAMETERS'] = {'size': '100%'}
db.init_app(app)
# blueprint for auth routes in our app
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
# blueprint for non-auth parts of app
from .__main__ import main as main_blueprint
app.register_blueprint(main_blueprint)
with app.app_context():
# Import parts of our application
from . import routes
return app
and I try to initialize the db with the following code:
from realProject import db, create_app
db.create_all(app=create_app())
all of the scripts are in realProject folder
but when trying to compile the last code I get this error:
ModuleNotFoundError: No module named 'realProject'
What am I doing wrong?
You need to follow this structure :
|__project_name
|__app.py ----------> The main file from where you run your app
|__app -----> This is the app folder
├── templates
│ └── index.html
└── __init__.py -----------> The __init__.py should be inside the app folder for it to be imported
└── routes.py
And then do this in your main file :
from app import db, create_app
db.create_all(app=create_app())
Related
I keep getting this error when trying to import my app and app.models.
Traceback (most recent call last):
File "tools.py", line 3, in
from app import db
ModuleNotFoundError: No module named 'app'
app/
api/
__init__.py
users.py
...
db_tools/
__init__.py
tools.py
errors/
__init__.py
...
__init__.py
models.py
app/db_tools/tools.py file:
import psycopg2
import os
from app import db
from app.models import UpdateLogs
...rest of code...
def request_update_log_comment():
return input('Enter a comment for the update:\n')
def create_update_log_comment():
comment = request_update_log_comment()
update_logs = UpdateLogs()
update_logs.save_log(comment)
db.session.commit()
if __name__ == '__main__':
create_update_log_comment()
/db_tools/init.py
from flask import Blueprint
bp = Blueprint('db_tools', __name__)
from app.db_tools import tools
I understand that there is no db.py file in app. However, all the other files in app/api and app/errors use this import without issue.
What gives? The app/db_tools folder is structured just like app/api and app/errors. Here's an example from api/users.py that works just fine. Notice that app/users.py is at the same file level as app/tools.py just in a different folder.
app/api/users.py
from flask import jsonify, request, url_for, abort
import ssl
import base64
import re
from app import db
from app.api import bp
from app.api.auth0 import AuthError, requires_auth
from app.api.errors import bad_request
from app.models import CustomNotes, SavedSets, ContactMessages
...rest of code...
app/init.py
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from config import Config
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_cors import CORS
db = SQLAlchemy()
migrate = Migrate()
cors = CORS()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
migrate.init_app(app, db)
cors.init_app(app)
from app.api import bp as api_bp
app.register_blueprint(api_bp, url_prefix='/api')
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app.db_tools import bp as db_tools_bp
app.register_blueprint(db_tools_bp)
if not app.debug and not app.testing:
if app.config['LOG_TO_STDOUT']:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
app.logger.addHandler(stream_handler)
else:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/website.log',
maxBytes=10240, backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Flask app startup')
return app
from app import models
You are trying to get db from the app package, but there is nothing called db.
so your folder structure should include db
app/
api/
__init__.py
...
db_tools/
__init__.py
tools.py
errors/
__init__.py
...
__init__.py
db.py <----------------------------
models.py
Now, if you want to get the object db created in app/__init__ (db = SQLAlchemy()) that is something different. For this, you will need to design the code in a different way.
Not sure what are you using in tool.py that required an object db so I cannot be more specific.
There is no db in app directory or in app\__init__.py so how can you import db from app? hence the error.
I am developing a Flask application, and I am not sure why I am getting this error:
File "app.py", line 17, in <module>
from endpoints.users.resource import UserResource
File "{basedir}/endpoints/users/resource.py", line 4, in <module>
from .model import User
File "{basedir}/endpoints/users/model.py", line 1, in <module>
from app import db
File "{basedir}/app.py", line 17, in <module>
from endpoints.users.resource import UserResource
ImportError: cannot import name 'UserResource' from 'endpoints.users.resource' ({basedir}/endpoints/users/resource.py)
I believe it is due to a circular dependency, from looking at the error, but I can't figure out why, because I think that the order in which I am importing things in my code should have circumvented this issue:
app.py:
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
api = Api(app)
api.prefix = '/api'
from endpoints.users.resource import UserResource
api.add_resource(UserResource, '/users')
if __name__ == '__main__':
app.run(host="0.0.0.0")
endpoints/users/model.py:
from app import db
class User(db.Model):
# info about the class, requires db
endpoints/users/resource.py:
from flask_restful import Resource
from .model import User
from app import db
class UserResource(Resource):
def get(self, username=None):
# get request, requires db and User
In app.py, since I am importing from endpoints.users.resource after db is created, shouldn't that circumvent the circular dependency?
In addition, I can run this with flask run but when I try to use python app.py, then it gives me the above error. Why would these give different results?
So on from endpoints.users.resource import UserResource line python tries to import from app import db line to app.py which causes app reference to itself, which is not good at all.
One workaround to solve circual import errors in Flask is using init_app function which exists in most of Flask apps. So just create database file like this:
database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app.py
from flask import Flask
from flask_restful import Api
from database import db
from endpoints.users.resource import UserResource
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
api = Api(app)
api.prefix = '/api'
api.add_resource(UserResource, '/users')
if __name__ == '__main__':
app.run(host="0.0.0.0")
endpoints/users/model.py:
from database import db
class User(db.Model):
# info about the class, requires db
endpoints/users/resource.py:
from flask_restful import Resource
from endpoints.users.model import User
from database import db
class UserResource(Resource):
def get(self, username=None):
# get request, requires db and User
Note that I rewrote your imports from related, so don't forget to add __init__.py files
Your structure will be like this:
.
├── app.py
└── database.py/
└── endpoints/
├── __init__.py
└── users/
├── __init__.py
├── model.py
└── resource.py
Trying to run the tutorial here: http://flask-sqlalchemy.pocoo.org/2.1/quickstart/ using my app
I have looked at the circular imports problem but I don't think that's it. I'm an absolute beginner to python and flask (and sqlalchemy). My app currently runs, but the database part doesn't
This is the current setup:
mysite
|- __init__.py
|- flask_app.py
|- models.py
|- views.py
init.py
from flask import Flask
app = Flask(__name__)
flask_app.py
from flask import Flask, request, url_for
import random
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql:// -- database uri --'
... app continues here
models.py
from app import app
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class Foo(db.Model):
... model continues here
views.py
from app import app,models
... views continue here, still not using anything from models
when I run from mysite import db in the python console I get:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'db'
Declare your db object in __init__.py. The stuff that is declared in __init__.py defines what can be imported under mysite/.
See: What is __init__.py for?
Also consider moving to the application factory pattern.
For example in __init__.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['DEBUG'] = True
... more application config ...
db.init_app(app)
return app
Then in flask_app.py:
from mysite import create_app, db
app = create_app()
if __name__ == '__main__':
app.run()
I point this out because you instantiate the app object twice in the code you've shown. Which is definitely wrong.
I use supervisor to run my app. It is structured as follows:
My app layout
my_app
__init__.py
my_app
__init__.py
startup
create_app.py
create_users.py
common_settings.py
core
__init__.py
models.py
views.py
Outer __init__.py
from my_app import app
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
def create_app(extra_config_settings={}):
"""
Initialize Flask applicaton
"""
# ***** Initialize app config settings *****
# Read common settings from 'app/startup/common_settings.py' file
app.config.from_object('app.startup.common_settings')
# Read environment-specific settings from file defined by OS environment variable 'ENV_SETTINGS_FILE'
app.config.from_envvar('ENV_SETTINGS_FILE')
# Load all blueprints with their manager commands, models and views
# Setup Flask-User to handle user account related forms
from my_app.core.models import User
# Setup Flask-User
db_adapter = SQLAlchemyAdapter(db, User) # Setup the SQLAlchemy DB Adapter
user_manager = UserManager(db_adapter, app) # Init Flask-User and bind to app
from my_app import core
return app
my_app/core/__init__.py
from . import models
from . import views
views.py
from my_app import db, app
'''
Register a new user
'''
#app.route('/register', methods = ['POST'])
def register_user():
user_manager = app.user_manager
db_adapter = user_manager.db_adapter
I was trying to follow an example I found online.
I'm creating the variables db_adapter and user_manager in create_app(). Are these the same ones being used in my views.py?
If anyone has any suggestions or links to examples that I can follow to structure my project, it would be greatly appreciated.
Thanks.
Assuming that that's how Flask-User works (sets the user_manager attribute on app), this is trivial to determine, just compare them in the create_app function when you still have a direct reference to the objects.
db_adapter = SQLAlchemyAdapter(db, User)
user_manager = UserManager(db_adapter, app)
assert db_adapter is user_manager.db_adapter
assert user_manager is app.user_manager
However, your entire project layout doesn't make much sense. You should be creating the entire app inside the create_app factory. You should not have an __init__.py file at the top level, that's the project folder not the package. You should use current_app within views to access the app, since it will only be created at runtime by the factory. You should create a manage.py file at the project level to use the factory.
my_project/
my_app/
__init__.py
models.py
views.py
defaults.py
instance/
config.py
manage.py
__init__.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('my_app.defaults')
app.config.from_pyfile('config.py')
db.init_app(app)
from my_app.views import bp
app.register_blueprint(bp)
return app
models.py:
from my_app import db
class User(db.Model):
...
views.py:
from flask import Blueprint, render_template
from my_app.models import User
bp = Blueprint('app', __name__)
#bp.route('/')
def index():
return render_template('index.html')
manage.py:
#!/usr/bin/env python
from flask_script import Manager
from my_app import create_app
Manager(create_app).run()
I working with Flask-Testing and make file test_app.py to test But I got this error File "test_app.py", line 4, in from app import create_app, db ImportError: No module named app.
so please help how can I fix it and what is the problem Thanx :)
here is my Structure:
myapplication
app
__ init __.py
model.py
form.py
autho
layout
static
templates
migrations
test
-test_app.py
config.py
manage.py
test_app.py
#!flask/bin/python
import unittest
from flask.ext.testing import TestCase
from app import create_app, db
from app.model import Users
from flask import request, url_for
import flask
class BaseTestCase(TestCase):
def create_app(self):
self.app = create_app('testing')
return self.app
config.py
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'mytest.sqlite')
__ init __.py
#!flask/bin/python
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.login import LoginManager
import psycopg2
from config import basedir
from config import config
db = SQLAlchemy()
lm = LoginManager()
lm.login_view = 'login'
login_manager = LoginManager()
login_manager.login_view = 'layout.login'
def create_app(config_name):
app = Flask(__name__)
app.config['DEBUG'] = True
app.config.from_object(config[config_name])
db.init_app(app)
login_manager.init_app(app)
# login_manager.user_loader(load_user)
from .layout import layout as appr_blueprint
# register our blueprints
app.register_blueprint(appr_blueprint)
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
return app
From the comments:
There could have been two issues:
The path to myapplication/ hadn't been added to the $PYTHONPATH environment variable (more info here and here)
Let's say the code lives under /home/peg/myapplication/. You need to type in your terminal
export PYTHONPATH=${PYTHONPATH}:/home/peg/myapplication/
__init__.py could have had a typo. There shouldn't be whitespaces between the underscores __ and the init.py chunk (__init__.py is good, __ init __.py is not)