I Have a Flask webapp im working on. Im using ZODB with Flask-ZODB extension.
I have a small script to initialize some default objects on my database, such as users and the "indexes" that ill be using to store some data the users will submit.
structure looks like:
myproject/
|- myproject/
| |- __init__.py
| |- models.py
| |- views.py
| |- database/
| |- static/
| |- templates/
|
|- run.py
|- setup.py
the setup script looks like this:
[setup.py]
from myproject.models import Usuario
from ZODB.DB import DB
from ZODB.FileStorage import FileStorage
from flask.ext.zodb import BTree
import transaction
# add admin users
superU = Usuario("somemail#gmail.com", "xxx")
admin = Usuario("admin#gmail.com", "yyy")
#create indexes
storage = FileStorage('myproject/database/db.fs')
conn = DB(storage)
db = conn.open().root()
for idx in ['usuarios', 'proyectos', 'informes', 'actividades', 'objetivos', 'usuarios']:
if not idx in db.keys():
db[idx] = BTree()
db['usuarios'][superU.id] = superU
db['usuarios'][admin.id] = admin
for usuario in db['usuarios'].values():
print "Usuario '", usuario.email, "' added..."
transaction.commit();
conn.close();
And the models file
The init file
[_init_.py]
from flask import Flask
from models import Usuario
# configuration
DEBUG = True
SECRET_KEY = 'development key'
USERNAME = 'admin'
PASSWORD = 'default'
app = Flask(__name__)
app.config.from_object(__name__)
from basedatos import Coleccion, Catalogo
coleccion = Coleccion(app)
catalogo = Catalogo()
import myproject.views
[models.py]
from flask import current_app as app
from flask.ext.zodb import Object, List, Dict
from flask_login import UserMixin
from itsdangerous import URLSafeSerializer
from hashlib import sha256
class Usuario(UserMixin):
"""
Usuarios de la aplicacion
"""
def __init__(self, email, password):
self.email = email
self.passwordHash = sha256(password).hexdigest()
self.id = email
def get_auth_token(self):
return URLSafeSerializer(app.secret_key, salt='id salt').dumps(self.id+self.passwordHash)
So the thing is that when I want to run my setup, i get this import error:
Traceback (most recent call last): File "setup.py", line 3, in
from myproject.models import Usuario File "S:\Fuentes\workspace\Python\flaskapps\myproject-app\myproject__init__.py",
line 1, in
from flask import Flask ImportError: No module named flask
When i run the app everything works just fine, i only have this issue when running the script from the console. (im on Windows)
Im closing this one, it was a virtualenv issue. It happens that if you exceute only setup.py or c:\Python27\python.exe setup.py it doesnt look in the sitePackages folder of the active venv. Solution is to call it just > python.exe setup.py
Related
I have been trying to move from using sqlite to sqlalchemy for a project. This has caused me to move many files and I appear to ruined my app routing and I can not explain how. See below for code and file structure. In short the only route I can now get back and working is the Swagger UI I have built and that probably only works because flask does not handle its route to my knowledge. Any help would be much appreciated. Keep in mind I am new to flask so if this is a very stupid issue forgive me, other answers on stackoverflow had eventually led to me creating the create_app function and while that does get the flask site running I imagine the #app.route's are not being called at all.
My file structure is like so:
Project
|--- project.py (Runs the project)
|--- Config.py (Holds the class config)
|--- web
| |--- __init__.py (See below)
| |--- routes.py (Hols the routes)
| |--- api (Swagger ui and other scripts)
| | |--- __init__.py
| | |--- swagger.yaml
My project.py:
from web import create_app
import db
import os
app = create_app()
if __name__ == "__main__":
app.run()
else:
if not os.path.exists("./Project.db"):
print(" * Building Database")
db.build_db()
print(" * Database built")
print(" * Database exists")
My web/init.py:
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from config import Config
import connexion
db = SQLAlchemy()
def create_app():
app = connexion.FlaskApp(__name__, specification_dir="./api")
app.add_api("swagger.yaml")
app = app.app
app.config.from_object(Config)
db.init_app(app)
return app
#migrate = Migrate(app, db)
from web import routes, models
My web/routes.py: (Snipped for brevity)
#! python3
from web import create_app, routes
from web.forms import LoginForm
import web.api
import flask
app = create_app()
#############
# Home URLs #
#############
#app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
return flask.redirect(flask.url_for('home'))
return flask.render_template('login.html', title='Sign In', form=form)
#app.route("/web")
def home():
devices = web.api.devices.get()
for device in devices:
device.update({"model": web.api.models.get_devices_model(device["alias"])["model"]})
return flask.render_template("home.html", devices=devices)
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 have suffered from some problems with my code for a some hours.
I'm sure that it is caused by a circular import issue, but I have another question.
I have two blueprint, auth and main. I just return a render_template without any data passing, and things all go good. But when I try to shwo something in my main.index, suddenly an error occured.
I wonder why it works fine just in auth.views while there does have a circular import issue?
my tree struct
app
|- auth
|- __init__.py
|- forms.py
|- views.py
|- main
|- __init__.py
|- forms.py
|- views.py
|- template
|- __init__.py
|- models.py
config.py
manage.py
datta.sqlite
In auth.__init__.py:
from flask import Blueprint
auth = Blueprint("auth", __name__)
from . import views
and in auth.views.py
from app.auth import auth
from app.models import *
from manage import app
#auth.route('/')
def index():
page = request.args.get("page", 1, type=int)
articles = Article.query.order_by(Article.update_time.desc()).paginate(
page, app.config["ARTICLES_PER_PAGE"], False)
next_url = url_for('auth.index', page=articles.next_num if articles.has_next else None)
prev_url = url_for('auth.index', page=articles.prev_num if articles.has_prev else None)
return render_template('index.html', articles=articles.items,
next_url=next_url, prev_url=prev_url)
In main.__init__.py:
from flask import Blueprint
main = Blueprint("main", __name__)
from . import views
In main.views.py:
from app.main import main
from app.models import *
from manage import app
#main.route('/')
def index():
page = request.args.get("page", 1, type=int)
articles = Article.query.order_by(Article.update_time.desc()).paginate(
page, app.config["ARTICLES_PER_PAGE"], False)
next_url = url_for('main.index', page=articles.next_num if articles.has_next else None)
prev_url = url_for('main.index', page=articles.prev_num if articles.has_prev else None)
return render_template('index.html', articles=articles.items,
next_url=next_url, prev_url=prev_url)
In app.__init__.py:
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
Config.init_app(app)
...
from app.main import main
app.register_blueprint(main)
from app.auth import auth
app.register_blueprint(auth, url_prefix='/auth')
return app
in manage.py
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager, Shell
from app import create_app, db
from app.models import *
app = create_app()
manager = Manager(app)
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)
def make_shell_context():
return dict(db=db, ArticleType=ArticleType, Source=Source,
Article=Article, User=User, Menu=Menu,
ArticleTypeSetting=ArticleTypeSetting)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command("db", MigrateCommand)
if __name__ == '__main__':
app.run(debug=True)
And my traceback are as follow:
Traceback (most recent call last):
File "C:/Users/bohn/Desktop/1pycharm workspace/BlogPoweredByFlask/manage.py", line 7, in <module>
app = create_app()
File "C:\Users\bohn\Desktop\1pycharm workspace\BlogPoweredByFlask\app\__init__.py", line 30, in create_app
from app.main import main
File "C:\Users\bohn\Desktop\1pycharm workspace\BlogPoweredByFlask\app\main\__init__.py", line 5, in <module>
from . import views
File "C:\Users\bohn\Desktop\1pycharm workspace\BlogPoweredByFlask\app\main\views.py", line 5, in <module>
from manage import app
File "C:\Users\bohn\Desktop\1pycharm workspace\BlogPoweredByFlask\manage.py", line 7, in <module>
app = create_app()
File "C:\Users\bohn\Desktop\1pycharm workspace\BlogPoweredByFlask\app\__init__.py", line 33, in create_app
from app.auth import auth
File "C:\Users\bohn\Desktop\1pycharm workspace\BlogPoweredByFlask\app\auth\__init__.py", line 5, in <module>
from . import views
File "C:\Users\bohn\Desktop\1pycharm workspace\BlogPoweredByFlask\app\auth\views.py", line 9, in <module>
from manage import app
ImportError: cannot import name 'app'
The way past this is to use flask.current_app instead of trying to import app.
In main.views, replace
from manage import app
with
from flask import current_app
then, instead of app.config[...], use current_app.config[...]
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
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