- Add postgresql certificate to secrets for secure communication in staging and production environments - Adapt for TLS communication with PostgreSQL - Adapt tasks to handle invalid connections from the connection pool - Migrate to psycopg3 for connection to PostgreSQL
207 lines
7.5 KiB
Python
207 lines
7.5 KiB
Python
import logging
|
|
import os
|
|
from flask import Flask, jsonify, url_for
|
|
from flask_security import SQLAlchemyUserDatastore
|
|
from flask_security.signals import user_authenticated
|
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
|
import logging.config
|
|
|
|
from common.extensions import (db, migrate, bootstrap, security, login_manager, cors, csrf, session,
|
|
minio_client, simple_encryption, metrics, cache_manager, content_manager)
|
|
from common.models.user import User, Role, Tenant, TenantDomain
|
|
import common.models.interaction
|
|
import common.models.entitlements
|
|
import common.models.document
|
|
from config.logging_config import configure_logging
|
|
from common.utils.security import set_tenant_session_data
|
|
from common.utils.errors import register_error_handlers
|
|
from common.utils.celery_utils import make_celery, init_celery
|
|
from common.utils.template_filters import register_filters
|
|
from config.config import get_config
|
|
from eveai_app.views.security_forms import ResetPasswordForm, ForgotPasswordForm
|
|
|
|
|
|
def create_app(config_file=None):
|
|
app = Flask(__name__, static_url_path='/static')
|
|
|
|
# Ensure all necessary headers are handled
|
|
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)
|
|
|
|
environment = os.getenv('FLASK_ENV', 'development')
|
|
|
|
match environment:
|
|
case 'development':
|
|
app.config.from_object(get_config('dev'))
|
|
case 'test':
|
|
app.config.from_object(get_config('test'))
|
|
case 'staging':
|
|
app.config.from_object(get_config('staging'))
|
|
case 'production':
|
|
app.config.from_object(get_config('prod'))
|
|
case _:
|
|
app.config.from_object(get_config('dev'))
|
|
|
|
app.config['SESSION_KEY_PREFIX'] = 'eveai_app_'
|
|
app.config['SECURITY_RESET_PASSWORD_FORM'] = ResetPasswordForm
|
|
app.config['SECURITY_FORGOT_PASSWORD_FORM'] = ForgotPasswordForm
|
|
|
|
try:
|
|
os.makedirs(app.instance_path)
|
|
except OSError:
|
|
pass
|
|
|
|
# Configureer logging op basis van de omgeving (K8s of traditioneel)
|
|
try:
|
|
configure_logging()
|
|
logger = logging.getLogger(__name__)
|
|
# Test dat logging werkt
|
|
logger.debug("Logging test in eveai_app")
|
|
except Exception as e:
|
|
print(f"Critical Error Initialising Error: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
logger.info("eveai_app starting up")
|
|
|
|
# Register extensions
|
|
|
|
register_extensions(app)
|
|
|
|
# Configure CSRF protection
|
|
app.config['WTF_CSRF_CHECK_DEFAULT'] = False # Disable global CSRF protection
|
|
app.config['WTF_CSRF_TIME_LIMIT'] = None # Remove time limit for CSRF tokens
|
|
|
|
app.celery = make_celery(app.name, app.config)
|
|
init_celery(app.celery, app)
|
|
|
|
# Setup Flask-Security-Too
|
|
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
|
security.init_app(app, user_datastore)
|
|
user_authenticated.connect(set_tenant_session_data, app)
|
|
|
|
# Register Blueprints
|
|
register_blueprints(app)
|
|
|
|
# Register Error Handlers
|
|
register_error_handlers(app)
|
|
|
|
# Register Cache Handlers
|
|
register_cache_handlers(app)
|
|
|
|
# Custom url_for function for templates
|
|
@app.context_processor
|
|
def override_url_for():
|
|
return dict(url_for=_url_for)
|
|
|
|
def _url_for(endpoint, **values):
|
|
static_url = app.config.get('STATIC_URL')
|
|
if endpoint == 'static' and static_url:
|
|
filename = values.get('filename', '')
|
|
return f"{static_url}/{filename}"
|
|
return url_for(endpoint, **values)
|
|
|
|
# Debugging settings
|
|
if app.config['DEBUG'] is True:
|
|
app.logger.setLevel(logging.DEBUG)
|
|
security_logger = logging.getLogger('flask_security')
|
|
security_logger.setLevel(logging.DEBUG)
|
|
sqlalchemy_logger = logging.getLogger('sqlalchemy.engine')
|
|
sqlalchemy_logger.setLevel(logging.DEBUG)
|
|
# log_request_middleware(app) # Add this when debugging nginx or another proxy
|
|
|
|
# @app.before_request
|
|
# def before_request():
|
|
# # app.logger.debug(f"Before request - Session ID: {session.sid}")
|
|
# app.logger.debug(f"Before request - Session data: {session}")
|
|
# app.logger.debug(f"Before request - Request headers: {request.headers}")
|
|
|
|
@app.before_request
|
|
def before_request():
|
|
from flask import session, request
|
|
from flask_login import current_user
|
|
import datetime
|
|
|
|
if request.path.startswith('/healthz'):
|
|
return
|
|
|
|
app.logger.debug(f"Before request - URL: {request.url}")
|
|
app.logger.debug(f"Before request - PATH: {request.path}")
|
|
app.logger.debug(f"Before request - Session permanent: {session.permanent}")
|
|
|
|
@app.route('/debug/session')
|
|
def debug_session():
|
|
from flask import session
|
|
from flask_security import current_user
|
|
import datetime
|
|
|
|
if current_user.is_authenticated:
|
|
info = {
|
|
'session_permanent': session.permanent,
|
|
'session_lifetime_minutes': app.permanent_session_lifetime.total_seconds() / 60,
|
|
'session_refresh_enabled': app.config.get('SESSION_REFRESH_EACH_REQUEST'),
|
|
'current_time': datetime.datetime.now().isoformat(),
|
|
'session_data_keys': list(session.keys())
|
|
}
|
|
return jsonify(info)
|
|
else:
|
|
return jsonify({'error': 'Not authenticated'})
|
|
|
|
# Register template filters
|
|
register_filters(app)
|
|
|
|
# Let all initialization complete before using cache
|
|
# @app.before_first_request
|
|
# def initialize_cache_data():
|
|
# # Cache testing
|
|
# agent_types = cache_manager.agent_config_cache.get_types()
|
|
# app.logger.debug(f"Agent types: {agent_types}")
|
|
# agent_config = cache_manager.agent_config_cache.get_config('RAG_AGENT')
|
|
# app.logger.debug(f"Agent config: {agent_config}")
|
|
|
|
app.logger.info(f"EveAI App Server Started Successfully (PID: {os.getpid()})")
|
|
app.logger.info("-------------------------------------------------------------------------------------------------")
|
|
return app
|
|
|
|
|
|
def register_extensions(app):
|
|
db.init_app(app)
|
|
migrate.init_app(app, db)
|
|
bootstrap.init_app(app)
|
|
csrf.init_app(app)
|
|
login_manager.init_app(app)
|
|
cors.init_app(app)
|
|
simple_encryption.init_app(app)
|
|
session.init_app(app)
|
|
minio_client.init_app(app)
|
|
cache_manager.init_app(app)
|
|
metrics.init_app(app)
|
|
content_manager.init_app(app)
|
|
|
|
|
|
def register_blueprints(app):
|
|
from .views.user_views import user_bp
|
|
app.register_blueprint(user_bp)
|
|
from .views.basic_views import basic_bp
|
|
app.register_blueprint(basic_bp)
|
|
from .views.document_views import document_bp
|
|
app.register_blueprint(document_bp)
|
|
from .views.security_views import security_bp
|
|
app.register_blueprint(security_bp)
|
|
from .views.interaction_views import interaction_bp
|
|
app.register_blueprint(interaction_bp)
|
|
from .views.entitlements_views import entitlements_bp
|
|
app.register_blueprint(entitlements_bp)
|
|
from .views.partner_views import partner_bp
|
|
app.register_blueprint(partner_bp)
|
|
from .views.healthz_views import healthz_bp
|
|
app.register_blueprint(healthz_bp)
|
|
|
|
|
|
def register_cache_handlers(app):
|
|
from common.utils.cache.config_cache import register_config_cache_handlers
|
|
register_config_cache_handlers(cache_manager)
|
|
from common.utils.cache.crewai_processed_config_cache import register_specialist_cache_handlers
|
|
register_specialist_cache_handlers(cache_manager)
|
|
from common.utils.cache.license_cache import register_license_cache_handlers
|
|
register_license_cache_handlers(cache_manager)
|