15
15
from common import *
16
16
from pydantic import BaseModel
17
17
from json_repair import repair_json
18
+ from parse_detail import parse_detail
19
+ from feedgen .feed import FeedGenerator
18
20
app = FastAPI ()
19
21
app .add_middleware (
20
22
CORSMiddleware ,
@@ -76,38 +78,22 @@ async def post_feedback(feedback: Feedback):
76
78
async def get_cards ():
77
79
data = await redis_client .get ("card_table" )
78
80
return {"code" : 200 , "msg" : "success" , "data" : json .loads (data )}
79
- @app .get ("/todayTopNews" )
80
- async def getTodayTopNews ():
81
- todayTopNewsData = await redis_client .get ("todayTopNews" )
82
- if todayTopNewsData :
83
- return {"code" : 200 , "msg" : "success" , "data" : json .loads (todayTopNewsData )}
84
- else :
85
- mongoData = await get_data ("hot" )
86
- data = mongoData ['data' ]
87
- filtered_sites = [site for site in data if site ["name" ] in news_sites ]
88
- async with httpx .AsyncClient (timeout = httpx .Timeout (60.0 )) as client : # 增加超时时间
81
+ async def chatWithModel (messages , check_list = True ):
82
+ err = 10
83
+ while err > 0 :
84
+ async with httpx .AsyncClient (timeout = httpx .Timeout (360.0 )) as client :
89
85
try :
90
86
response = await client .post (
91
87
api_url ,
92
88
headers = api_headers ,
93
89
json = {
94
90
"model" : "gpt-4o" ,
95
- "messages" : [
96
- {
97
- "role" : "system" ,
98
- "content" : "你是一个新闻专家,熟悉各种新闻编写手段,并且熟知全球时事"
99
- },
100
- {
101
- "role" : "user" ,
102
- "content" : "请从下方数据中选出10条你认为最应该让我知道的内容,返回json格式数据,返回格式[{hot_lable:'',hot_url:'',hot_value:''}]\n data:" + json .dumps (filtered_sites )
103
- }
104
- ],
91
+ "messages" : messages ,
105
92
"stream" : True ,
106
93
"temperature" : 0 ,
107
94
"response_format" : {"type" : "json_object" }
108
95
}
109
96
)
110
-
111
97
text = ""
112
98
try :
113
99
async for line in response .aiter_lines ():
@@ -117,28 +103,104 @@ async def getTodayTopNews():
117
103
text += chunk
118
104
except httpx .ReadTimeout :
119
105
print ("Stream reading timed out, using partial response" )
120
-
106
+ err -= 1
107
+ continue
121
108
if not text :
122
- return {"code" : 500 , "msg" : "Failed to get response from API" , "data" : []}
123
-
124
- todayTopNewsData = json .loads (repair_json (text ))
125
- if "messages" in todayTopNewsData :
126
- todayTopNewsData = todayTopNewsData ["messages" ]
127
- if len (todayTopNewsData ) == 1 :
128
- todayTopNewsData = todayTopNewsData [0 ]
129
- if "content" in todayTopNewsData :
130
- todayTopNewsData = todayTopNewsData ['content' ]
131
- # 缓存结果到 Redis
132
- await redis_client .setex ("todayTopNews" , 3600 , json .dumps (todayTopNewsData ))
133
-
134
- return {"code" : 200 , "msg" : "success" , "data" : todayTopNewsData }
135
-
136
- except httpx .RequestError as e :
137
- print (f"API request failed: { str (e )} " )
138
- return {"code" : 500 , "msg" : f"API request failed: { str (e )} " , "data" : []}
139
- except json .JSONDecodeError as e :
140
- print (f"Failed to parse API response: { str (e )} " )
141
- return {"code" : 500 , "msg" : f"Failed to parse API response: { str (e )} " , "data" : []}
109
+ err -= 1
110
+ continue
111
+ if check_list and "hot_value" not in text :
112
+ err -= 1
113
+ continue
114
+ if not check_list and "hot_tag" not in text :
115
+ err -= 1
116
+ continue
117
+ return text
118
+ except Exception as e :
119
+ print (e )
120
+ err -= 1
121
+ return ""
122
+ @app .get ("/todayTopNews" )
123
+ async def getTodayTopNews ():
124
+ todayTopNewsData = await redis_client .get ("todayTopNews" )
125
+ if todayTopNewsData :
126
+ return {"code" : 200 , "msg" : "success" , "data" : json .loads (todayTopNewsData )}
127
+ else :
128
+ mongoData = await get_data ("hot" )
129
+ data = mongoData ['data' ]
130
+ filtered_sites = [site for site in data if site ["name" ] in news_sites ]
131
+ try :
132
+ text = await chatWithModel ([
133
+ {
134
+ "role" : "system" ,
135
+ "content" : "你是一个新闻专家,熟悉各种新闻编写手段,并且熟知全球时事"
136
+ },
137
+ {
138
+ "role" : "user" ,
139
+ "content" : "请从下方数据中选出10条你认为最应该让我知道的内容,返回json格式数据,返回格式{'hot_topics': [{hot_lable:'',hot_url:'',hot_value:''}]}\n data:" + json .dumps (filtered_sites )
140
+ }
141
+ ])
142
+ todayTopNewsData = json .loads (repair_json (text ))
143
+ if "messages" in todayTopNewsData :
144
+ todayTopNewsData = todayTopNewsData ["messages" ]
145
+ if len (todayTopNewsData ) == 1 :
146
+ todayTopNewsData = todayTopNewsData [0 ]
147
+ if "content" in todayTopNewsData :
148
+ todayTopNewsData = todayTopNewsData ['content' ]
149
+ if "hot_topics" in todayTopNewsData :
150
+ todayTopNewsData = todayTopNewsData ['hot_topics' ]
151
+ needKnows = await parse_detail (todayTopNewsData )
152
+ summarizes = []
153
+ for needKnow in needKnows :
154
+ err = 3
155
+ while err > 0 :
156
+ try :
157
+ summarize = await chatWithModel ([
158
+ {
159
+ "role" : "system" ,
160
+ "content" : "你是一个新闻专家,熟悉各种新闻编写手段,并且熟知全球时事,并且有丰富的内容总结经验"
161
+ },
162
+ {
163
+ "role" : "user" ,
164
+ "content" : "对下方数据的content进行300字左右的高效总结,并增加一个tag,作为hot_content的值,以json格式返回,返回格式{hot_lable:'',hot_url:'',hot_value:'',hot_content:'',hot_tag:''}\n data:" + json .dumps (needKnow )
165
+ }
166
+ ], False )
167
+ summarize = json .loads (repair_json (summarize ))
168
+ if "messages" in summarize :
169
+ summarize = summarize ["messages" ]
170
+ if len (summarize ) == 1 :
171
+ summarize = summarize [0 ]
172
+ if "content" in summarize :
173
+ summarize = summarize ['content' ]
174
+ del needKnow ['content' ]
175
+ needKnow ['hot_content' ] = summarize ['hot_content' ]
176
+ needKnow ['hot_tag' ] = summarize ['hot_tag' ]
177
+ summarizes .append (needKnow )
178
+ break
179
+ except Exception as e :
180
+ print (e )
181
+ err -= 1
182
+ await redis_client .setex ("todayTopNews" , 3600 , json .dumps (summarizes ))
183
+ fg = FeedGenerator ()
184
+ fg .title ('todayTopNewsWithAI' )
185
+ fg .link (href = 'https://www.hotday.uk' )
186
+ fg .description ('Today top news with AI' )
187
+ for item in summarizes :
188
+ fe = fg .add_entry ()
189
+ fe .title (item .get ('title' , item ['hot_lable' ]))
190
+ fe .link (href = item .get ('url' , item ['hot_url' ]))
191
+ fe .description (item .get ('description' , item ['hot_content' ]))
192
+ fg .rss_file ('rss_feed_today_top_news.xml' )
193
+ return {"code" : 200 , "msg" : "success" , "data" : summarizes }
194
+
195
+ except httpx .RequestError as e :
196
+ print (f"API request failed: { str (e )} " )
197
+ return {"code" : 500 , "msg" : f"API request failed: { str (e )} " , "data" : []}
198
+ except json .JSONDecodeError as e :
199
+ print (f"Failed to parse API response: { str (e )} " )
200
+ return {"code" : 500 , "msg" : f"Failed to parse API response: { str (e )} " , "data" : []}
201
+ except Exception as e :
202
+ print (f"some error happen: { str (e )} " )
203
+ return {"code" : 500 , "msg" : f"Some error happen: { str (e )} " , "data" : []}
142
204
143
205
@app .get ("/rank/{item_id}" )
144
206
async def get_data (item_id : str ):
@@ -261,7 +323,15 @@ async def get_data(item_id: str):
261
323
except Exception as e :
262
324
# 记录日志或处理 Redis 错误
263
325
print (f"Redis setex error: { e } " )
264
-
326
+ fg = FeedGenerator ()
327
+ fg .title ('todayTopNewsWithAI' )
328
+ fg .link (href = 'https://www.hotday.uk' )
329
+ fg .description ('Today top news with AI' )
330
+ for item in data :
331
+ fe = fg .add_entry ()
332
+ fe .title (item .get ('title' , item ['hot_lable' ]))
333
+ fe .link (href = item .get ('url' , item ['hot_url' ]))
334
+ fg .rss_file ('rss_feed.xml' )
265
335
return {
266
336
"code" : 200 ,
267
337
"msg" : "success" ,
0 commit comments