Files
eveAI/eveai_app/__init__.py
Josako 7bddeb0ebd - Add configuration of agents, tasks, tools, specialist in context of SPIN specialist
- correct startup of applications using gevent
- introduce startup scripts (eveai_app)
- caching manager for all configurations
2025-01-16 20:27:00 +01:00

171 lines
6.1 KiB
Python

import logging
import os
from flask import Flask, render_template, jsonify, flash, redirect, request
from flask_security import SQLAlchemyUserDatastore, LoginForm
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, mail, login_manager, cors, csrf, session,
minio_client, simple_encryption, metrics, cache_manager)
from common.models.user import User, Role, Tenant, TenantDomain
import common.models.interaction
import common.models.entitlements
import common.models.document
from common.utils.nginx_utils import prefixed_url_for
from common.utils.startup_eveai import perform_startup_actions
from config.logging_config import LOGGING
from common.utils.security import set_tenant_session_data
from .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
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 '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
try:
os.makedirs(app.instance_path)
except OSError:
pass
logging.config.dictConfig(LOGGING)
logger = logging.getLogger(__name__)
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)
# Debugging settings
if app.config['DEBUG'] is True:
app.logger.setLevel(logging.DEBUG)
mail_logger = logging.getLogger('flask_mailman')
mail_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
# Some generic Error Handling Routines
@app.errorhandler(Exception)
def handle_exception(e):
app.logger.error(f"Unhandled Exception: {e}", exc_info=True)
response = {
"message": str(e),
"type": type(e).__name__
}
return jsonify(response), 500
# @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}")
# 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}")
# Perform startup actions such as cache invalidation
perform_startup_actions(app)
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)
mail.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)
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.administration_views import administration_bp
app.register_blueprint(administration_bp)
from .views.healthz_views import healthz_bp, init_healtz
app.register_blueprint(healthz_bp)
init_healtz(app)
def register_cache_handlers(app):
from common.utils.cache.config_cache import (
AgentConfigCacheHandler, TaskConfigCacheHandler, ToolConfigCacheHandler, SpecialistConfigCacheHandler)
cache_manager.register_handler(AgentConfigCacheHandler, 'eveai_config')
cache_manager.register_handler(TaskConfigCacheHandler, 'eveai_config')
cache_manager.register_handler(ToolConfigCacheHandler, 'eveai_config')
cache_manager.register_handler(SpecialistConfigCacheHandler, 'eveai_config')