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
Related
I am trying to run the server of this repository (it's about oauth2): https://github.com/lepture/flask-oauthlib/blob/master/tests/oauth2/server.py
The main file looks like this:
if __name__ == '__main__':
from flask import Flask
app = Flask(__name__)
app.debug = True
app.secret_key = 'development'
app.config.update({
'SQLALCHEMY_DATABASE_URI': 'sqlite:///test.sqlite'
})
app = create_server(app)
app.run()
However, I am getting this error:
Error: Failed to find Flask application or factory in module 'hello'. Use 'FLASK_APP=hello:name' to specify one.
I executed the following commands in terminal:
export FLASK_APP=server.py` and
export FLASK_APP=main.py
After that, I tried rerunning with flask run
Again, I am getting this error:
Error: Failed to find Flask application or factory in module 'main'. Use 'FLASK_APP=main:name' to specify one.
Try this code
from flask import Flask
app = Flask(__name__)
app.debug = True
app.secret_key = 'development'
app.config.update({
'SQLALCHEMY_DATABASE_URI': 'sqlite:///test.sqlite'
})
if __name__ == '__main__':
app.run(host="0.0.0.0", port="5000", debug=True)
You should run it directly
python server.py
And if you want to use flask run then you would have to put all (except app.run()) before if __name__ == '__main__': because flask run will import this file and import will skip code inside if __name__ == '__main__':
# ... other code ...
from flask import Flask
app = Flask(__name__)
app.debug = True
app.secret_key = 'development'
app.config.update({
'SQLALCHEMY_DATABASE_URI': 'sqlite:///test.sqlite'
})
app = create_server(app)
if __name__ == '__main__':
app.run()
And it will need export FLASK_APP=server:app because you want to run file server.py and use instance of Flask() with name app
export FLASK_APP=server:app
flask run
Because code uses standard name app so you could skip it in export
export FLASK_APP=server
flask run
You can also run without export
flask --app server run
Try this one:
But I recommend you to start with the basics before work with databases. Try to render HTML templates, use bootstrap, etc. You are running here. Anyway, this boilerplate works for me.
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
# Key for Forms
app.config['SECRET_KEY'] = 'mysecretkey'
# SQL DATABASE AND MODELS
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
Migrate(app, db)
class Puppy(db.Model):
__tablename__ = 'puppies'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text)
def __init__(self, name):
self.name = name
#app.route('/')
def index():
return '<h1>Hello Puppy!</h1>'
if __name__ == '__main__':
app.run(debug=True)
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 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 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.