Files
Meeting_Assistant/app.py
beabigegg df5411e44c OK
2025-11-13 08:18:15 +08:00

131 lines
4.8 KiB
Python

import os
import click
from datetime import timedelta
from flask import Flask
from dotenv import load_dotenv
from flask_migrate import Migrate
from flask_jwt_extended import JWTManager
from flask_cors import CORS
from models import db, bcrypt, User
from celery_app import celery # Import celery instance
def create_app():
"""Application Factory Pattern"""
load_dotenv()
app = Flask(__name__)
# --- Configuration ---
app.config.from_mapping(
SQLALCHEMY_DATABASE_URI=os.environ.get('DATABASE_URL'),
SQLALCHEMY_ENGINE_OPTIONS={
'pool_recycle': 3600,
'pool_size': 20,
'max_overflow': 30,
'pool_pre_ping': True,
'pool_timeout': 30
},
JWT_SECRET_KEY=os.environ.get('JWT_SECRET_KEY'),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
JWT_ACCESS_TOKEN_EXPIRES=timedelta(days=2),
CELERY_BROKER_URL=os.environ.get('CELERY_BROKER_URL', 'redis://localhost:6379/0'),
CELERY_RESULT_BACKEND=os.environ.get('CELERY_RESULT_BACKEND', 'redis://localhost:6379/0'),
DIFY_API_BASE_URL=os.environ.get("DIFY_API_BASE_URL"),
DIFY_STT_API_KEY=os.environ.get("DIFY_STT_API_KEY"),
DIFY_TRANSLATOR_API_KEY=os.environ.get("DIFY_TRANSLATOR_API_KEY"),
DIFY_SUMMARIZER_API_KEY=os.environ.get("DIFY_SUMMARIZER_API_KEY"),
DIFY_ACTION_EXTRACTOR_API_KEY=os.environ.get("DIFY_ACTION_EXTRACTOR_API_KEY"),
# LDAP Configuration
LDAP_SERVER=os.environ.get('LDAP_SERVER', 'panjit.com.tw'),
LDAP_PORT=int(os.environ.get('LDAP_PORT', 389)),
LDAP_USE_SSL=os.environ.get('LDAP_USE_SSL', 'False').lower() == 'true',
LDAP_BIND_USER_DN=os.environ.get('LDAP_BIND_USER_DN', ''),
LDAP_BIND_USER_PASSWORD=os.environ.get('LDAP_BIND_USER_PASSWORD', ''),
LDAP_SEARCH_BASE=os.environ.get('LDAP_SEARCH_BASE', 'DC=panjit,DC=com,DC=tw'),
LDAP_USER_LOGIN_ATTR=os.environ.get('LDAP_USER_LOGIN_ATTR', 'userPrincipalName')
)
project_root = os.path.dirname(os.path.abspath(__file__))
UPLOAD_FOLDER = os.path.join(project_root, 'uploads')
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 1024 # 1GB upload limit
# --- Initialize Extensions ---
db.init_app(app)
bcrypt.init_app(app)
Migrate(app, db)
JWTManager(app)
CORS(app)
# --- Configure Celery ---
celery.conf.update(app.config)
# This custom Task class ensures tasks run with the Flask app context
class ContextTask(celery.Task):
def __call__(self, *args, **kwargs):
with app.app_context():
return self.run(*args, **kwargs)
celery.Task = ContextTask
# --- Import and Register Blueprints ---
from auth_routes import auth_bp
from api_routes import api_bp
from ai_routes import ai_bp
from action_item_routes import action_bp
app.register_blueprint(auth_bp)
app.register_blueprint(api_bp)
app.register_blueprint(ai_bp)
app.register_blueprint(action_bp)
# --- Static File Serving (for Single Container) ---
from flask import send_from_directory, send_file
# Serve React build files
@app.route('/')
def serve_frontend():
try:
return send_file(os.path.join(app.root_path, 'frontend/dist/index.html'))
except:
return "AI Meeting Assistant is running. Frontend build not found."
@app.route('/<path:path>')
def serve_static(path):
# Try to serve static files first
try:
return send_from_directory(os.path.join(app.root_path, 'frontend/dist'), path)
except:
# If not found, serve index.html for SPA routing
try:
return send_file(os.path.join(app.root_path, 'frontend/dist/index.html'))
except:
return "File not found", 404
# --- CLI Commands ---
@app.cli.command("create_admin")
@click.argument("username")
@click.argument("password")
def create_admin(username, password):
"""Creates a new admin user."""
with app.app_context():
try:
if User.query.filter_by(username=username).first():
print(f"Error: User '{username}' already exists.")
return
admin_user = User(username=username, role='admin')
admin_user.set_password(password)
db.session.add(admin_user)
db.session.commit()
print(f"Admin user '{username}' created successfully.")
except Exception as e:
db.session.rollback()
print(f"An error occurred: {e}")
return app
app = create_app()
if __name__ == '__main__':
port = int(os.environ.get("FLASK_RUN_PORT", 5000))
app.run(host='0.0.0.0', port=port, debug=True)