From d91bc39663f9e46cf928bd31e7fce3edf24a850d Mon Sep 17 00:00:00 2001 From: aaron <> Date: Thu, 12 Jun 2025 10:16:04 +0800 Subject: [PATCH] update --- cryptoai/routes/fastapi_app.py | 94 ++++++++++++++++++++++++++++++++++ cryptoai/routes/payment.py | 5 +- docker-compose.yml | 2 +- 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/cryptoai/routes/fastapi_app.py b/cryptoai/routes/fastapi_app.py index 35b13ed..c31bafc 100644 --- a/cryptoai/routes/fastapi_app.py +++ b/cryptoai/routes/fastapi_app.py @@ -9,6 +9,7 @@ FastAPI应用程序入口 import os import logging import uvicorn +import json from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse @@ -34,6 +35,9 @@ logging.basicConfig( ) logger = logging.getLogger("fastapi") +# 配置选项 +LOG_REQUEST_BODY = os.environ.get("LOG_REQUEST_BODY", "true").lower() == "true" + # 创建FastAPI应用 app = FastAPI( title="CryptoAI API", @@ -58,6 +62,96 @@ app.include_router(crypto_router, prefix="/crypto", tags=["加密货币数据"]) app.include_router(analysis_router, prefix="/analysis", tags=["分析历史"]) app.include_router(alltick_router, prefix="/alltick", tags=["AllTick数据"]) app.include_router(payment_router, prefix="/payment", tags=["支付"]) + +# 请求体日志中间件 +@app.middleware("http") +async def log_request_body(request: Request, call_next): + """ + 记录请求体的中间件 + 可通过环境变量 LOG_REQUEST_BODY=false 来禁用 + """ + # 如果禁用了请求体日志记录,则直接处理请求 + if not LOG_REQUEST_BODY: + response = await call_next(request) + return response + + # 获取请求的基本信息 + method = request.method + url = str(request.url) + client_ip = request.client.host if request.client else "unknown" + + # 初始化请求体内容 + body_content = "" + + # 只记录非 GET 请求的请求体 + if method in ["POST", "PUT", "PATCH", "DELETE"]: + try: + # 读取请求体 + body = await request.body() + + if body: + # 尝试解析为 JSON + try: + body_json = json.loads(body.decode('utf-8')) + # 敏感信息过滤 - 隐藏密码等敏感字段 + sensitive_fields = ['password', 'token', 'secret', 'key', 'auth'] + filtered_body = body_json.copy() + + def filter_sensitive_data(data, fields_to_hide): + if isinstance(data, dict): + for key in data: + if any(sensitive in key.lower() for sensitive in fields_to_hide): + data[key] = "***HIDDEN***" + elif isinstance(data[key], dict): + filter_sensitive_data(data[key], fields_to_hide) + elif isinstance(data[key], list): + for item in data[key]: + if isinstance(item, dict): + filter_sensitive_data(item, fields_to_hide) + + filter_sensitive_data(filtered_body, sensitive_fields) + body_content = json.dumps(filtered_body, ensure_ascii=False, indent=2) + except (json.JSONDecodeError, UnicodeDecodeError): + # 如果不是 JSON,则显示原始内容(限制长度) + body_content = body.decode('utf-8', errors='ignore')[:1000] + if len(body) > 1000: + body_content += "... (truncated)" + else: + body_content = "(empty)" + + except Exception as e: + body_content = f"(error reading body: {str(e)})" + + # 记录请求信息 + logger.info(f""" +╭─── REQUEST LOG ─────────────────────────────────────────── +│ Method: {method} +│ URL: {url} +│ Client IP: {client_ip} +│ Content-Type: {request.headers.get('content-type', 'N/A')} +│ User-Agent: {request.headers.get('user-agent', 'N/A')[:100]} +│ Body: +{body_content} +╰───────────────────────────────────────────────────────── +""") + else: + # GET 请求只记录基本信息 + query_params = str(request.query_params) if request.query_params else "(none)" + logger.info(f""" +╭─── REQUEST LOG ─────────────────────────────────────────── +│ Method: {method} +│ URL: {url} +│ Client IP: {client_ip} +│ Query Params: {query_params} +│ User-Agent: {request.headers.get('user-agent', 'N/A')[:100]} +╰───────────────────────────────────────────────────────── +""") + + # 处理请求 + response = await call_next(request) + + return response + # 请求计时中间件 @app.middleware("http") async def add_process_time_header(request: Request, call_next): diff --git a/cryptoai/routes/payment.py b/cryptoai/routes/payment.py index be90f25..04312be 100644 --- a/cryptoai/routes/payment.py +++ b/cryptoai/routes/payment.py @@ -12,6 +12,7 @@ from cryptoai.utils.db_manager import get_db from cryptoai.models.user_subscription import UserSubscriptionManager from datetime import timedelta import logging +from fastapi import Request router = APIRouter() @@ -116,9 +117,9 @@ class NotifyRequest(BaseModel): # chain_type: str @router.post("/notify") -async def notify(request: NotifyRequest, session: Session = Depends(get_db)): +async def notify(notify: NotifyRequest, session: Session = Depends(get_db)): try: - data = request.data + data = notify.data # 更新订单状态 subscription_order_manager = SubscriptionOrderManager(session) subscription_order_manager.update_order_status(data['merchantOrderNo'], 2) diff --git a/docker-compose.yml b/docker-compose.yml index 19a62d7..7d65433 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: cryptoai-api: build: . container_name: cryptoai-api - image: cryptoai-api:0.2.1 + image: cryptoai-api:0.2.2 restart: always ports: - "8000:8000"