|
@@ -1,11 +1,16 @@
|
|
|
import base64
|
|
|
+import logging
|
|
|
import os
|
|
|
+import sys
|
|
|
+from datetime import datetime
|
|
|
+from logging.handlers import TimedRotatingFileHandler
|
|
|
from pathlib import Path
|
|
|
|
|
|
-from fastapi import FastAPI, File, UploadFile
|
|
|
+from fastapi import FastAPI, File, UploadFile, Request, status
|
|
|
+from fastapi.responses import JSONResponse
|
|
|
from openai import OpenAI
|
|
|
|
|
|
-app = FastAPI()
|
|
|
+app = FastAPI(title="AI解析接口工具")
|
|
|
|
|
|
client = OpenAI(
|
|
|
api_key=os.getenv("DASHSCOPE_API_KEY"), # 如果您没有配置环境变量,请在此处替换您的API-KEY
|
|
@@ -16,13 +21,107 @@ DEFAULT_USER_MSG = f"""解析文件中的表格内容:要求准确识别金额
|
|
|
检查所有字段是否完整,确保没有遗漏或错误,可能需要多次校对,以确保生成的json准确无误。"""
|
|
|
|
|
|
ALL_IMG_CONTENT_TYPE = {
|
|
|
- "jpg": "jpeg",
|
|
|
- "png": "png",
|
|
|
- "jpeg": "jpeg",
|
|
|
- "webp": "webp",
|
|
|
+ "jpg": "jpeg",
|
|
|
+ "png": "png",
|
|
|
+ "jpeg": "jpeg",
|
|
|
+ "webp": "webp",
|
|
|
}
|
|
|
|
|
|
|
|
|
+# 自定义日志配置函数
|
|
|
+def setup_logging():
|
|
|
+ # 创建根日志记录器
|
|
|
+ logger = logging.getLogger()
|
|
|
+ logger.setLevel(logging.DEBUG) # 设置最低日志级别
|
|
|
+
|
|
|
+ # 清除现有处理器,避免重复日志
|
|
|
+ for handler in logger.handlers[:]:
|
|
|
+ logger.removeHandler(handler)
|
|
|
+
|
|
|
+ # 1. 控制台处理器 - 用于开发调试
|
|
|
+ console_handler = logging.StreamHandler(sys.stdout)
|
|
|
+ console_handler.setLevel(logging.DEBUG)
|
|
|
+
|
|
|
+ # 2. 文件处理器 - 用于生产环境持久化存储
|
|
|
+ file_handler = TimedRotatingFileHandler(
|
|
|
+ "app.log",
|
|
|
+ when="midnight", # 每天午夜轮转
|
|
|
+ interval=1,
|
|
|
+ backupCount=7, # 保留7天
|
|
|
+ encoding="utf-8"
|
|
|
+ )
|
|
|
+ file_handler.setLevel(logging.INFO)
|
|
|
+
|
|
|
+ # 3. 错误日志处理器 - 单独记录错误
|
|
|
+ error_handler = TimedRotatingFileHandler(
|
|
|
+ "errors.log",
|
|
|
+ when="midnight", # 每天午夜轮转
|
|
|
+ interval=1,
|
|
|
+ backupCount=15, # 保留7天
|
|
|
+ encoding="utf-8"
|
|
|
+ )
|
|
|
+ error_handler.setLevel(logging.WARNING)
|
|
|
+
|
|
|
+ # 创建日志格式
|
|
|
+ formatter = logging.Formatter(
|
|
|
+ fmt="%(asctime)s | %(levelname)-8s | %(name)s | %(filename)s:%(lineno)d | %(message)s",
|
|
|
+ datefmt="%Y-%m-%d %H:%M:%S"
|
|
|
+ )
|
|
|
+
|
|
|
+ # 为处理器设置格式
|
|
|
+ console_handler.setFormatter(formatter)
|
|
|
+ file_handler.setFormatter(formatter)
|
|
|
+ error_handler.setFormatter(formatter)
|
|
|
+
|
|
|
+ # 添加处理器到日志记录器
|
|
|
+ logger.addHandler(console_handler)
|
|
|
+ logger.addHandler(file_handler)
|
|
|
+ logger.addHandler(error_handler)
|
|
|
+
|
|
|
+ # 配置Uvicorn访问日志
|
|
|
+ access_logger = logging.getLogger("uvicorn.access")
|
|
|
+ access_logger.handlers = []
|
|
|
+ access_logger.addHandler(file_handler)
|
|
|
+ access_logger.propagate = False
|
|
|
+
|
|
|
+ return logger
|
|
|
+
|
|
|
+
|
|
|
+# 初始化日志系统
|
|
|
+logger = setup_logging()
|
|
|
+
|
|
|
+
|
|
|
+# 中间件:记录所有请求和响应
|
|
|
+@app.middleware("http")
|
|
|
+async def log_requests(request: Request, call_next):
|
|
|
+ start_time = datetime.now()
|
|
|
+
|
|
|
+ # 记录请求信息
|
|
|
+ logger.info(f"Request: {request.method} {request.url.path} | Client: {request.client.host}")
|
|
|
+
|
|
|
+ try:
|
|
|
+ response = await call_next(request)
|
|
|
+ except Exception as exc:
|
|
|
+ # 记录异常
|
|
|
+ logger.error(f"Request failed: {str(exc)}", exc_info=True)
|
|
|
+ return JSONResponse(
|
|
|
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
|
+ content={"message": "Internal server error"}
|
|
|
+ )
|
|
|
+
|
|
|
+ # 计算处理时间
|
|
|
+ process_time = (datetime.now() - start_time).total_seconds() * 1000
|
|
|
+
|
|
|
+ # 记录响应信息
|
|
|
+ logger.info(
|
|
|
+ f"Response: {response.status_code} | "
|
|
|
+ f"Time: {process_time:.2f}ms | "
|
|
|
+ f"Client: {request.client.host}"
|
|
|
+ )
|
|
|
+
|
|
|
+ return response
|
|
|
+
|
|
|
+
|
|
|
@app.get("hearth")
|
|
|
async def hearth():
|
|
|
print("ok")
|