Correct way to use Flask configuration from_object - python

I'm trying to use debug mode in Flask, but it's crashing every time. Ny config.py file looks like this:
class Config(object):
DEBUG = False
DEVELOPMENT = False
SECRET_KEY = 'do-i-really-need-this'
FLASK_SECRET = SECRET_KEY
SQLALCHEMY_DATABASE_URI = 'host'
class DevConfig(Config):
DEVELOPMENT = True
DEBUG = True
SQLALCHEMY_DATABASE_URI = 'host2'
Then, init.py:
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.from_object('config.DevConfig')
db.init_app(app)
with app.app_context():
# Imports
from . import routes
# Create tables for our models
db.create_all()
return app
And finally, the run file:
from application import create_app
app = create_app()
if __name__ == "__main__":
app.run(host='0.0.0.0')
When I try to run it, following error appears:
* Serving Flask app "application" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
INFO:werkzeug: * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
INFO:werkzeug: * Restarting with stat
Traceback (most recent call last):
File "<ipython-input-1-aaa9539d5209>", line 1, in <module>
runfile('/home/vladimir.balayan/Desktop/scipts/UX/flasksqlalchemy-tutorial-master/wsgi.py', wdir='/home/vladimir.balayan/Desktop/scipts/UX/flasksqlalchemy-tutorial-master')
File "/home/vladimir.balayan/anaconda3/envs/wbe-testing/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 827, in runfile
execfile(filename, namespace)
File "/home/vladimir.balayan/anaconda3/envs/wbe-testing/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/home/vladimir.balayan/Desktop/scipts/UX/flasksqlalchemy-tutorial-master/wsgi.py", line 11, in <module>
app.run(host='0.0.0.0')
File "/home/vladimir.balayan/anaconda3/envs/wbe-testing/lib/python3.7/site-packages/flask/app.py", line 990, in run
run_simple(host, port, self, **options)
File "/home/vladimir.balayan/anaconda3/envs/wbe-testing/lib/python3.7/site-packages/werkzeug/serving.py", line 1007, in run_simple
run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
File "/home/vladimir.balayan/anaconda3/envs/wbe-testing/lib/python3.7/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
sys.exit(reloader.restart_with_reloader())
File "/home/vladimir.balayan/anaconda3/envs/wbe-testing/lib/python3.7/site-packages/werkzeug/_reloader.py", line 159, in restart_with_reloader
args = _get_args_for_reloading()
File "/home/vladimir.balayan/anaconda3/envs/wbe-testing/lib/python3.7/site-packages/werkzeug/_reloader.py", line 76, in _get_args_for_reloading
if __main__.__package__ is None:
AttributeError: module '__main__' has no attribute '__package__'
I already installed python-dotenv module and made .env file with FLASK_ENV=development, but the error is the same.
I'm using Spyder IDE for debugging and this tutorial

If your application structure is the same as shown in the tutorial you are following, try changing your config.py to this
from os import environ, path
basedir = path.abspath(path.dirname(__file__))
class Config(object):
DEBUG = False
DEVELOPMENT = False
SECRET_KEY = environ.get('SECRET_KEY') or \
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'
FLASK_SECRET = SECRET_KEY
class DevConfig(Config):
DEVELOPMENT = True
DEBUG = True
SQLALCHEMY_DATABASE_URI = environ.get('SQLALCHEMY_DATABASE_URI') or \
'sqlite:///' + os.path.join(basedir, 'db.sqlite')
class ProdConfig(Config):
DEVELOPMENT = True
DEBUG = True
SQLALCHEMY_DATABASE_URI = environ.get('SQLALCHEMY_DATABASE_URI') or \
'sqlite:///' + os.path.join(basedir, 'db.sqlite')
config = {
'dev': DevConfig,
'prod': ProdConfig,
'default': DevConfig,
}
And then your __init__.py to this
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config
db = SQLAlchemy()
def create_app(config_name):
"""Construct the core application."""
app = Flask(__name__)
app.config.from_object(config.get(config_name or 'default'))
db.init_app(app)
with app.app_context():
# Imports
from . import routes
# Create tables for our models
db.create_all()
return app
Then in your run.py or whatever file you are using to launch the application you could do this
from os import environ
from application import create_app
app = create_app(environ.get('FLASK_CONFIG'))
if __name__ == "__main__":
app.run(host='0.0.0.0')
Hope this helps.

Related

'AttributeError: module '__main__' has no attribute '__package__'

I was trying to build flask-web API. When I am trying to run the app.py code, I have got this error, please refer the code which I have mentioned below. Do I have to install some package to get 'package' into 'main'?
I tried to run in different platforms such jupyter notebook, spyder and Google Colab too, but it didn't work, and getting similar issues.
Here is my app.py code whic is giving error:
from flask import Flask, request, jsonify, render_template
import pickle
app = Flask(__name__)
model = pickle.load(open('model.pkl', 'rb'))
#app.route('/')
def home():
return render_template('index.html')
#app.route('/predict',methods=['POST'])
def predict():
'''
For rendering results on HTML GUI
'''
int_features = [int(x) for x in request.form.values()]
final_features = [np.array(int_features)]
prediction = model.predict(final_features)
output = round(prediction[0], 2)
return render_template('index.html', prediction_text='Employee Salary should be $ {}'.format(output))
#app.route('/predict_api',methods=['POST'])
def predict_api():
'''
For direct API calls trought request
'''
data = request.get_json(force=True)
prediction = model.predict([np.array(list(data.values()))])
output = prediction[0]
return jsonify(output)
if __name__ == "__main__":
app.run(debug=True)
Here is the error message I have got:
* Serving Flask app "__main__" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Restarting with stat
Traceback (most recent call last):
File "<ipython-input-21-3add8626fce0>", line 36, in <module>
app.run(debug=True)
File "C:\Users\ishwo\Anaconda3\lib\site-packages\flask\app.py", line 990, in run
run_simple(host, port, self, **options)
File "C:\Users\ishwo\Anaconda3\lib\site-packages\werkzeug\serving.py", line 1007, in run_simple
run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
File "C:\Users\ishwo\Anaconda3\lib\site-packages\werkzeug\_reloader.py", line 332, in run_with_reloader
sys.exit(reloader.restart_with_reloader())
File "C:\Users\ishwo\Anaconda3\lib\site-packages\werkzeug\_reloader.py", line 159, in restart_with_reloader
args = _get_args_for_reloading()
File "C:\Users\ishwo\Anaconda3\lib\site-packages\werkzeug\_reloader.py", line 76, in _get_args_for_reloading
if __main__.__package__ is None:
AttributeError: module '__main__' has no attribute '__package__'}

Populating FlaskForm from SQLAlchemy DB, returns an error:

I'm debugging an error, when I try to query from my database to populate the fields of my FlaskForm, I get the following error:
Traceback (most recent call last):
File "manage.py", line 16, in <module>
app = create_app(os.getenv('DVR_CONFIG') or 'default')
File "C:\Users\---\myapp\\app\__init__.py", line 42, in create_app
from .main import main as main_blueprint
File "C:\Users\---\myapp\\app\main\__init__.py", line 5, in <module>
from . import views, errors
File "C:\Users\---\myapp\\app\main\views.py", line 5, in <module>
from .forms import CharacterSelect
File "C:\Users\---\myapp\\app\main\forms.py", line 15, in <module>
class CharacterSelect(FlaskForm):
File "C:\Users\---\myapp\\app\main\forms.py", line 17, in CharacterSelect
user = User.query.filter_by(unique_name=session.get('unique_name')).first()
File "C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py", line 500, in __get__
return type.query_class(mapper, session=self.sa.session())
File "C:\Python27\lib\site-packages\sqlalchemy\orm\scoping.py", line 78, in __call__
return self.registry()
File "C:\Python27\lib\site-packages\sqlalchemy\util\_collections.py", line 990, in __call__
return self.registry.setdefault(key, self.createfunc())
File "C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py", line 771, in create_session
return SignallingSession(self, **options)
File "C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py", line 153, in __init__
self.app = app = db.get_app()
File "C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py", line 922, in get_app
raise RuntimeError('application not registered on db '
RuntimeError: application not registered on db instance and no application bound to current context
Here is the offending code:
from ..models import User
class CharacterSelect(FlaskForm):
user = User.query.filter_by(unique_name=session.get('unique_name')).first()
charId0 = user.characterId_0
charId1 = user.characterId_1
charId2 = user.characterId_2
user_list = [charId0, 'Char0', charId1, 'Char1', charId2, 'Char2']
new_user_list = [x for x in user_list if x is not None]
selectedUser = SelectField(u'Character Select', choices=user_list)
From researching this error, it appears Flask doesn't know which app my DB is attached to. Also most of the stackoverflow answers I have seen recommend using:
with app.app_context():
:
:
db.create_all()
However, from working through Miguels Flask Book and Flasky blog, he doesn't seem to need to use "with app.app_context()" and only uses "db.create_all()" in his unit test code. Miguel inits the DB like so:
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
:
:
db.init_app(app)
Any help in debugging and understanding this error is much appreciated!
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
db.init_app(app)
return app
Many things are nor clear from your code snippet. What is obvious however is that you have to have your db.init_app(app) inside your create_app() function. Then you would return app object from the function. Most preferably in different module i.e. manage.py (this really depends on your application structure)
from somewhere import create_app
app = create_app(config_name)
if __name__ == "__main__":
app.run()
Now variable app is your application instance with db registered.
Someone has pointed me to the FlaskForm Docs, where the is a pretty sparse example.
Esentially I need to create the tuple list in my views.py and pass it into my Form Object, see below for details:
views.py:
user = g.user
charId0 = user.characterId_0
charId1 = user.characterId_1
charId2 = user.characterId_2
user_list = [(charId0, 'Char0'), (charId1, 'Char1'), (charId2, 'Char2')]
form = CharacterSelect(request.form)
form.selectedUser.choices = user_list
forms.py:
class CharacterSelect(FlaskForm):
selectedUser = SelectField(u'Character Select', choices=[])

python-logstash error thrown while running locally

If I import logstash, running locally I get the following error
Connected to pydev debugger (build 162.1812.1)
/home/vagrant/.envs/emailservice/lib/python3.4/site-packages/flask/exthook.py:71: ExtDeprecationWarning: Importing flask.ext.cache is deprecated, use flask_cache instead.
.format(x=modname), ExtDeprecationWarning
Traceback (most recent call last):
File "/home/vagrant/.pycharm_helpers/pydev/pydevd.py", line 1580, in <module>
globals = debugger.run(setup['file'], None, None, is_module)
File "/home/vagrant/.pycharm_helpers/pydev/pydevd.py", line 964, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/home/vagrant/.pycharm_helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/emailService/app.py", line 59, in <module>
import logstash
File "/home/vagrant/.envs/emailservice/lib/python3.4/site-packages/logstash/__init__.py", line 2, in <module>
from event import Event
ImportError: No module named 'event'
Process finished with exit code 1
my app.py file looks mostly like this. I run it locally through a vagrant session. If I remove the import logstash from the local branch of the if, the application starts up fine and I get local console log output.
import logging
import os
import sys
from flask import Flask
from flask_restful import Api
from flask_cache import Cache
from flask_sqlalchemy import SQLAlchemy
from opbeat.contrib.flask import Opbeat
from tasks import make_celery
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', 'SUCHSECRETSWOW')
app.config.from_object(os.environ.get('APP_SETTINGS', 'config.DevelopmentConfig'))
cache = Cache(app)
db = SQLAlchemy(app)
api = Api(app)
celery = make_celery(app)
if len(app.config['OPBEAT_ORGANIZATION_ID']):
opbeat = Opbeat(
app,
organization_id=app.config['OPBEAT_ORGANIZATION_ID'],
app_id=app.config['OPBEAT_APP_ID'],
secret_token=app.config['OPBEAT_SECRET_TOKEN'],
)
#app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
return response
def clear_cache():
cache.clear()
def start_resources():
from emailService.api import HealthApi
api.add_resource(HealthApi, '/health')
def start_tasks():
from emailService.tasks import KickoffFetchEmailPeriodTask
if __name__ == '__main__':
if app.config.get('DEVELOPMENT', False):
#The reason this exists is purely because of my error.
import logstash
app.logger.setLevel(logging.DEBUG)
app.logger.addHandler(logging.StreamHandler())
else:
import logstash
app.logger = logging.getLogger('python-logstash-logger')
app.logger.setLevel(logging.INFO)
app.logger.addHandler(logstash.LogstashHandler('myhost.veryhost.suchhost', 5959, version=1))
app.logger.addHandler(logging.StreamHandler())
clear_cache()
start_tasks()
start_resources()
app.logger.debug('Starting app')
app.run(host='0.0.0.0', port=16600, debug=True, use_reloader=False)
All of the google searches result in a great big fat sum total of nothing helpful.
You're probably running into this issue, you have pip installed logstash instead of python-logstash
Run this and it should work afterwards:
> pip uninstall logstash
> pip install python-logstash

Flask-Migrate Error: 'ConfigParser.NoSectionError: No section: 'alembic''

For the last few weeks I've been building a website mostly based on Miguel Grinberg's book 'Flask Web Development'. This is my 'manage.py' file for reference:
import os
from app import create_app, db
from app.models import User, Role, Permission, Post
from flask.ext.script import Manager, Shell
from flask.ext.migrate import Migrate, MigrateCommand
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
return dict(app=app, db=db, User=User, Follow=Follow, Role=Role,
Permission=Permission, Post=Post)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
And this is my app/__init.py file:
from flask import Flask #session, flash, url_for
from flask.ext.mail import Mail
from flask.ext.moment import Moment
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.login import LoginManager
from config import config
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
mail = Mail()
moment = Moment()
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
login_manager.init_app(app)
mail.init_app(app)
moment.init_app(app)
db.init_app(app)
from main import main as main_blueprint
from .auth import auth as auth_blueprint
app.register_blueprint(main_blueprint)
app.register_blueprint(auth_blueprint, url_prefix = '/auth')
return app
As you can see it's a relatively bare-bones project, but it was going well until a few days ago when I accidentally deleted my migrations folder, which up until that point was working without perfectly fine. When I attempted to set up the migrations folder again, I got this error:
(website1)joshua#joshua-ThinkPad-Edge-E430 ~/website/website1 $ python manage.py db migrate
Traceback (most recent call last):
File "manage.py", line 29, in <module>
manager.run()
File "/home/joshua/.virtualenvs/website1/lib/python2.7/site-packages/flask_script/__init__.py", line 412, in run
result = self.handle(sys.argv[0], sys.argv[1:])
File "/home/joshua/.virtualenvs/website1/lib/python2.7/site-packages/flask_script/__init__.py", line 383, in handle
res = handle(*args, **config)
File "/home/joshua/.virtualenvs/website1/lib/python2.7/site-packages/flask_script/commands.py", line 216, in __call__
return self.run(*args, **kwargs)
File "/home/joshua/.virtualenvs/website1/lib/python2.7/site-packages/flask_migrate/__init__.py", line 153, in migrate
config = _get_config(directory, opts=['autogenerate'])
File "/home/joshua/.virtualenvs/website1/lib/python2.7/site-packages/flask_migrate/__init__.py", line 51, in _get_config
config.set_main_option('script_location', directory)
File "/home/joshua/.virtualenvs/website1/lib/python2.7/site-packages/alembic/config.py", line 201, in set_main_option
self.file_config.set(self.config_ini_section, name, value)
File "/home/joshua/anaconda/lib/python2.7/ConfigParser.py", line 753, in set
ConfigParser.set(self, section, option, value)
File "/home/joshua/anaconda/lib/python2.7/ConfigParser.py", line 396, in set
raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'alembic'
I'm not really sure what to do about this, I've tried dropping then re-creating my database and running db migrate again but I got the same error as before. I also tried uninstalling and reinstalling alembic but with no luck.
I'm not really sure what do do at this point, up until now whenever I've had an issue with the tutorial I took the time to figure it out on my own since I want to understand how everything works, but I'm totally stumped on this one.
Courtesy Dauros: I neglected to run python manage.py db init.

"Directory migrations already exists" during init on Heroku

I ran the command heroku run init and got this error. How can I fix it?
manager.run()
File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/__init__.py", line 412, in run
result = self.handle(sys.argv[0], sys.argv[1:])
File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/__init__.py", line 383, in handle
res = handle(*args, **config)
File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/commands.py", line 216, in __call__
return self.run(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/flask_migrate/__init__.py", line 61, in init
command.init(config, directory, 'flask')
File "/app/.heroku/python/lib/python2.7/site-packages/alembic/command.py", line 28, in init
raise util.CommandError("Directory %s already exists" % directory)
alembic.util.CommandError: Directory migrations already exists
manage.py:
app = create_app(os.environ.get('FLASK_CONFIG', 'default'))
magrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
#manager.command
def init_db():
db.drop_all()
db.create_all()
config.py:
class Config(object):
DEBUG = False
SECRET_KEY = 'Thisismysecretkey'
SQLALCHEMY_DATABASE_URI = os.environ.get(
'DATABASE_URL',
'postgresql+psycopg2://peg:1234#localhost/app')
print SQLALCHEMY_DATABASE_URI
class HerokuConfig(ProductionConfig):
def init_app(cls, app):
ProductionConfig.init_app(app)
import logging
from logging import StreamHandler
file_handler = StreamHandler()
file_handler.setLevel(logging.WARNING)
app.logger.addHandler(file_handler)
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'heroku': HerokuConfig,
'default': DevelopmentConfig
}
You appear to be trying to run manage.py db init again. Don't do that, the migration directory and migrations already exist in the application you've already built. Instead, run manage.py db upgrade.

Categories