I have a website I've been writing using Flask, although for this question I do not think that's relevant. This is the folder structure I'm working with. Rhea is the name of the project and the parent directory.
Rhea
|- Scripts
|-script1.py
|- Static
|- Templates
|- __init__
My problem is I declare variables inside my init that I need to use inside script1.py. How do I import these into script1.py?
For reference this is my init file
import os
from flask import Flask
from flask_appconfig import AppConfig
from flask_bootstrap import Bootstrap
from flask.ext.sqlachemy import SQLAlchemy
from .frontend import frontend
from .nav import nav
from .models import User
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'db', 'userdb.db')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db')
WTF_CSRF_ENABLED = True
BOOTSTRAP_SERVE_LOCAL = True
SECRET_KEY = --SNIP--
app = Flask(__name__)
app.config.from_object(__name__)
AppConfig(app)
Bootstrap(app)
db = SQLAlchemy(app)
app.register_blueprint(frontend)
nav.init_app(app)
app.run(host='0.0.0.0', port=6060, debug=False);
return app
The variables I need is db, SQLALCHEMY_DATABASE_URI, and the SQLALCHEMY_MIGRATE_REPO.
Thank's for any help.
A solution is to append the the sys.path with the Rhea's package parent directory. But it's ugly.
# cript1.py
import os
import sys
rhea_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
sys.path.append(rhea_dir)
import Rhea
print Rhea.SQLALCHEMY_DATABASE_URI
Related
I'm trying to write some unit tests for a flask application I made. The project is setup like this:
apiproject (parent folder containing everything)
/venv
run.py
requirements.txt
/project
__init__.py
/departments
__init__.py
routes.py
models.py
/users
__init__.py
routes.py
models.py
/tests
TestUsers.py
run.py:
from project import app
if __name__ == '__main__':
app.run(debug=True)
my actual app is created under project/init.py
from flask import Flask, jsonify, Response
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import os
from dotenv import load_dotenv
from flask_cors import CORS
load_dotenv(verbose=False)
DB_URL = os.getenv("DATABASE_URL")
# initialize the application
app = Flask(__name__)
and in my TestUsers.py I have this:
import json
from project import app
import unittest
from dotenv import load_dotenv
load_env(verbose=False)
class TestUsers(unittest.TestCase):
def setUp(self):
self.app = app
self.url_prefix = prefix = os.getenv("URL_PREFIX")
self.client = self.app.test_client()
def test_index(self):
response = self.client.get(self.url_prefix + '/')
self.assertEqual(response.status_code, 200)
if __name__ == '__main__':
unittest.main()
When I run TestUsers.py, I get ModuleNotFoundError: No module named 'project'. I tried doing sys.path.append('../') and ../../ inside of TestUsers.py, but that didn't help.
inside TestUsers.py, before importing app:
https://stackoverflow.com/a/22737042/7858114
I think you need an init.py in your apiproject folder too.
I am trying to initialise my db, and everytime i run the flask db init command, I get that error.
I am unsure why, my FLASK_APP and FLASK_ENV are set correctly.
I have been reorganising the project structure and file names to abide more with the flask guidelines in the moments before this.
run.py
from app import app
app.run(debug=True)
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = True
init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
migrate = Migrate(app, db)
from app import views, models
db_create.py
from config import SQLALCHEMY_DATABASE_URI
from app import db
import os.path
db.create_all()
models.py
from app import db
class Property(db.Model):
id = db.Column(db.Integer, primary_key=True)
address = db.Column(db.String(500), index=True, unique=True)
start_date = db.Column(db.DateTime)
duration = db.Column(db.Integer)
rent = db.Column(db.Float)
views.py
from app import app
from flask import render_template
#app.route('/')
def index():
return render_template('index.html')
Error:
$ flask db init
Usage: flask db init [OPTIONS]
Error: Could not import "app.run".
edit: Folder structure so you can understand better:
config.py
run.py
app/
__init__.py
db_create.py
models.py
views.py
static/
templates/
index.html
layout.html
adding again: The issue is not running my code, it is when I am trying to initialise my db using flask db init
I get the error in my terminal when trying to run this, hoping someone can help me figure out why and then fix it, thanks for reading :)
Please make sure that your working directory is not inside your flask app app/.
flask_app/
config.py
run.py
app/
__init__.py
db_create.py
models.py
views.py
static/
templates/
index.html
layout.html
In this case, your working directory should be flask_app/.
you need to check the flask app variable again with echo $FLASK_APP.
In Miguel's Tutorial, FLASK_APP is set in .flaskenv, however you need to make sure that FLASK_APP is really set to your starter file. I had the default value set to run.py, which impaired starting up the migration repo. so set it with export FLASK_APP=<your-app-starter-file>.py.
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
I have the following flask app:
main.py
from application import create_app
app = create_app('flask.cfg')
application/init.py
def create_app(config_filename=None):
app = Flask(__name__, instance_relative_config=True)
app.config.from_pyfile(config_filename)
instance/flask.cfg
import os
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = os.environ.get(
'DATABASE_URL') or 'sqlite:///' + os.path.join(basedir, 'database/app.db')
My problem with this setup: basedir resolves to the instance folder and not to the basedir of my project where my database folder is located.
Whats the best way to handle this?
__file__ is the same directory that your file is in.
You used __file__ in instance/flask.cfg so it refers to instance/ where flask.cfg is!
All you need is going one step back to your project directory cause
your main.py is in the project directory
You need to do something like this:
basedir = os.path.abspath(os.path.join('../', os.path.dirname(__file__)))
Also this will work
basedir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
I'm creating a personal application with flask_restful, and I was doing everything with a single models.py and app.py, but the application is going to grow so I decided to make some folder restructuring.
I currently have the following structure:
/project_folder
application_name
__init__.py
controllers.py
models.py
config.py
manage.py
run.py
tests
__init__.py
test_controller.py
Everything works so far, but I want the structure to be the following:
/project_folder
application_name
__init__.py
controllers
__init__.py
brewery_controller.py
...others
models
__init__.py
base_model.py
brewery.py
...others
config.py
manage.py
run.py
tests
__init__.py
test_controller.py
But I can't seem to make it work. Here is the application __init__.py
#/project_folder/application_name/__init__.py
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api
from controllers import BreweryList, BreweryResource
from models import db
def initApp(config):
app = Flask(__name__)
app.config.from_object(config)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
api = Api(app)
api.add_resource(BreweryList, '/breweries')
api.add_resource(BreweryResource, '/breweries/<brewery_id>')
return app
I tried with
from brewery_controller import BreweryList, BreweryResource
from base_model import db
with no luck. I keep getting ImportError: cannot import BreweryList and the same goes for db if I uncomment the Brewery classes import line.
The controllers/__init__.py and models/__init__.py are both empty.
Here is also the run.py
import os
from beerinv import initApp
if __name__ == '__main__':
app = initApp(os.environ['APP_SETTINGS'])
app.run()
Could solve the issue by following #davidism comment by putting full import path:
from application_name.controllers.brewery_controller import BreweryList, BreweryResource
from application_name.models.base_model import db