Trouble running Flask alongside uWSGI/Nginx - python

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?

Related

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!

FlaskApp has no attribute 'config'

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__)
šŸ¤ 

Flask - Cannot commit changes on view

I have this Flask app deployed on a server.
Everything works fine except for the views where I need to db.session.commit() anytihing. I've been looking for circular imports and db engine stuff but I can't seem to understand why it doesn't work.
Below I post my init.py and one of the views I can't seem to make work.
#__init__.py
from flask import Flask
from flask.ext.bootstrap import Bootstrap
from flask.ext.moment import Moment
from flask.ext.sqlalchemy import SQLAlchemy
from config import config
from flask.ext.login import LoginManager
import os
basedir = os.path.abspath(os.path.dirname(__file__))
bootstrap = Bootstrap()
moment = Moment()
db = SQLAlchemy()
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
moment.init_app(app)
db.app = app
db.init_app(app)
db.create_all()
login_manager.init_app(app)
#BLUEPRINTS
from main import main as main_blueprint
app.register_blueprint(main_blueprint)
from auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix = '/auth')
from api import api as api_blueprint
app.register_blueprint(api_blueprint, url_prefix = '/api')
return app
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
if __name__ == "__main__":
app.run()
The config.py file where the db settings are defined
# -*- coding: utf-8 -*-
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_TRACK_MODIFICATIONS = True
# MAIL_SERVER = 'smtp.googlemail.com'
MAIL_SERVER = 'smtp.live.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
# VariĆ”veis de configuraĆ§Ć£o definidas na linha de comandos por motivos de seguranƧa
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
ORGANITE_MAIL_SUBJECT_PREFIX = '[Organite]'
ORGANITE_MAIL_SENDER = '*****#hotmail.com'
ORGANITE_ADMIN = '*****#hotmail.com'
#staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///data-dev.sqlite'
class TestConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'data.sqlite')
config = {
'development': DevelopmentConfig,
'testing': TestConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
Then on my api blueprint one of the views that don't work:
# -*- coding: utf-8 -*-
from flask import jsonify, request, session, redirect, url_for, current_app
from flask.ext.login import login_user, logout_user, login_required, \
current_user
from .. import db
from ..models import User
from flask.ext.login import login_required
from ..decorators import admin_required, permission_required
from . import api
import cx_Oracle
import datetime
import json
import os
os.environ["NLS_LANG"] = ".UTF8"
#Remover utilizador > JSON
#api.route('/delete/<id>', methods=['GET'])
#login_required
#admin_required
def del_user(id):
user = User.query.filter_by(num_mec=id).first()
if user is not None:
try:
db.session.delete(user)
db.session.commit()
status = 'Sucesso'
except:
status = 'Falhou'
else:
status='Falhou'
db.session.close()
return jsonify({'result': status})
No matter the changes I make the result will always be 'Falhou', meaning the db.session.commit() failed.
I don't even know how to see log errors for this kind of things and I can't seem to understand why it doesn't work.
Please, help, I am running out of time to finish this project.
In this case, unfortunately, the real cause of the error is being obscured by the try: except block which suppresses the error and just handles it by returning the failure result.
Remove the try: except and you will see the cause of the session commit failure in the crash log that Flask generates (in this case, as you mentioned in the comment, there was not sufficient permissions on the database file).
As a general rule, unless an exception is expected and must be handled gracefully, it's better to let it crash and burn with maximum error reporting (at least in debug mode) so that bugs don't slip by silently unnoticed. Since there is no general use-case where you would expect a failed commit to be normal behaviour, you should not be wrapping it in a try: except block.

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)

Flask extensions & its configuration

I have some trouble finding a pythonic way to run a Flask app with extensions' config parameters.
Here's my myapp/__init__.py, which initializes the flask app and its extensions:
from flask import Flask
from flask.ext.script import Manager
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.redis import Redis
app = Flask(__name__)
manager = Manager(app)
db = SQLAlchemy(app)
redis = Redis(app)
I decided to store app's configuration in separate files for debugging and deployment and loading them with Flask.config.from_pyfile.
Configuration file has several options, including:
SQLALCHEMY_DATABASE_URI = "sqlite:////tmp/test.db"
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379
REDIS_DB = 0
I use Flask-Script to run the server:
from myapp import app, manager
#manager.command
def debug():
app.config.from_pyfile("debug.cfg")
app.run()
While SQLAlchemy works OK (creating an SQLite database at the /tmp/test.db), I have yet to run Redis instance because it seems to try hard and find REDIS_HOST in app.config before it was even loaded from the config file.
Is there any way to bypass it without having to hardcode the default settings before config was imported from file?
Yes, if you pass in app to the Redis() constructor you need to have the configuration loaded.
Postpone passing in app, call redis.init_app(app) after loading the configuration:
app = Flask(__name__)
manager = Manager(app)
db = SQLAlchemy()
redis = Redis()
def attach_extensions(app):
db.init_app(app)
redis.init_app(app)
then when configuration has loaded:
from myapp import app, manager, attach_extensions
#manager.command
def debug():
app.config.from_pyfile("debug.cfg")
attach_extensions(app)
app.run()

Categories