Просмотр исходного кода

已经修改config,自适应生成和开发环境,获取相应的配置参数

wangxq 1 месяц назад
Родитель
Сommit
b277bbc931

+ 26 - 31
app/__init__.py

@@ -1,39 +1,26 @@
 from flask import Flask
+from flask_sqlalchemy import SQLAlchemy
 from flask_cors import CORS
 import logging
-from app.config.config import Config
-from app.services.package_function import db
+from app.config.config import config, current_env
+import os
 
-def create_app(config_class=Config):
+db = SQLAlchemy()
+
+def create_app():
     """Create and configure the Flask application"""
     app = Flask(__name__)
-    app.config.from_object(config_class)
-    
-    # Initialize SQLAlchemy
-    db.init_app(app)
     
-    # Enable CORS
-    CORS(
-        app,
-        resources={
-            r"/api/*": {  # 使用更简洁的API路径
-                "origins": "*",
-                "methods": ["GET", "POST", "PUT", "DELETE"],
-                "allow_headers": ["Content-Type"]
-            }
-        },
-        supports_credentials=True
-    )
+    # 加载配置
+    app.config.from_object(config[current_env])
     
-    # Configure logging
-    configure_logging(app)
-    
-    # 输出启动信息
-    app.logger.info(f"Starting server on port {config_class.PORT}")
+    # 初始化扩展
+    CORS(app)
+    db.init_app(app)
     
-    # 导入并注册API蓝图
-    from app.api.meta_data import bp as meta_data_bp
-    from app.api.data_resource import bp as data_resource_bp
+    # 注册蓝图
+    from app.api.meta_data import bp as meta_bp
+    from app.api.data_resource import bp as resource_bp
     from app.api.data_model import bp as data_model_bp
     from app.api.data_interface import bp as data_interface_bp
     from app.api.data_metric import bp as data_metric_bp
@@ -41,9 +28,8 @@ def create_app(config_class=Config):
     from app.api.graph import bp as graph_bp
     from app.api.system import bp as system_bp
     
-    # 使用更简洁的API前缀
-    app.register_blueprint(meta_data_bp, url_prefix='/api/meta')
-    app.register_blueprint(data_resource_bp, url_prefix='/api/resource')
+    app.register_blueprint(meta_bp, url_prefix='/api/meta')
+    app.register_blueprint(resource_bp, url_prefix='/api/resource')
     app.register_blueprint(data_model_bp, url_prefix='/api/model')
     app.register_blueprint(data_interface_bp, url_prefix='/api/interface')
     app.register_blueprint(data_metric_bp, url_prefix='/api/metric')
@@ -51,12 +37,21 @@ def create_app(config_class=Config):
     app.register_blueprint(graph_bp, url_prefix='/api/graph')
     app.register_blueprint(system_bp, url_prefix='/api/system')
     
+    # Configure logging
+    configure_logging(app)
+    
+    # 输出启动信息
+    app.logger.info(f"Starting server in {current_env} mode on port {app.config['PORT']}")
+    
     return app
 
 def configure_logging(app):
     """Configure logging for the application"""
+    env = os.environ.get('FLASK_ENV', 'development')
+    log_file = f'flask_{env}.log'
+    
     logger = logging.getLogger("app")
-    handler = logging.FileHandler('flask.log', encoding='UTF-8')
+    handler = logging.FileHandler(log_file, encoding='UTF-8')
     handler.setLevel(logging.INFO)
     logging_format = logging.Formatter(
         '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')

+ 29 - 15
app/api/data_resource/routes.py

@@ -1,14 +1,13 @@
 from io import BytesIO, StringIO
 import os
 import pandas as pd
-from flask import request, jsonify, send_file
+from flask import request, jsonify, send_file, current_app
 from app.api.data_resource import bp
 from app.models.result import success, failed
 import logging
 import json
 import re
 from minio import Minio
-from app.config.config import Config
 from app.core.graph.graph_operations import MyEncoder
 from app.services.neo4j_driver import neo4j_driver
 from app.core.data_resource.resource import (
@@ -33,27 +32,31 @@ from app.core.meta_data import (
     get_formatted_time
 )
 import traceback
+from app.core.system.auth import require_auth
 
 logger = logging.getLogger("app")
 
-# 配置MinIO客户端
-minio_client = Minio(
-    Config.MINIO_HOST,
-    access_key=Config.MINIO_USER,
-    secret_key=Config.MINIO_PASSWORD,
-    secure=True
-)
-
-# 配置文件上传相关
-UPLOAD_FOLDER = Config.UPLOAD_FOLDER
-bucket_name = Config.BUCKET_NAME
-prefix = Config.PREFIX
+def get_minio_client():
+    """获取 MinIO 客户端实例"""
+    return Minio(
+        current_app.config['MINIO_HOST'],
+        access_key=current_app.config['MINIO_USER'],
+        secret_key=current_app.config['MINIO_PASSWORD'],
+        secure=current_app.config['MINIO_SECURE']
+    )
+
+def get_minio_config():
+    """获取 MinIO 配置"""
+    return {
+        'bucket_name': current_app.config['BUCKET_NAME'],
+        'prefix': current_app.config['PREFIX'],
+        'allowed_extensions': current_app.config['ALLOWED_EXTENSIONS']
+    }
 
 def is_english(text):
     """检查文本是否为英文"""
     return text.isascii() and bool(re.match(r'^[a-zA-Z0-9_\s.,;:!?()\'"-]+$', text))
 
-
 @bp.route('/translate', methods=['POST'])
 def data_resource_translate():
     # 获取表单数据
@@ -510,6 +513,17 @@ def data_resource_detail():
         logger.error(f"获取数据资源详情失败: {str(e)}")
         return jsonify(failed(str(e)))
 
+@bp.route('/config', methods=['GET'])
+@require_auth
+def get_resource_config():
+    """获取数据资源配置信息"""
+    config = get_minio_config()
+    return jsonify({
+        'allowed_extensions': list(config['allowed_extensions']),
+        'bucket_name': config['bucket_name'],
+        'prefix': config['prefix']
+    })
+
     """解析表定义SQL,支持带schema和不带schema两种格式"""
     try:
         # 支持以下格式:

+ 47 - 24
app/api/meta_data/routes.py

@@ -1,7 +1,6 @@
-from flask import request, jsonify, send_from_directory, send_file
+from flask import request, jsonify, send_from_directory, send_file, current_app
 from app.api.meta_data import bp
 from app.models.result import success, failed
-from app.config.config import Config
 import logging
 import json
 import io
@@ -24,28 +23,30 @@ from app.core.meta_data import (
     handle_id_unstructured,
     solve_unstructured_data
 )
+from app.core.system.auth import require_auth
 
 logger = logging.getLogger("app")
 
-# 配置MinIO客户端
-minio_client = Minio(
-    Config.MINIO_HOST,
-    access_key=Config.MINIO_USER,
-    secret_key=Config.MINIO_PASSWORD,
-    secure=Config.MINIO_SECURE
-)
-
-# 配置文件上传相关
-UPLOAD_FOLDER = Config.UPLOAD_FOLDER
-bucket_name = Config.BUCKET_NAME
-prefix = Config.PREFIX
+def get_minio_client():
+    """获取 MinIO 客户端实例"""
+    return Minio(
+        current_app.config['MINIO_HOST'],
+        access_key=current_app.config['MINIO_USER'],
+        secret_key=current_app.config['MINIO_PASSWORD'],
+        secure=current_app.config['MINIO_SECURE']
+    )
 
-# 允许的文件扩展名
-ALLOWED_EXTENSIONS = {'txt', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'csv'}
+def get_minio_config():
+    """获取 MinIO 配置"""
+    return {
+        'bucket_name': current_app.config['BUCKET_NAME'],
+        'prefix': current_app.config['PREFIX'],
+        'allowed_extensions': current_app.config['ALLOWED_EXTENSIONS']
+    }
 
 def allowed_file(filename):
     """检查文件扩展名是否允许"""
-    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
+    return '.' in filename and filename.rsplit('.', 1)[1].lower() in get_minio_config()['allowed_extensions']
 
 # 元数据列表
 @bp.route('/node/list', methods=['POST'])
@@ -305,6 +306,10 @@ def upload_file():
         if not allowed_file(file.filename):
             return jsonify(failed("不支持的文件类型"))
             
+        # 获取 MinIO 配置
+        minio_client = get_minio_client()
+        config = get_minio_config()
+            
         # 上传到MinIO
         file_content = file.read()
         file_size = len(file_content)
@@ -318,11 +323,11 @@ def upload_file():
         timestamp = time.strftime("%Y%m%d%H%M%S", time.localtime())
         
         # 生成唯一文件名
-        object_name = f"{prefix}/{filename_without_ext}_{timestamp}.{file_type}"
+        object_name = f"{config['prefix']}/{filename_without_ext}_{timestamp}.{file_type}"
         
         # 上传文件
         minio_client.put_object(
-            bucket_name, 
+            config['bucket_name'], 
             object_name,
             io.BytesIO(file_content),
             file_size,
@@ -349,8 +354,12 @@ def upload_file_display():
         if not object_name:
             return jsonify(failed("文件路径不能为空"))
             
+        # 获取 MinIO 配置
+        minio_client = get_minio_client()
+        config = get_minio_config()
+            
         # 获取文件内容
-        response = minio_client.get_object(bucket_name, object_name)
+        response = minio_client.get_object(config['bucket_name'], object_name)
         file_data = response.read()
         
         # 获取文件名
@@ -400,16 +409,20 @@ def download_file():
         if not object_name:
             return jsonify(failed("文件路径不能为空"))
             
-        # URL解码,处理特殊字符.
+        # URL解码,处理特殊字符
         import urllib.parse
         object_name = urllib.parse.unquote(object_name)
         
         # 记录下载请求信息,便于调试
         logger.info(f"下载文件请求: {object_name}")
         
+        # 获取 MinIO 配置
+        minio_client = get_minio_client()
+        config = get_minio_config()
+        
         # 获取文件
         try:
-            response = minio_client.get_object(bucket_name, object_name)
+            response = minio_client.get_object(config['bucket_name'], object_name)
             file_data = response.read()
         except S3Error as e:
             logger.error(f"MinIO获取文件失败: {str(e)}")
@@ -419,7 +432,6 @@ def download_file():
         file_name = object_name.split('/')[-1]
         
         # 直接从内存返回文件,不创建临时文件
-        import io
         file_stream = io.BytesIO(file_data)
         
         # 返回文件
@@ -580,4 +592,15 @@ def create_text_graph():
             return jsonify(failed("图谱创建失败"))
     except Exception as e:
         logger.error(f"创建文本图谱失败: {str(e)}")
-        return jsonify(failed(str(e))) 
+        return jsonify(failed(str(e)))
+
+@bp.route('/config', methods=['GET'])
+@require_auth
+def get_meta_config():
+    """获取元数据配置信息"""
+    config = get_minio_config()
+    return jsonify({
+        'bucket_name': config['bucket_name'],
+        'prefix': config['prefix'],
+        'allowed_extensions': list(config['allowed_extensions'])
+    }) 

+ 81 - 101
app/config/config.py

@@ -1,129 +1,109 @@
 import os
 import platform
 
-class Config:
-    """Base configuration class"""
+def get_environment():
+    """
+    获取当前运行环境
+    优先级:
+    1. 环境变量 FLASK_ENV
+    2. 根据操作系统自动判断(Windows -> development, Linux -> production)
+    """
+    # 首先检查环境变量
+    env = os.environ.get('FLASK_ENV')
+    if env:
+        return env.lower()
+    
+    # 根据操作系统判断
+    system = platform.system().lower()
+    if system == 'windows':
+        return 'development'
+    elif system == 'linux':
+        return 'production'
+    else:
+        return 'development'  # 其他系统默认使用开发环境
+
+class BaseConfig:
+    """基础配置类,包含所有环境共享的配置"""
     SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
     JSON_AS_ASCII = False
     
-    # Platform specific configurations
+    # 平台特定配置
     PLATFORM = platform.system().lower()
     
-    # File paths
-    if PLATFORM == 'windows':
-        FILE_PATH = os.environ.get('FILE_PATH') or 'C:/temp/'
-    elif PLATFORM == 'linux':
-        FILE_PATH = os.environ.get('FILE_PATH') or '/tmp/'
-    
-    # Upload configurations
-    UPLOAD_FOLDER = f"{FILE_PATH}resource_uploads/"
+    # 文件上传配置
     ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'xlsx', 'xls', 'csv'}
     
-    # MinIO configurations - 原配置
-    """
-    MINIO_HOST = os.environ.get('MINIO_HOST') or 'minio.citupro.com'
-    MINIO_USER = os.environ.get('MINIO_USER') or 'default-user'
-    MINIO_PASSWORD = os.environ.get('MINIO_PASSWORD') or 'default-password'
-    MINIO_SECURE = True
-    """
-    
-    # MinIO configurations - 新配置
-    MINIO_HOST = '192.168.67.138:9000'
-    MINIO_USER = 'citu-test'
-    MINIO_PASSWORD = 'citu-test'
-    MINIO_SECURE = False  # 内网环境,设置为 False
-    BUCKET_NAME = 'dataops-bucket' # 数据资源及元数据上传的bucket
-    
-    # Bucket configurations - 原配置
-    """
-    BUCKET_NAME = os.environ.get('BUCKET_NAME') or 'dev'
-    if PLATFORM == 'windows':
-        PREFIX = 'dataops-test'
-    elif PLATFORM == 'linux':
-        PREFIX = 'dataops'
-    """
-    
-    # Bucket configurations - 新配置
-    # BUCKET_NAME = 'dataops-test'
-    PREFIX = ''  # 由于 bucket_name 已经包含了所需信息,PREFIX 可以置空
-    
-    # 新增端口配置基类设置
-    PORT = 5500  # 默认端口
-
-    # 修改后(PostgreSQL配置)
-     
-    # SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:citupgdba@192.168.3.143:5432/dataops'
-    # 本地开发环境
-    SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:postgres@192.168.67.138:5432/dataops'
-    SQLALCHEMY_ENGINE_OPTIONS = {
-        'pool_pre_ping': True,
-        'pool_recycle': 300,
-        'pool_size': 10,
-        'max_overflow': 20
-    } 
-   
-    # 修改后(PostgreSQL配置)
-    """ 
-    SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:citumxl2357@127.0.0.1:5432/dataops'
+    # PostgreSQL 基础配置
     SQLALCHEMY_ENGINE_OPTIONS = {
         'pool_pre_ping': True,
         'pool_recycle': 300,
         'pool_size': 10,
         'max_overflow': 20
-    } 
-    """
+    }
+    
+    # Neo4j 基础配置
+    NEO4J_ENCRYPTED = False
 
-    # Neo4j配置段
-     
-    # NEO4J_URI = "bolt://192.168.3.143:7687"
-    # NEO4J_HTTP_URI = "http://192.168.3.143:7474"
-    # NEO4J_USER = "neo4j"
-    # NEO4J_PASSWORD = "mxlneo4j"
+class DevelopmentConfig(BaseConfig):
+    """Windows 开发环境配置"""
+    FLASK_ENV = 'development'
+    DEBUG = True
+    PORT = 5500
+    
+    # 开发环境 MinIO 配置
+    MINIO_HOST = '192.168.67.138:9000'
+    MINIO_USER = 'citu-test'
+    MINIO_PASSWORD = 'citu-test'
+    MINIO_SECURE = False
+    BUCKET_NAME = 'dataops-bucket'
+    PREFIX = ''
+    
+    # 开发环境 PostgreSQL 配置
+    SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:postgres@192.168.67.138:5432/dataops'
+    
+    # 开发环境 Neo4j 配置
     NEO4J_URI = "bolt://192.168.67.138:7687"
     NEO4J_HTTP_URI = "http://192.168.67.138:7474"
     NEO4J_USER = "neo4j"
     NEO4J_PASSWORD = "password"
-    #NEO4J_PASSWORD = "Doudou312$"
-    NEO4J_ENCRYPTED = False  # 内网环境可关闭加密 
-
-    # Neo4j配置段
-    """ 
-    NEO4J_URI = "bolt://115.190.96.180:7687"
-    NEO4J_HTTP_URI = "http://115.190.96.180:7474"
-    NEO4J_USER = "neo4j"
-    NEO4J_PASSWORD = "mxlneo4j"
-    NEO4J_ENCRYPTED = False  # 内网环境可关闭加密
-    """
-
-      # File paths
-    if PLATFORM == 'windows':
-        FILE_PATH = os.environ.get('FILE_PATH') or 'C:/temp/'
-    elif PLATFORM == 'linux':
-        FILE_PATH = os.environ.get('FILE_PATH') or '/tmp/'
     
+    # 开发环境文件路径配置
+    UPLOAD_BASE_PATH = 'C:\\tmp\\upload'
+    ARCHIVE_BASE_PATH = 'C:\\tmp\\archive'
 
-    # 数据资源,Windows 和 Linux 的文件上传和归档根路径配置
-    # 例如,当excle文件完成加载后,会被自动移动到归档路径。
-    if PLATFORM == 'windows':       
-        UPLOAD_BASE_PATH = 'C:\\tmp\\upload'
-        ARCHIVE_BASE_PATH = 'C:\\tmp\\archive'
-    elif PLATFORM == 'linux':
-        UPLOAD_BASE_PATH = '/data/upload'
-        ARCHIVE_BASE_PATH = '/data/archive'
-
-class DevelopmentConfig(Config):
-    """Development configuration"""
-    DEBUG = True
-    PORT = 5500  # 开发环境保持5500
-
-class ProductionConfig(Config):
-    """Production configuration"""
+class ProductionConfig(BaseConfig):
+    """Linux 生产环境配置"""
+    FLASK_ENV = 'production'
     DEBUG = False
-    PORT = 80  # 生产环境使用标准HTTP端口
+    PORT = 80
+    
+    # 生产环境 MinIO 配置
+    MINIO_HOST = os.environ.get('MINIO_HOST', 'minio.citupro.com')
+    MINIO_USER = os.environ.get('MINIO_USER', 'default-user')
+    MINIO_PASSWORD = os.environ.get('MINIO_PASSWORD', 'default-password')
+    MINIO_SECURE = True
+    BUCKET_NAME = 'dataops-bucket'
+    PREFIX = ''
+    
+    # 生产环境 PostgreSQL 配置
+    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'postgresql://postgres:citupgdba@192.168.3.143:5432/dataops')
+    
+    # 生产环境 Neo4j 配置
+    NEO4J_URI = os.environ.get('NEO4J_URI', "bolt://192.168.3.143:7687")
+    NEO4J_HTTP_URI = os.environ.get('NEO4J_HTTP_URI', "http://192.168.3.143:7474")
+    NEO4J_USER = os.environ.get('NEO4J_USER', "neo4j")
+    NEO4J_PASSWORD = os.environ.get('NEO4J_PASSWORD', "mxlneo4j")
+    
+    # 生产环境文件路径配置
+    UPLOAD_BASE_PATH = '/data/upload'
+    ARCHIVE_BASE_PATH = '/data/archive'
 
-# Configuration dictionary
+# 配置字典
 config = {
     'development': DevelopmentConfig,
     'production': ProductionConfig,
     'default': DevelopmentConfig
-} 
+}
+
+# 获取当前环境
+current_env = get_environment() 

+ 2 - 2
app/core/data_resource/resource.py

@@ -690,7 +690,7 @@ def select_create_ddl(sql_content):
         
     except Exception as e:
         logger.error(f"提取DDL语句失败: {str(e)}")
-        logger.error(traceback.format_exc())
+       # logger.error(traceback.format_exc())
         return []
 
 def table_sql(sql):
@@ -950,7 +950,7 @@ def select_sql(sql_query):
         
     except Exception as e:
         logger.error(f"解析SELECT查询语句失败: {str(e)}")
-        logger.error(traceback.format_exc())
+       # logger.error(traceback.format_exc())
         return None
 
 def model_resource_list(page, page_size, name_filter=None):

+ 16 - 5
app/core/graph/graph_operations.py

@@ -4,7 +4,8 @@ Graph Database Core Operations
 """
 
 from neo4j import GraphDatabase
-from app.config.config import Config
+from flask import current_app
+from app.services.neo4j_driver import Neo4jDriver
 import json
 import logging
 
@@ -17,6 +18,16 @@ class MyEncoder(json.JSONEncoder):
             return super(MyEncoder, self).default(obj)
         return str(obj)
 
+class GraphOperations:
+    def __init__(self):
+        self.driver = Neo4jDriver()
+        
+    def get_connection(self):
+        return self.driver.connect()
+        
+    def close(self):
+        self.driver.close()
+
 def connect_graph():
     """
     连接到Neo4j图数据库
@@ -26,10 +37,10 @@ def connect_graph():
     """
     try:
         # 从Config获取Neo4j连接参数
-        uri = Config.NEO4J_URI
-        user = Config.NEO4J_USER
-        password = Config.NEO4J_PASSWORD
-        encrypted = Config.NEO4J_ENCRYPTED
+        uri = current_app.config.get('NEO4J_URI')
+        user = current_app.config.get('NEO4J_USER')
+        password = current_app.config.get('NEO4J_PASSWORD')
+        encrypted = current_app.config.get('NEO4J_ENCRYPTED')
         
         # 创建Neo4j驱动
         driver = GraphDatabase.driver(

+ 22 - 3
app/core/system/auth.py

@@ -10,7 +10,8 @@ import uuid
 import psycopg2
 from psycopg2 import pool
 from urllib.parse import urlparse
-from app.config.config import Config
+from flask import current_app, request, jsonify
+from functools import wraps
 
 logger = logging.getLogger(__name__)
 
@@ -29,7 +30,7 @@ def get_pg_connection():
     if pg_pool is None:
         try:
             # 解析SQLAlchemy URI
-            uri = urlparse(Config.SQLALCHEMY_DATABASE_URI)
+            uri = urlparse(current_app.config['SQLALCHEMY_DATABASE_URI'])
             username = uri.username
             password = uri.password
             database = uri.path[1:]  # 移除开头的 '/'
@@ -291,4 +292,22 @@ def init_db():
     Returns:
         bool: 是否成功初始化
     """
-    return create_user_table() 
+    return create_user_table()
+
+def require_auth(f):
+    @wraps(f)
+    def decorated(*args, **kwargs):
+        auth_header = request.headers.get('Authorization')
+        if not auth_header:
+            return jsonify({'message': '缺少认证头'}), 401
+            
+        try:
+            # 验证认证头
+            if auth_header != current_app.config['SECRET_KEY']:
+                return jsonify({'message': '无效的认证信息'}), 401
+                
+            return f(*args, **kwargs)
+        except Exception as e:
+            return jsonify({'message': '认证失败'}), 401
+            
+    return decorated 

+ 18 - 21
app/core/system/config.py

@@ -6,7 +6,7 @@
 import logging
 import json
 import os
-from app.config.config import Config
+from flask import current_app, jsonify
 
 logger = logging.getLogger(__name__)
 
@@ -21,16 +21,13 @@ def get_system_config():
     try:
         # 收集系统配置信息(去除敏感信息)
         config_info = {
-            "environment": Config.ENVIRONMENT,
-            "debug_mode": Config.DEBUG,
-            "port": Config.PORT,
-            "platform": Config.PLATFORM,
-            "upload_folder": Config.UPLOAD_FOLDER,
-            "bucket_name": Config.BUCKET_NAME,
-            "prefix": Config.PREFIX,
-            "neo4j_uri": Config.NEO4J_URI,
-            "neo4j_encrypted": Config.NEO4J_ENCRYPTED,
-            # 不返回敏感信息如密码、密钥等
+            'environment': current_app.config['FLASK_ENV'],
+            'debug_mode': current_app.config['DEBUG'],
+            'platform': current_app.config['PLATFORM'],
+            'port': current_app.config['PORT'],
+            'allowed_extensions': list(current_app.config['ALLOWED_EXTENSIONS']),
+            'bucket_name': current_app.config['BUCKET_NAME'],
+            'prefix': current_app.config['PREFIX']
         }
         
         return config_info
@@ -49,26 +46,26 @@ def validate_config():
     errors = []
     
     # 检查Neo4j配置
-    if not hasattr(Config, 'NEO4J_URI') or not Config.NEO4J_URI:
+    if 'NEO4J_URI' not in current_app.config or not current_app.config['NEO4J_URI']:
         errors.append("NEO4J_URI未配置")
-    if not hasattr(Config, 'NEO4J_USER') or not Config.NEO4J_USER:
+    if 'NEO4J_USER' not in current_app.config or not current_app.config['NEO4J_USER']:
         errors.append("NEO4J_USER未配置")
-    if not hasattr(Config, 'NEO4J_PASSWORD') or not Config.NEO4J_PASSWORD:
+    if 'NEO4J_PASSWORD' not in current_app.config or not current_app.config['NEO4J_PASSWORD']:
         errors.append("NEO4J_PASSWORD未配置")
     
     # 检查MinIO配置
-    if not hasattr(Config, 'MINIO_HOST') or not Config.MINIO_HOST:
+    if 'MINIO_HOST' not in current_app.config or not current_app.config['MINIO_HOST']:
         errors.append("MINIO_HOST未配置")
-    if not hasattr(Config, 'MINIO_USER') or not Config.MINIO_USER:
+    if 'MINIO_USER' not in current_app.config or not current_app.config['MINIO_USER']:
         errors.append("MINIO_USER未配置")
-    if not hasattr(Config, 'MINIO_PASSWORD') or not Config.MINIO_PASSWORD:
+    if 'MINIO_PASSWORD' not in current_app.config or not current_app.config['MINIO_PASSWORD']:
         errors.append("MINIO_PASSWORD未配置")
     
     # 检查其他必要配置
-    if not hasattr(Config, 'UPLOAD_FOLDER') or not Config.UPLOAD_FOLDER:
-        errors.append("UPLOAD_FOLDER未配置")
-    if not os.path.isdir(Config.UPLOAD_FOLDER):
-        errors.append(f"UPLOAD_FOLDER目录不存在: {Config.UPLOAD_FOLDER}")
+    if 'BUCKET_NAME' not in current_app.config or not current_app.config['BUCKET_NAME']:
+        errors.append("BUCKET_NAME未配置")
+    if 'PREFIX' not in current_app.config:
+        errors.append("PREFIX未配置")
     
     return (len(errors) == 0, errors)
 

+ 22 - 39
app/core/system/health.py

@@ -9,8 +9,9 @@ import psutil
 import os
 import socket
 from datetime import datetime
-from app.config.config import Config
-from app.services.neo4j_driver import neo4j_driver
+from flask import current_app, jsonify
+from app.services.db_healthcheck import check_database_connection
+from app.services.neo4j_driver import Neo4jDriver
 
 logger = logging.getLogger(__name__)
 
@@ -22,7 +23,7 @@ def check_neo4j_connection():
         bool: 连接成功返回True,失败返回False
     """
     try:
-        with neo4j_driver.get_session() as session:
+        with Neo4jDriver().get_session() as session:
             # 执行简单查询确认连接
             session.run("RETURN 1")
             return True
@@ -31,38 +32,21 @@ def check_neo4j_connection():
         return False
 
 def check_system_health():
-    """
-    检查系统整体健康状态
-    包括关键依赖组件的连接状态
-    
-    Returns:
-        dict: 包含各组件健康状态的字典
-    """
-    # 检查Neo4j连接
-    neo4j_status = check_neo4j_connection()
-    
-    # 可以添加其他组件的健康检查
-    # 例如MySQL、Redis、MinIO等
-    
-    # 构造健康状态信息
+    """检查系统各个组件的健康状态"""
     health_status = {
-        "service": "DataOps-platform",
-        "status": "UP" if neo4j_status else "DEGRADED",
-        "version": "1.0.0",  # 可以从配置或版本文件中读取
-        "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
-        "dependencies": {
-            "neo4j": {
-                "status": "UP" if neo4j_status else "DOWN",
-                "details": {
-                    "url": Config.NEO4J_URI,
-                    "encrypted": Config.NEO4J_ENCRYPTED
-                }
-            }
-            # 可以添加其他依赖的状态
-        }
+        'database': check_database_connection(),
+        'neo4j': Neo4jDriver().verify_connectivity(),
+        'environment': current_app.config['FLASK_ENV'],
+        'platform': current_app.config['PLATFORM']
     }
     
-    return health_status
+    # 检查所有组件是否都正常
+    all_healthy = all([health_status['database'], health_status['neo4j']])
+    
+    return {
+        'status': 'healthy' if all_healthy else 'unhealthy',
+        'components': health_status
+    }
 
 def get_system_info():
     """
@@ -108,13 +92,12 @@ def get_system_info():
                 },
             },
             "application": {
-                "environment": Config.ENVIRONMENT,
-                "debug_mode": Config.DEBUG,
-                "port": Config.PORT,
-                "platform": Config.PLATFORM,
-                "upload_folder": Config.UPLOAD_FOLDER,
-                "bucket_name": Config.BUCKET_NAME,
-                "prefix": Config.PREFIX,
+                "environment": current_app.config['FLASK_ENV'],
+                "debug_mode": current_app.config['DEBUG'],
+                "port": current_app.config['PORT'],
+                "platform": current_app.config['PLATFORM'],
+                "bucket_name": current_app.config['BUCKET_NAME'],
+                "prefix": current_app.config['PREFIX'],
                 # 不返回敏感信息如密码、密钥等
             }
         }

+ 13 - 3
app/services/db_healthcheck.py

@@ -1,12 +1,22 @@
-from sqlalchemy import text
+from flask import current_app
+from sqlalchemy import create_engine
 from sqlalchemy.exc import OperationalError
-from app.config.config import Config
-from app import db
 import logging
 
 # Set up logger
 logger = logging.getLogger(__name__)
 
+def check_database_connection():
+    """检查数据库连接状态"""
+    try:
+        engine = create_engine(current_app.config['SQLALCHEMY_DATABASE_URI'])
+        connection = engine.connect()
+        connection.close()
+        return True
+    except OperationalError as e:
+        logger.error(f"数据库连接失败: {str(e)}")
+        return False
+
 def check_db_connection():
     try:
         with db.engine.connect() as conn:

+ 26 - 13
app/services/neo4j_driver.py

@@ -1,22 +1,35 @@
+from flask import current_app
 from neo4j import GraphDatabase
-from app.config.config import Config
+from neo4j.exceptions import ServiceUnavailable
 
 class Neo4jDriver:
     def __init__(self):
-        self._driver = GraphDatabase.driver(
-            Config.NEO4J_URI,
-            auth=(Config.NEO4J_USER, Config.NEO4J_PASSWORD),
-            encrypted=Config.NEO4J_ENCRYPTED,
-            max_connection_pool_size=20,  # 根据负载调整
-            connection_timeout=30,  # 秒
-            connection_acquisition_timeout=60  # 秒
-        )
-    
-    def get_session(self):
-        return self._driver.session()
+        self._driver = None
+        
+    def connect(self):
+        if not self._driver:
+            self._driver = GraphDatabase.driver(
+                current_app.config['NEO4J_URI'],
+                auth=(current_app.config['NEO4J_USER'], current_app.config['NEO4J_PASSWORD']),
+                encrypted=current_app.config['NEO4J_ENCRYPTED']
+            )
+        return self._driver
     
     def close(self):
-        self._driver.close()
+        if self._driver:
+            self._driver.close()
+            self._driver = None
+            
+    def verify_connectivity(self):
+        try:
+            self.connect().verify_connectivity()
+            return True
+        except ServiceUnavailable:
+            return False
+    
+    def get_session(self):
+        """获取 Neo4j 会话"""
+        return self.connect().session()
 
 # 单例实例
 neo4j_driver = Neo4jDriver() 

+ 3 - 10
application.py

@@ -1,14 +1,7 @@
 from app import create_app
-from app.config.config import Config, DevelopmentConfig  # 新增配置导入
-from app.core.graph.graph_operations import MyEncoder
+from app.config.config import current_env
 
-app = create_app(DevelopmentConfig)
+app = create_app()
 
 if __name__ == '__main__':
-    # 修改后带端口配置的启动命令
-    app.run(
-        host='0.0.0.0',
-        port=DevelopmentConfig.PORT,  # 从配置类获取端口
-        debug=DevelopmentConfig.DEBUG,
-        use_reloader=False if DevelopmentConfig.PLATFORM == 'linux' else True
-    ) 
+    app.run(host='0.0.0.0', port=app.config['PORT'])