Files
zydi-web/app/api/main.py
T
2025-02-13 02:15:58 +00:00

180 lines
6.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from datetime import datetime
from typing import Optional
import json
from concurrent.futures import ThreadPoolExecutor
from .config import create_redis_connections
from .models import (
get_camera_data_by_date,
background_generate_report
)
app = FastAPI()
# 配置CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 创建线程池执行器
executor = ThreadPoolExecutor(max_workers=3)
# 用于跟踪报告生成任务的状态
report_tasks = {}
# 创建Redis连接池
redis_connections = create_redis_connections()
@app.get("/web/face/{camera_id}/data")
async def get_camera_data(camera_id: str, date: Optional[str] = None):
"""获取摄像头人脸数据"""
if date is None:
date = datetime.now().strftime("%Y%m%d")
return await get_camera_data_by_date(camera_id, date, redis_connections[camera_id], is_face=True)
@app.get("/web/{camera_id}/data")
async def get_camera_data(camera_id: str, date: Optional[str] = None):
"""获取摄像头行为数据"""
if date is None:
date = datetime.now().strftime("%Y%m%d")
return await get_camera_data_by_date(camera_id, date, redis_connections[camera_id])
@app.get("/web/report/{date}")
async def get_report_by_date(date: str):
"""获取指定日期的分析报告"""
try:
print(f"\n=== 开始处理日期: {date} ===")
try:
parsed_date = datetime.strptime(date, "%Y-%m-%d")
date_no_hyphen = parsed_date.strftime("%Y%m%d")
print(f"转换后的日期格式: {date_no_hyphen}")
except ValueError:
raise HTTPException(
status_code=400,
detail="Invalid date format. Please use YYYY-MM-DD"
)
report_redis = redis_connections["report"]
report_key = f"report_{date_no_hyphen}"
task_key = f"task_status_{date_no_hyphen}"
print(f"缓存键: {report_key}")
cached_report = report_redis.get(report_key)
print(f"是否有缓存: {'' if cached_report else ''}")
if cached_report:
print("返回缓存数据")
return {
"message": "success",
"data": json.loads(cached_report),
"source": "cache"
}
task_status_json = report_redis.get(task_key)
if task_status_json:
task_status = json.loads(task_status_json)
if task_status["status"] == "running":
return {
"message": "processing",
"detail": "报告正在生成中,请稍后再试"
}
elif task_status["status"] == "completed":
report_data = report_redis.get(report_key)
if report_data:
return {
"message": "success",
"data": json.loads(report_data),
"source": "new_generation"
}
else:
return {
"message": "no_data",
"detail": "暂无数据"
}
elif task_status["status"] == "failed":
return {
"message": "error",
"detail": f"报告生成失败: {task_status.get('error', '未知错误')}"
}
print("启动后台任务生成报告...")
executor.submit(background_generate_report, date_no_hyphen, redis_connections)
return {
"message": "processing",
"detail": "报告正在生成中,请稍后再试"
}
except Exception as e:
print(f"Error processing report request: {str(e)}")
import traceback
print(f"详细错误信息: {traceback.format_exc()}")
raise HTTPException(
status_code=500,
detail=f"处理报告时发生错误: {str(e)}\n错误类型: {type(e)}"
)
@app.get("/web/report/download/{date}")
async def download_report(date: str):
"""下载指定日期的分析报告"""
try:
try:
parsed_date = datetime.strptime(date, "%Y-%m-%d")
date_no_hyphen = parsed_date.strftime("%Y%m%d")
except ValueError:
error_msg = "日期格式必须为YYYY-MM-DD(例如:2024-12-31"
print(f"日期格式错误: {error_msg}")
raise HTTPException(
status_code=400,
detail=error_msg
)
report_key = f"report_{date_no_hyphen}"
report_redis = redis_connections["report"]
report_data = report_redis.get(report_key)
if not report_data:
error_msg = f"未找到 {date} 的报告数据,请先生成报告"
print(error_msg)
raise HTTPException(
status_code=404,
detail=error_msg
)
try:
data = json.loads(report_data)
if "hourly_distribution" in data:
del data["hourly_distribution"]
print("成功获取报告数据")
return {
"message": "success",
"data": data
}
except json.JSONDecodeError as je:
error_msg = f"报告数据格式错误: {str(je)}"
print(error_msg)
raise HTTPException(
status_code=500,
detail=error_msg
)
except HTTPException as he:
raise he
except Exception as e:
error_msg = f"处理请求时发生错误: {str(e)}"
print(error_msg)
raise HTTPException(
status_code=500,
detail=error_msg
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=6005)