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__)))
Related
I have created a flask app.I want to run this both development and production server.
This is my app.py file:
app = Flask(__name__)
db = SQLAlchemy(app)
app.config.from_object(Config)
db.init_app(app)
if __name__ == "__main__":
app.run()
this is my wsgi.py file:
from app import app as application
app = application
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
I want to know if my wsgi configurtion is ok or is it the right way to do it.How can i make sure my production server will run wsgi.py file with the production database configuration?In local i am getting this warning Use a production WSGI server instead.the way i configured willl it ensure it will run on wsgi server in prodcution?While i run this command:
uwsgi --wsgi-file app.py --http :5000
i am getting internal server error in localhost:5000.
One way of handling this is by having a configuration file (config.py) that contains classes for each environment. Then within each of your environments, you'd have a .env file that contains environment-specific variables, such as database URIs, secret keys, etc.
Example config file:
from os import environ, path
from dotenv import load_dotenv
basedir = path.abspath(path.dirname(__file__))
load_dotenv(path.join(basedir, '.env'))
class Config:
"""Base config."""
SECRET_KEY = environ.get('SECRET_KEY')
SESSION_COOKIE_NAME = environ.get('SESSION_COOKIE_NAME')
STATIC_FOLDER = 'static'
TEMPLATES_FOLDER = 'templates'
class ProdConfig(Config):
FLASK_ENV = 'production'
DEBUG = False
TESTING = False
DATABASE_URI = environ.get('PROD_DATABASE_URI')
class DevConfig(Config):
FLASK_ENV = 'development'
DEBUG = True
TESTING = True
DATABASE_URI = environ.get('DEV_DATABASE_URI')
Then, in your application, you can specify which config class you'd like to load.
ENV = environ.get("environment")
# Using a production configuration
if ENV=='PROD':
app.config.from_object('config.ProdConfig')
# Using a development configuration
if ENV=='PROD':
app.config.from_object('config.DevConfig')
For more details, Flask has some docs on this situation
I use a config.py in my flask project to handle login to databases, store secret keys, and such.
example to the the config.py file:
import urllib.parse
import os
class Config:
SECRET_KEY = '123'
#staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
DEV = True
# Configure Database URI:
params = urllib.parse.quote_plus("DRIVER={ODBC};" +
"SERVER=azure.com;" +
"DATABASE=db;" +
"UID=po;" +
"PWD=12345")
SQLALCHEMY_DATABASE_URI = "mssql+pyodbc:///?odbc_connect=%s" % params
and I use it as such:
def create_app(config_name):
app_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
template_path = os.path.join(app_path, 'server/templates/')
static_path = os.path.join(app_path, 'server/static/')
app = Flask(__name__, template_folder=template_path, static_folder=static_path)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
db.init_app(app)
mail.init_app(app)
login_manager.init_app(app)
app.register_blueprint(bp_front)
app.register_blueprint(bp_back)
app.register_blueprint(auth_blueprint, url_prefix='/auth')
return app
Now everything works as expected, but I want to use Gitlab CI for testing, and since I have a test DB which I content to. So how do I get access to settings for connecting without committing the config.py to the repo?
How\Should I configure flask to use environment variables if the tests are executed by Gitlab CI?
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 want to start gunicorn with >> gunicorn wsgi:app.
But I get an error saying ModuleNotFoundError: No module named 'default_config. My virtuel env is activated. I spent hours on google but couldn't find an answer. Even hints are very much appreciated.
Folder structure:
- App
- flask_app
- __init__.py
- factory.py
- default_config.py
- venv (virtual environment)
- wsgi.py
__init__.py => is empty
### wsgi.py ###
from flask_app.factory import create_app
app = create_app('development')
.
### default_config.py ###
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = 'development key'
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
.
### factory.py ###
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from default_config import config
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__, instance_relative_config=True)
app.config.from_object(config[config_name])
app.config.from_pyfile('config.py')
db.init_app(app)
return app
This is because your wsgi file doesn't know the app location by default. You can use relative path like the comment above or you can just add app to your environment path.
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