- 排除 .env / *.bak / 内部运维文档(README_INTERNAL.html) - config.py 默认密码已替换为占位符 CHANGE_ME_* - init_db.sql 移除生产数据库用户 GRANT 段 - README.html 数据库用户名已脱敏 - 保留:源码 + 公网 API 文档 + 建表 SQL(无授权语句)
121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
"""Flask Application Entry Point"""
|
|
import logging
|
|
import sys
|
|
import os
|
|
|
|
# Add project root to path
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
import json
|
|
from datetime import datetime, date
|
|
from flask import Flask, Response
|
|
from config import Config
|
|
from memory_system import MemorySystem
|
|
from api.routes import api
|
|
from auth.api_auth import require_auth, api_auth_bp
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _sanitize(obj):
|
|
"""Recursively sanitize data for JSON serialization."""
|
|
if isinstance(obj, dict):
|
|
return {k: _sanitize(v) for k, v in obj.items()}
|
|
if isinstance(obj, list):
|
|
return [_sanitize(v) for v in obj]
|
|
if isinstance(obj, bytes):
|
|
return None
|
|
if isinstance(obj, (datetime, date)):
|
|
return obj.isoformat()
|
|
return obj
|
|
|
|
|
|
def json_response(data, status=200):
|
|
"""Create a JSON response with proper serialization."""
|
|
return Response(
|
|
json.dumps(_sanitize(data), ensure_ascii=False),
|
|
status=status,
|
|
mimetype="application/json",
|
|
)
|
|
|
|
|
|
|
|
LANDING_HTML = """<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Memory System - 多智能体记忆系统</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
|
background: #0d1117; color: #c9d1d9; display: flex; justify-content: center;
|
|
align-items: center; min-height: 100vh; }
|
|
.container { text-align: center; max-width: 600px; padding: 40px 24px; }
|
|
h1 { font-size: 32px; color: #f0f6fc; margin-bottom: 12px; }
|
|
p { font-size: 16px; color: #8b949e; line-height: 1.8; margin-bottom: 24px; }
|
|
.links { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
|
|
a { display: inline-block; padding: 10px 24px; border-radius: 8px;
|
|
text-decoration: none; font-size: 15px; font-weight: 500; transition: all 0.2s; }
|
|
a.primary { background: #238636; color: #fff; }
|
|
a.primary:hover { background: #2ea043; }
|
|
a.secondary { border: 1px solid #30363d; color: #c9d1d9; }
|
|
a.secondary:hover { border-color: #58a6ff; color: #58a6ff; }
|
|
.footer { margin-top: 48px; font-size: 13px; color: #484f58; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>🧠 Memory System</h1>
|
|
<p>多智能体记忆系统 —— 为 AI Agent 提供双层次记忆、语义检索和智能生命周期管理的基础设施。</p>
|
|
<div class="links">
|
|
<a class="primary" href="/docs/">📖 API 文档</a>
|
|
<a class="secondary" href="/health">💚 健康检查</a>
|
|
</div>
|
|
<p class="footer">Memory System v3.0 | Powered by Flask + MySQL + Redis + BGE</p>
|
|
</div>
|
|
</body>
|
|
</html>"""
|
|
|
|
|
|
def create_app():
|
|
app = Flask(__name__)
|
|
app.config["JSON_SORT_KEYS"] = False
|
|
app.json_response = json_response
|
|
app.sanitize = _sanitize
|
|
|
|
# Initialize memory system
|
|
cfg = Config()
|
|
app.memory_system = MemorySystem(cfg)
|
|
logger.info("MemorySystem initialized")
|
|
|
|
# Register auth before_request handler
|
|
app.before_request(require_auth)
|
|
logger.info("API Key auth middleware registered")
|
|
|
|
# Register API blueprint
|
|
app.register_blueprint(api)
|
|
|
|
# Register admin blueprint (localhost-only)
|
|
app.register_blueprint(api_auth_bp)
|
|
logger.info("Admin endpoints registered at /admin/*")
|
|
|
|
return app
|
|
|
|
|
|
app = create_app()
|
|
|
|
|
|
@app.route("/")
|
|
def index():
|
|
from flask import Response
|
|
return Response(LANDING_HTML, mimetype="text/html")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="127.0.0.1", port=8081, debug=False)
|