smgc commited on
Commit
b9e956c
1 Parent(s): 73e1543

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -83
app.py CHANGED
@@ -66,7 +66,7 @@ def validate_api_key():
66
  api_key = request.headers.get('x-api-key')
67
  if api_key != API_KEY:
68
  log_request(request.remote_addr, request.path, 401)
69
- return jsonify({"error": "Invalid API key"}), 401
70
  return None
71
 
72
  def normalize_content(content):
@@ -95,10 +95,16 @@ def calculate_tokens(text):
95
  tokens = text.split()
96
  return len(tokens)
97
 
 
 
 
 
 
 
98
  @app.route('/')
99
  def root():
100
  log_request(request.remote_addr, request.path, 200)
101
- return jsonify({
102
  "message": "Welcome to the Perplexity AI Proxy API",
103
  "endpoints": {
104
  "/ai/v1/messages": {
@@ -141,73 +147,72 @@ def messages():
141
  log_request(request.remote_addr, request.path, 200)
142
 
143
  def generate():
144
- yield create_event("message_start", {
145
- "type": "message_start",
146
- "message": {
147
- "id": msg_id,
148
- "type": "message",
149
- "role": "assistant",
150
- "content": [],
151
- "model": model,
152
- "stop_reason": None,
153
- "stop_sequence": None,
154
- "usage": {"input_tokens": input_tokens, "output_tokens": 1},
155
- },
156
- })
157
- yield create_event("content_block_start", {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}})
158
- yield create_event("ping", {"type": "ping"})
159
-
160
- def on_connect():
161
- app_logger.info("Connected to Perplexity AI")
162
- emit_data = {
163
- "version": "2.9",
164
- "source": "default",
165
- "attachments": [],
166
- "language": "en-GB",
167
- "timezone": "Europe/London",
168
- "mode": "concise",
169
- "is_related_query": False,
170
- "is_default_related_query": False,
171
- "visitor_id": str(uuid.uuid4()),
172
- "frontend_context_uuid": str(uuid.uuid4()),
173
- "prompt_source": "user",
174
- "query_source": "home"
175
- }
176
- sio.emit('perplexity_ask', (previous_messages, emit_data))
177
-
178
- def on_query_progress(data):
179
- nonlocal response_text
180
- if 'text' in data:
181
- text = json.loads(data['text'])
182
- chunk = text['chunks'][-1] if text['chunks'] else None
183
- if chunk:
184
- response_text.append(chunk)
185
-
186
- if data.get('final', False):
 
 
 
 
 
187
  response_event.set()
188
 
189
- def on_disconnect():
190
- app_logger.info("Disconnected from Perplexity AI")
191
- response_event.set()
192
-
193
- def on_connect_error(data):
194
- app_logger.error(f"Connection error: {data}")
195
- response_text.append(f"Error connecting to Perplexity AI: {data}")
196
- response_event.set()
197
 
198
- sio.on('connect', on_connect)
199
- sio.on('query_progress', on_query_progress)
200
- sio.on('disconnect', on_disconnect)
201
- sio.on('connect_error', on_connect_error)
202
 
203
- try:
204
  sio.connect('wss://www.perplexity.ai/', **connect_opts, headers=sio_opts['extraHeaders'])
205
 
206
  while not response_event.is_set():
207
  sio.sleep(0.1)
208
  while response_text:
209
  chunk = response_text.pop(0)
210
- # 记录每一块返回的内容
211
  app_logger.info(f"Returning chunk to client: {chunk}")
212
  yield create_event("content_block_delta", {
213
  "type": "content_block_delta",
@@ -215,33 +220,29 @@ def messages():
215
  "delta": {"type": "text_delta", "text": chunk},
216
  })
217
 
218
- except Exception as e:
219
- app_logger.error(f"Error during socket connection: {str(e)}")
220
- yield create_event("content_block_delta", {
221
- "type": "content_block_delta",
222
- "index": 0,
223
- "delta": {"type": "text_delta", "text": f"Error during socket connection: {str(e)}"},
 
224
  })
 
 
 
 
 
225
  finally:
226
  if sio.connected:
227
  sio.disconnect()
228
 
229
- output_tokens = calculate_tokens(''.join(response_text))
230
-
231
- yield create_event("content_block_stop", {"type": "content_block_stop", "index": 0})
232
- yield create_event("message_delta", {
233
- "type": "message_delta",
234
- "delta": {"stop_reason": "end_turn", "stop_sequence": None},
235
- "usage": {"input_tokens": input_tokens, "output_tokens": output_tokens},
236
- })
237
- yield create_event("message_stop", {"type": "message_stop"})
238
-
239
  return Response(generate(), content_type='text/event-stream')
240
 
241
  except Exception as e:
242
  app_logger.error(f"Request error: {str(e)}")
243
  log_request(request.remote_addr, request.path, 400)
244
- return jsonify({"error": str(e)}), 400
245
 
246
  def handle_non_stream(previous_messages, msg_id, model, input_tokens):
247
  try:
@@ -310,13 +311,11 @@ def handle_non_stream(previous_messages, msg_id, model, input_tokens):
310
  },
311
  }
312
 
313
- # 记录完整的响应内容
314
- app_logger.info(f"Returning full response to client: {full_response}")
315
- return Response(json.dumps(full_response, ensure_ascii=False), content_type='application/json')
316
 
317
  except Exception as e:
318
  app_logger.error(f"Error during socket connection: {str(e)}")
319
- return jsonify({"error": str(e)}), 500
320
  finally:
321
  if sio.connected:
322
  sio.disconnect()
@@ -324,18 +323,20 @@ def handle_non_stream(previous_messages, msg_id, model, input_tokens):
324
  @app.errorhandler(404)
325
  def not_found(error):
326
  log_request(request.remote_addr, request.path, 404)
327
- return "Not Found", 404
328
 
329
  @app.errorhandler(500)
330
  def server_error(error):
331
  app_logger.error(f"Server error: {str(error)}")
332
  log_request(request.remote_addr, request.path, 500)
333
- return "Something broke!", 500
334
 
335
  def create_event(event, data):
336
  if isinstance(data, dict):
337
  data = json.dumps(data, ensure_ascii=False)
338
- return f"event: {event}\ndata: {data}\n\n"
 
 
339
 
340
  if __name__ == '__main__':
341
  port = int(os.environ.get('PORT', 8081))
 
66
  api_key = request.headers.get('x-api-key')
67
  if api_key != API_KEY:
68
  log_request(request.remote_addr, request.path, 401)
69
+ return create_json_response({"error": "Invalid API key"}), 401
70
  return None
71
 
72
  def normalize_content(content):
 
95
  tokens = text.split()
96
  return len(tokens)
97
 
98
+ def create_json_response(data):
99
+ """创建一个JSON响应,并在发送之前记录它"""
100
+ json_str = json.dumps(data, ensure_ascii=False)
101
+ app_logger.info(f"Sending JSON response: {json_str}")
102
+ return Response(json_str, content_type='application/json')
103
+
104
  @app.route('/')
105
  def root():
106
  log_request(request.remote_addr, request.path, 200)
107
+ return create_json_response({
108
  "message": "Welcome to the Perplexity AI Proxy API",
109
  "endpoints": {
110
  "/ai/v1/messages": {
 
147
  log_request(request.remote_addr, request.path, 200)
148
 
149
  def generate():
150
+ try:
151
+ yield create_event("message_start", {
152
+ "type": "message_start",
153
+ "message": {
154
+ "id": msg_id,
155
+ "type": "message",
156
+ "role": "assistant",
157
+ "content": [],
158
+ "model": model,
159
+ "stop_reason": None,
160
+ "stop_sequence": None,
161
+ "usage": {"input_tokens": input_tokens, "output_tokens": 1},
162
+ },
163
+ })
164
+ yield create_event("content_block_start", {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}})
165
+ yield create_event("ping", {"type": "ping"})
166
+
167
+ def on_connect():
168
+ app_logger.info("Connected to Perplexity AI")
169
+ emit_data = {
170
+ "version": "2.9",
171
+ "source": "default",
172
+ "attachments": [],
173
+ "language": "en-GB",
174
+ "timezone": "Europe/London",
175
+ "mode": "concise",
176
+ "is_related_query": False,
177
+ "is_default_related_query": False,
178
+ "visitor_id": str(uuid.uuid4()),
179
+ "frontend_context_uuid": str(uuid.uuid4()),
180
+ "prompt_source": "user",
181
+ "query_source": "home"
182
+ }
183
+ sio.emit('perplexity_ask', (previous_messages, emit_data))
184
+
185
+ def on_query_progress(data):
186
+ nonlocal response_text
187
+ if 'text' in data:
188
+ text = json.loads(data['text'])
189
+ chunk = text['chunks'][-1] if text['chunks'] else None
190
+ if chunk:
191
+ response_text.append(chunk)
192
+
193
+ if data.get('final', False):
194
+ response_event.set()
195
+
196
+ def on_disconnect():
197
+ app_logger.info("Disconnected from Perplexity AI")
198
  response_event.set()
199
 
200
+ def on_connect_error(data):
201
+ app_logger.error(f"Connection error: {data}")
202
+ response_text.append(f"Error connecting to Perplexity AI: {data}")
203
+ response_event.set()
 
 
 
 
204
 
205
+ sio.on('connect', on_connect)
206
+ sio.on('query_progress', on_query_progress)
207
+ sio.on('disconnect', on_disconnect)
208
+ sio.on('connect_error', on_connect_error)
209
 
 
210
  sio.connect('wss://www.perplexity.ai/', **connect_opts, headers=sio_opts['extraHeaders'])
211
 
212
  while not response_event.is_set():
213
  sio.sleep(0.1)
214
  while response_text:
215
  chunk = response_text.pop(0)
 
216
  app_logger.info(f"Returning chunk to client: {chunk}")
217
  yield create_event("content_block_delta", {
218
  "type": "content_block_delta",
 
220
  "delta": {"type": "text_delta", "text": chunk},
221
  })
222
 
223
+ output_tokens = calculate_tokens(''.join(response_text))
224
+
225
+ yield create_event("content_block_stop", {"type": "content_block_stop", "index": 0})
226
+ yield create_event("message_delta", {
227
+ "type": "message_delta",
228
+ "delta": {"stop_reason": "end_turn", "stop_sequence": None},
229
+ "usage": {"input_tokens": input_tokens, "output_tokens": output_tokens},
230
  })
231
+ yield create_event("message_stop", {"type": "message_stop"})
232
+
233
+ except Exception as e:
234
+ app_logger.error(f"Error in generate function: {str(e)}")
235
+ yield create_event("error", {"type": "error", "message": str(e)})
236
  finally:
237
  if sio.connected:
238
  sio.disconnect()
239
 
 
 
 
 
 
 
 
 
 
 
240
  return Response(generate(), content_type='text/event-stream')
241
 
242
  except Exception as e:
243
  app_logger.error(f"Request error: {str(e)}")
244
  log_request(request.remote_addr, request.path, 400)
245
+ return create_json_response({"error": str(e)}), 400
246
 
247
  def handle_non_stream(previous_messages, msg_id, model, input_tokens):
248
  try:
 
311
  },
312
  }
313
 
314
+ return create_json_response(full_response)
 
 
315
 
316
  except Exception as e:
317
  app_logger.error(f"Error during socket connection: {str(e)}")
318
+ return create_json_response({"error": str(e)}), 500
319
  finally:
320
  if sio.connected:
321
  sio.disconnect()
 
323
  @app.errorhandler(404)
324
  def not_found(error):
325
  log_request(request.remote_addr, request.path, 404)
326
+ return create_json_response({"error": "Not Found"}), 404
327
 
328
  @app.errorhandler(500)
329
  def server_error(error):
330
  app_logger.error(f"Server error: {str(error)}")
331
  log_request(request.remote_addr, request.path, 500)
332
+ return create_json_response({"error": "Internal Server Error"}), 500
333
 
334
  def create_event(event, data):
335
  if isinstance(data, dict):
336
  data = json.dumps(data, ensure_ascii=False)
337
+ event_str = f"event: {event}\ndata: {data}\n\n"
338
+ app_logger.info(f"Sending SSE event: {event_str}")
339
+ return event_str
340
 
341
  if __name__ == '__main__':
342
  port = int(os.environ.get('PORT', 8081))