work-tracing/app/__init__.py
ilia-gurielidze-autstand 9e6d0a6911 first commit
2025-05-05 12:12:46 +04:00

108 lines
3.7 KiB
Python

"""
Employee Workstation Activity Tracking - Flask Application Factory
This module provides the application factory function 'create_app' that initializes
the Flask application with its configuration, database connection, and registered blueprints.
"""
import os
import logging
from logging.handlers import RotatingFileHandler
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from dotenv import load_dotenv
# Initialize SQLAlchemy globally to avoid circular imports
db = SQLAlchemy()
def create_app(test_config=None):
"""Create and configure the Flask application using the factory pattern."""
# Load environment variables
load_dotenv() # Try .env first
config_env_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config.env')
if os.path.exists(config_env_path):
load_dotenv(config_env_path)
print(f"Loaded environment variables from {config_env_path}")
else:
print(f"Warning: config.env file not found at {config_env_path}")
# Get the project root directory (parent of app directory)
project_root = os.path.dirname(os.path.dirname(__file__))
# Create and configure the app with template folder in project root
app = Flask(__name__,
instance_relative_config=True,
template_folder=os.path.join(project_root, 'templates'),
static_folder=os.path.join(project_root, 'static'))
# Default configuration
app.config.from_mapping(
SECRET_KEY=os.environ.get('SECRET_KEY', 'dev'),
SQLALCHEMY_DATABASE_URI=os.environ.get('DATABASE_URI', os.environ.get('DATABASE_URL')),
SQLALCHEMY_TRACK_MODIFICATIONS=False
)
# Override configuration with test config if provided
if test_config is not None:
app.config.update(test_config)
# Ensure DATABASE_URI is set
if not app.config['SQLALCHEMY_DATABASE_URI']:
raise ValueError("DATABASE_URI or DATABASE_URL environment variable must be set")
# Ensure the instance folder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# Configure logging
if not app.debug: # Avoid duplicate logs in debug mode
log_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
log_handler = RotatingFileHandler(
os.path.join(app.instance_path, 'server.log'),
maxBytes=1024 * 1024 * 5, # 5 MB
backupCount=5
)
log_handler.setFormatter(log_formatter)
log_handler.setLevel(logging.INFO)
app.logger.addHandler(log_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Flask application starting up...')
# Initialize database with the app
db.init_app(app)
# Import and register blueprints
from app.api import events_bp, reports_bp
app.register_blueprint(events_bp)
app.register_blueprint(reports_bp)
from app.views.dashboard import views_bp
app.register_blueprint(views_bp)
# Register error handlers
from app.errors import register_error_handlers
register_error_handlers(app)
# Initialize database tables when in development
@app.cli.command("init-db")
def init_db_command():
"""Clear existing data and create new tables."""
with app.app_context():
db.create_all()
app.logger.info("Database tables created")
@app.route('/healthcheck')
def healthcheck():
return {'status': 'ok'}, 200
return app
def init_db():
"""Initialize the database outside of the CLI context"""
app = create_app()
with app.app_context():
db.create_all()
app.logger.info("Database initialized")