add /api/report-callback
This commit is contained in:
parent
8583f4c607
commit
3583a50695
15
bruno/survey/report-callback.bru
Normal file
15
bruno/survey/report-callback.bru
Normal file
@ -0,0 +1,15 @@
|
||||
meta {
|
||||
name: report-callback
|
||||
type: http
|
||||
seq: 3
|
||||
}
|
||||
|
||||
post {
|
||||
url: http://120.26.23.172/api/report-callback
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
settings {
|
||||
encodeUrl: true
|
||||
}
|
||||
@ -176,36 +176,22 @@ class ReportGenerator:
|
||||
analysis_data = self.generate_analysis_text({'id': session_id})
|
||||
|
||||
# 调用自定义API生成报告
|
||||
report_result = self.call_report_api(analysis_data)
|
||||
# 构造回调URL
|
||||
report_result = self.call_report_api(analysis_data, session_id)
|
||||
|
||||
if report_result:
|
||||
# 提取学员信息用于更新报告数据
|
||||
student_info = analysis_data['student_info']
|
||||
report_result['studentInfo']['name'] = student_info.get('name', '未知')
|
||||
report_result['studentInfo']['school'] = student_info.get('school', '未知')
|
||||
report_result['studentInfo']['grade'] = student_info.get('grade', '未知')
|
||||
report_result['studentInfo']['subject'] = '科学'
|
||||
report_result['studentInfo']['testDate'] = get_east8_time().strftime('%Y年%m月%d日')
|
||||
|
||||
# 构造报告数据
|
||||
report_data = {
|
||||
'studentInfo': report_result['studentInfo'],
|
||||
'report': report_result['report'],
|
||||
'generated_at': get_east8_time().isoformat(),
|
||||
'session_id': session_id,
|
||||
'analysis_data': analysis_data
|
||||
}
|
||||
|
||||
# 保存报告到数据库
|
||||
self.save_report_to_db(session_id, report_data, analysis_data)
|
||||
if report_result and report_result.get('success'):
|
||||
# API调用成功,异步生成中
|
||||
# 保存分析数据用于后续回调处理
|
||||
self.save_analysis_data_for_regeneration(session_id, analysis_data)
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'report_data': report_data,
|
||||
'message': '报告异步生成中',
|
||||
'session_id': session_id,
|
||||
'analysis_data': analysis_data
|
||||
}
|
||||
else:
|
||||
raise Exception("API返回空内容")
|
||||
raise Exception("API调用失败")
|
||||
|
||||
except Exception as e:
|
||||
print(f"生成报告失败: {e}")
|
||||
@ -218,87 +204,42 @@ class ReportGenerator:
|
||||
'can_regenerate': True
|
||||
}
|
||||
|
||||
def call_report_api(self, analysis_data):
|
||||
def call_report_api(self, analysis_data, session_id):
|
||||
"""调用自定义报告API生成报告"""
|
||||
# 构建请求数据
|
||||
request_data = {
|
||||
"analysis_text": analysis_data['analysis_text']
|
||||
"analysis_text": analysis_data['analysis_text'],
|
||||
"session_id": session_id
|
||||
}
|
||||
|
||||
# 实现重试机制
|
||||
max_retries = 3
|
||||
retry_delay = 2 # 秒
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
print(f"调用报告生成API (尝试 {attempt + 1}/{max_retries})...")
|
||||
print(f" API端点: {self.api_url}")
|
||||
print(f" 数据长度: {len(request_data['analysis_text'])} 字符")
|
||||
try:
|
||||
print(f"调用报告生成API...")
|
||||
print(f" API端点: {self.api_url}")
|
||||
print(f" Session ID: {session_id}")
|
||||
print(f" 数据长度: {len(request_data['analysis_text'])} 字符")
|
||||
|
||||
response = requests.post(
|
||||
self.api_url,
|
||||
headers=self.headers,
|
||||
json=request_data,
|
||||
timeout=self.timeout
|
||||
)
|
||||
response = requests.post(
|
||||
self.api_url,
|
||||
headers=self.headers,
|
||||
json=request_data,
|
||||
timeout=10 # 简化超时时间
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print(f"✅ API调用成功,已提交异步报告生成请求")
|
||||
print(f" 响应内容: {str(result)[:200]}...")
|
||||
return {"success": True, "message": "异步报告生成请求已提交"}
|
||||
else:
|
||||
raise Exception(f"API调用失败: HTTP {response.status_code} - {response.text}")
|
||||
|
||||
# 验证响应格式
|
||||
if 'studentInfo' in result and 'report' in result:
|
||||
print(f"✅ API调用成功,生成报告数据")
|
||||
return result
|
||||
else:
|
||||
print(f"⚠️ API响应格式异常,但继续处理")
|
||||
print(f" 响应内容: {str(result)[:200]}...")
|
||||
return result
|
||||
|
||||
elif response.status_code == 401:
|
||||
raise Exception("API密钥无效或已过期")
|
||||
|
||||
elif response.status_code == 429:
|
||||
# 速率限制,增加等待时间
|
||||
wait_time = retry_delay * (2 ** attempt)
|
||||
print(f"API速率限制,等待 {wait_time} 秒后重试...")
|
||||
time.sleep(wait_time)
|
||||
continue
|
||||
|
||||
elif response.status_code >= 500:
|
||||
# 服务器错误,重试
|
||||
wait_time = retry_delay * (2 ** attempt)
|
||||
print(f"API服务器错误 ({response.status_code}),{wait_time} 秒后重试...")
|
||||
time.sleep(wait_time)
|
||||
continue
|
||||
|
||||
else:
|
||||
raise Exception(f"API调用失败: HTTP {response.status_code} - {response.text}")
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
wait_time = retry_delay * (2 ** attempt)
|
||||
print(f"API请求超时,{wait_time} 秒后重试...")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(wait_time)
|
||||
else:
|
||||
raise Exception(f"API请求超时,已达到最大重试次数 ({self.timeout}秒)")
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
wait_time = retry_delay * (2 ** attempt)
|
||||
print(f"API连接错误,{wait_time} 秒后重试...")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(wait_time)
|
||||
else:
|
||||
raise Exception("API连接失败,已达到最大重试次数")
|
||||
|
||||
except Exception as e:
|
||||
if attempt == max_retries - 1:
|
||||
raise Exception(f"API调用失败: {str(e)}")
|
||||
else:
|
||||
wait_time = retry_delay * (2 ** attempt)
|
||||
print(f"API调用出错: {e},{wait_time} 秒后重试...")
|
||||
time.sleep(wait_time)
|
||||
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"API调用出错: {e}")
|
||||
raise Exception(f"报告生成API调用失败: {str(e)}")
|
||||
|
||||
def save_report_to_db(self, session_id, report_data, analysis_data):
|
||||
"""保存报告到数据库"""
|
||||
@ -499,7 +440,7 @@ class EnhancedSurveySystem:
|
||||
analysis_data = json.loads(result[0])
|
||||
|
||||
# 调用API生成报告
|
||||
report_result = self.report_generator.call_report_api(analysis_data)
|
||||
report_result = self.report_generator.call_report_api(analysis_data, session_id)
|
||||
|
||||
if report_result:
|
||||
# 提取学员信息用于更新报告数据
|
||||
|
||||
80
main.py
80
main.py
@ -14,7 +14,7 @@ from pydantic import BaseModel
|
||||
from typing import Dict, List, Optional, Any
|
||||
import asyncio
|
||||
import threading
|
||||
from enhanced_survey_system import enhanced_system, get_east8_time_string
|
||||
from enhanced_survey_system import enhanced_system, get_east8_time_string, get_east8_time
|
||||
|
||||
app = FastAPI(title="Enhanced Survey System")
|
||||
|
||||
@ -49,6 +49,10 @@ class SaveAnswersRequest(BaseModel):
|
||||
class GenerateReportRequest(BaseModel):
|
||||
sessionId: str
|
||||
|
||||
class ReportCallbackRequest(BaseModel):
|
||||
session_id: str
|
||||
data: Dict[str, Any]
|
||||
|
||||
class SessionResponse(BaseModel):
|
||||
success: bool
|
||||
sessionId: str
|
||||
@ -1030,6 +1034,80 @@ def generate_quiz_page(session_data: sqlite3.Row, session_id: str) -> str:
|
||||
</body>
|
||||
</html>'''
|
||||
|
||||
@app.post("/api/report-callback", response_model=ApiResponse)
|
||||
async def report_callback(request: ReportCallbackRequest):
|
||||
"""接收异步报告生成完成的回调数据"""
|
||||
session_id = request.session_id
|
||||
report_data = request.data
|
||||
|
||||
if not session_id or not report_data:
|
||||
raise HTTPException(status_code=400, detail="session_id和data不能为空")
|
||||
|
||||
try:
|
||||
# 验证会话是否存在
|
||||
conn = sqlite3.connect('data/survey.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
SELECT id FROM quiz_sessions WHERE id = ?
|
||||
''', (session_id,))
|
||||
|
||||
session_exists = cursor.fetchone()
|
||||
if not session_exists:
|
||||
conn.close()
|
||||
raise HTTPException(status_code=404, detail="会话不存在")
|
||||
|
||||
# 获取分析数据(如果有保存的话)
|
||||
cursor.execute('''
|
||||
SELECT analysis_data FROM temp_analysis_data
|
||||
WHERE session_id = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
''', (session_id,))
|
||||
|
||||
analysis_result = cursor.fetchone()
|
||||
analysis_data = json.loads(analysis_result[0]) if analysis_result else {}
|
||||
|
||||
# 构造完整的报告数据
|
||||
full_report_data = {
|
||||
'studentInfo': report_data.get('studentInfo', {}),
|
||||
'report': report_data.get('report', {}),
|
||||
'generated_at': get_east8_time().isoformat(),
|
||||
'session_id': session_id,
|
||||
'analysis_data': analysis_data
|
||||
}
|
||||
|
||||
# 保存报告到数据库
|
||||
report_id = str(uuid.uuid4())
|
||||
cursor.execute('''
|
||||
INSERT INTO reports (id, session_id, report_data, analysis_data, generated_at)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (report_id, session_id, json.dumps(full_report_data), json.dumps(analysis_data), get_east8_time_string()))
|
||||
|
||||
# 更新会话状态为已完成
|
||||
cursor.execute('''
|
||||
UPDATE quiz_sessions
|
||||
SET status = 'completed', completed_at = ?
|
||||
WHERE id = ?
|
||||
''', (get_east8_time_string(), session_id))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
print(f"✅ 回调处理成功: {session_id}")
|
||||
print(f" 报告ID: {report_id}")
|
||||
|
||||
return ApiResponse(
|
||||
success=True,
|
||||
message='回调数据处理成功'
|
||||
)
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
print(f"❌ 回调处理失败: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"回调处理失败: {str(e)}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
||||
Loading…
Reference in New Issue
Block a user