FlaskApp has no attribute 'config' - python

all. I writing project using Flask, SQLAlchemy, and connexion. Before connexion was implemented, all works success (p.s. when app created as app = Flask(__name__). After implementing connexion raises an exception:
'SQLALCHEMY_DATABASE_URI' not in app.config and AttributeError: 'FlaskApp' object has no attribute 'config'. So where is a mistake? Help, please.
run.py:
from app import create_app
app = create_app('development')
if __name__ == '__main__':
app.run()
app:
...
from settings import app_config
db = SQLAlchemy()
def create_app(config_name):
# app = Flask(__name__)
app = connexion.App(__name__)
app.add_api('swagger.yml')
application = app.app
application.config.from_object(app_config[config_name])
application.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
return app
settings.py
class BaseConfig(object):
DEBUG = False
CSRF_ENABLED = True
SECRET = os.getenv('SECRET', 'default_secret_key')
DEFAULT_URI = 'postgresql://shooter:shooter#localhost/shooterstats'
SQLALCHEMY_DATABASE_URI = DEFAULT_URI
class DevelopmentConfig(BaseConfig):
DEBUG = True

There was a mistake here db.init_app(app). I changed it to db.init_app(application) and it is working success now.

Here is one way you can set up your Flask application with Connexion.
import connexion
# This creates the connexion application instance.
connexion_app = connexion.App(__name__)
# This gets the underlying Flask app instance.
flask_app = connexion_app.app # Flask(__name__)
🤠

Related

Trouble running Flask alongside uWSGI/Nginx

I'm currently facing issues running my Flask app, and I suspect it's related to a recent restructure of my main app files. I'm struggling to identify the source of the problem and would greatly appreciate any assistance.
When I try to run the app using the flask run command, the website is only accessible on the default port 5000. Attempting to access the website at http://127.0.0.1:5000/ results in the error message "This site can't be reached 127.0.0.1 refused to connect."
I've tried changing the port number in the run.py file to a custom value, but despite updating the code, the logs still indicate that the app is using port 5000. Additionally, I've verified that port 5000 isn't being used by any other process.
I have tried disabling the firewall and verifying that there are no other network issues, but the problem still persists.
I'm uncertain whether the issue is with my code or the server configuration, but I suspect it may be related to the recent restructuring of the main app files.
Notably, uWSGI has no problem running on the domain or IP address.
Any insights or solutions to this issue would be greatly appreciated. Thank you for your help.
Below, I have provided the relevant code for context:
Evidenca-2.0/wsgi.ini
[uwsgi]
module = wsgi:app
master = true
processes = 5
socket = wsgi.sock
chmod-socket = 660
vacuum = true
die-on-term = true```
Evidenca-2.0/wsgi.py
from run import app
if __name__ == '__main__':
app.run()
Evidenca-2.0/run.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_minify import Minify
import os
import logging
from apps.config import config_dict
from apps import create_app, db
# Configure the app
app_config_mode = os.getenv('FLASK_ENV', 'development')
try:
app_config = config_dict[app_config_mode.capitalize()]
except KeyError:
logging.warning(f'Invalid config mode: {app_config_mode}. Defaulting to development mode.')
app_config = config_dict['Development']
app = create_app(app_config)
# Initialize extensions
db = SQLAlchemy()
migrate = Migrate(app, db)
minify = Minify(app=app, html=True, js=False, cssless=False)
# Configure logging
log_file_name = 'app.log'
if app_config.DEBUG:
log_level = logging.DEBUG
else:
log_level = logging.INFO
logging.basicConfig(filename=log_file_name, level=log_level)
if app_config.DEBUG:
logging.debug(f'DEBUG = {app_config.DEBUG}')
logging.debug(f'FLASK_ENV = {os.getenv("FLASK_ENV")}')
logging.debug(f'Page Compression = {"FALSE" if app_config.DEBUG else "TRUE"}')
logging.debug(f'DBMS = {app_config.SQLALCHEMY_DATABASE_URI}')
logging.debug(f'ASSETS_ROOT = {app_config.ASSETS_ROOT}')
logging.debug(f'UPLOAD_FOLDER = {app_config.UPLOAD_FOLDER}')
# Start the app
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8000, threaded=True)
Evidenca-2.0/apps/config.py:
import os
from sqlalchemy import create_engine
from flask import Flask
class Config:
basedir = os.path.abspath(os.path.dirname(__file__))
# Set up the App SECRET_KEY
SECRET_KEY = os.getenv('SECRET_KEY', 'S#perS3crEt_007')
# Set up the database configuration
SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI', 'mysql+pymysql://aviat:admin#localhost/Evidenca')
SQLALCHEMY_TRACK_MODIFICATIONS = False
# Flask-User settings
USER_APP_NAME = "Flask-User QuickStart App" # Shown in and email templates and page footers
USER_ENABLE_EMAIL = False # Disable email authentication
USER_ENABLE_USERNAME = True # Enable username authentication
USER_REQUIRE_RETYPE_PASSWORD = False # Simplify register form
# Assets Management
ASSETS_ROOT = os.getenv('ASSETS_ROOT', '/static/assets')
# File Upload
UPLOAD_FOLDER = os.getenv('UPLOAD_FOLDER', '/uploads')
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# Set up logging
LOG_FILE_NAME = os.getenv('LOG_FILE_NAME', 'app.log')
LOG_LEVEL = os.getenv('LOG_LEVEL', 'DEBUG')
# Set up the MariaDB database engine
ENGINE = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)
# Set up the app configuration
DEBUG = os.getenv('DEBUG', False)
SESSION_COOKIE_HTTPONLY = True
REMEMBER_COOKIE_HTTPONLY = True
REMEMBER_COOKIE_DURATION = 3600
if DEBUG:
print('DEBUG = ' + str(DEBUG))
print('FLASK_ENV = ' + os.getenv('FLASK_ENV'))
print('Page Compression = FALSE')
print('DBMS = ' + SQLALCHEMY_DATABASE_URI)
print('ASSETS_ROOT = ' + ASSETS_ROOT)
print('UPLOAD_FOLDER = ' + UPLOAD_FOLDER)
class ProductionConfig(Config):
DEBUG = False
class DevelopmentConfig(Config):
DEBUG = False
class DebugConfig(Config):
DEBUG = True
# Load all possible configurations
config_dict = {
'Production': ProductionConfig,
'Development': DevelopmentConfig,
'Debug': DebugConfig
}
Evidenca-2.0/apps/_init_.py:
# -*- encoding: utf-8 -*-
"""
Copyright (c) 2023 - Aviat Networks
This module sets up the main application and initializes its components. It also
registers the necessary extensions and blueprints for the application.
"""
from flask import Flask
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from importlib import import_module
# Initialize flask app, SQLAlchemy database, and LoginManager
app = Flask(__name__)
db = SQLAlchemy()
login_manager = LoginManager()
def register_extensions(app):
"""
Register the necessary extensions for the application.
"""
db.init_app(app)
login_manager.init_app(app)
def register_blueprints(app):
"""
Register the blueprints for the application.
"""
for module_name in ('authentication', 'inventory'):
module = import_module('apps.{}.routes'.format(module_name))
if module_name == 'authentication':
app.register_blueprint(module.auth_bp, url_prefix='/auth')
if module_name == 'inventory':
app.register_blueprint(module.inventory_blueprint)
def configure_database(app):
"""
Configure the database for the application.
"""
# Initialize the database before the first request
#app.before_first_request
def initialize_database():
db.create_all()
# Remove database session after each request
#app.teardown_request
def shutdown_session(exception=None):
db.session.remove()
def create_app(config):
"""
Create and configure the Flask application.
:param config: The configuration object for the application.
:return: The Flask application instance.
"""
app = Flask(__name__)
app.config.from_object(config)
register_extensions(app)
register_blueprints(app)
configure_database(app)
return app
The odd thing is that it works, if I set it up like this: flask run -h 192.168.X.X How come it doesn't work on localhost?

A secret key is required to use CSRF Linode server, gunicorn, nginx error Flask

I have looked at similar questions to this one and haven't found a solution yet. My flask app (a personal website) runs with full functionality on the local server but when I try to run it on the IP address at port 5000 the contactme page (the only page with forms) returns the runtime error in the title. I have my secret key in the directory /etc/config.json and my config.py, __init__.py, and run.py code is below:
run.py
from personalwebsite import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
init.py:
from flask import Flask
from flask_mail import Mail # this package allows us to send an email when the contact form is filled out
from flask_sqlalchemy import SQLAlchemy # Package for our database ORM
from personalwebsite.config import Config
# Instantiate/Create the database
db = SQLAlchemy()
mail = Mail() # Instantiate our Mail object
def create_app(config_class=Config):
app = Flask(__name__) # Instantiate the app
app.config.from_object(Config)
# Imports all routes from the routes.py file
db.init_app(app)
mail.init_app(app)
from personalwebsite.contact.routes import contacts
from personalwebsite.main.routes import main
from personalwebsite.projects.routes import projects
from personalwebsite.resume.routes import resume
app.register_blueprint(contacts)
app.register_blueprint(main)
app.register_blueprint(projects)
app.register_blueprint(resume)
return app
And config.py:
import os
import json
with open('/etc/config.json') as config_file:
config=json.load(config_file)
class Config:
SECRET_KEY = config.get('SECRETKEY')
SQLALCHEMY_DATABASE_URI = "sqlite:///site.db"
MAIL_SERVER = 'smtp.googlemail.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = config.get('EMAILUSERNAME')
MAIL_PASSWORD = config.get('EMAILKEY')
I'm not really sure what is wrong here and have been trying to deploy this simple website for the last few days. Any help is appreciated!

AttributeError: 'NoneType' object has no attribute 'drivername' URI config implementation wrong

I see a lot of people with this error but nothing fixes it for me. I'm using a config.py file to hold my config classes. This seems to be where the issue lies. I'm also using the application factory pattern. I call the object in my __init__.py:
from flask import Flask, request
from flask_restful import Api, Resource, reqparse, abort
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_marshmallow import Marshmallow
import config
# Globally accessible libraries
db:SQLAlchemy = SQLAlchemy()
api:Api = Api()
migrate:Migrate = Migrate()
ma:Marshmallow = Marshmallow()
def init_app():
"""Initialize the core application."""
app = Flask(__name__, instance_relative_config=False)
app.config.from_object(config.Config)
# Initialize Plugins
db.init_app(app)
api.init_app(app)
migrate.init_app(app, db)
ma.init_app(app)
with app.app_context():
# Include our Routes
And when I run the program I get this error
File "/home/sai/.local/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py", line 933, in apply_driver_hacks
if sa_url.drivername.startswith('mysql'):
AttributeError: 'NoneType' object has no attribute 'drivername'
Here is my config.py:
import os
from pickle import TRUE
class Config(object):
DEBUG = False
TESTING = False
CSRF_ENABLED = True
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL")
SQLALCHEMY_TRACK_MODIFICATIONS = False
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SECRET_KEY = os.environ.get("SECRET_KEY")
class ProductionConfig(Config):
DEBUG = False
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(Config):
ENV = "development"
DEBUG=True
TESTING = True
DEVELOPMENT = True
SQLALCHEMY_TRACK_MODIFICATIONS = False
class SetupConfig(DevelopmentConfig):
SQLALCHEMY_DATABASE_URI = "sqlite:///database.db"
I'm using the default .env loader that flask provides described here and I made sure my uri in my .env didn't have quotes around it just like the guide I used. Here is a snippet of .env:
DEBUG=True
FLASK_ENV=development
FLASK_APP=wsgi.py
DATABASE_URL = mysql+pymysql://user:password#host/main
The only thing that gets my app to run is if I hard code the URI with app.config['SQLALCHEMY_DATABASE_URI'} = ... but that solution doesn't help me as I don't want to push the URI to a public repo. I've spent 4 hours of my day just moving things around hoping to fix it and I'm genuinely just lost. Any help would be hugely appreciated thank you!
I think you might need to put load_env() in your Config class. I understand that flask has it's own way to reading .env files but maybe try it.

Logging Flask Application in Heroku

I am trying to find a way to structure my code such that I can view logs in the production server hosted on Heroku.
Every tutorial I found seems to do logging like this:
How to show stdout logs in Heroku using Flask?
However, I am using the application factory pattern which utilizes Blueprints. As such here are some sample:
main.py
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run()
app/_ _ init _ _.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
...
db = SQLAlchemy()
...
def create_app():
app = Flask(__name__)
...
db.init_app(app)
from .routes.demo_blueprint import demo_blueprint
...
# Register the routes to the Flask object
app.register_blueprint(demo_blueprint)
...
app/routes/demo_blueprint.py
from app import db
...
demo_blueprint = Blueprint('demo_blueprint', __name__)
#demo_blueprint.route('/demo', methods=['GET'])
...
In order to perform logging at the blueprint level, I would need to import app from main.py. However, this would cause an import error since __init__.py imports the blueprint before app is created. I was wondering if there were any work arounds for this.
Turns out it was a simple fix. To access the application context in the Blueprint, just use current_app. Following the example:
How to show stdout logs in Heroku using Flask?
main.py
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run()
app/_ _ init _ _.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
...
db = SQLAlchemy()
...
def create_app():
app = Flask(__name__)
if __name__ != '__main__':
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
...
db.init_app(app)
from .routes.demo_blueprint import demo_blueprint
...
# Register the routes to the Flask object
app.register_blueprint(demo_blueprint)
...
app/routes/demo_blueprint.py
from flask import ***current_user***
from app import db
...
demo_blueprint = Blueprint('demo_blueprint', __name__)
#demo_blueprint.route('/demo', methods=['GET'])
def demo():
current_app.logger.debug('debug message: %s', 'test')
...

ResponseError: operation not permitted

import config
from flask import Flask
from flask_redis import Redis
from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)
redis_store = Redis(app)
app.debug = config.DEBUG
app.redis_url = config.REDIS_URL
#app.route('/')
def index():
return redis_store.ping()
app.wsgi_app = ProxyFix(app.wsgi_app)
if __name__ == '__main__':
app.run()
config.py
DEBUG = True
REDIS_URL = "redis://:123#localhost:6379/0"
/etc/redis/redis.conf
...
requirepass 123
ERROR:
raise response
ResponseError: operation not permitted
Seems like the AUTH command is not executed, or something similar. Any idea about the possible problem?
According to its README, Flask-Redis looks for a key called REDIS_URL as part of the Flask config.
Configuration
Your configuration should be declared within your Flask config. You can declare
via a Redis URL containing the database
REDIS_URL = "redis://:password#localhost:6379/0"
Without setting that redis_store will just use the default settings, which won't include your password.
app = Flask(__name__)
app.config['REDIS_URL'] = config.REDIS_URL
redis_store = Redis(app)

Categories