smgc commited on
Commit
af3d711
1 Parent(s): d6550e2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -54
app.py CHANGED
@@ -1,37 +1,15 @@
1
  import os
2
  import json
3
  import uuid
 
4
  from datetime import datetime
5
  from flask import Flask, request, Response, jsonify
6
  import socketio
7
  import requests
8
  import logging
9
  from threading import Event
10
- import re
11
-
12
- # 自定义日志格式化器
13
- class CustomFormatter(logging.Formatter):
14
- def format(self, record):
15
- log_data = {
16
- "timestamp": self.formatTime(record, self.datefmt),
17
- "level": record.levelname,
18
- "message": record.getMessage(),
19
- }
20
- if hasattr(record, 'event_type'):
21
- log_data['event_type'] = record.event_type
22
- if hasattr(record, 'data'):
23
- log_data['data'] = record.data
24
- return json.dumps(log_data, ensure_ascii=False, indent=2)
25
-
26
- def setup_logging():
27
- logger = logging.getLogger()
28
- logger.setLevel(logging.INFO)
29
- handler = logging.StreamHandler()
30
- handler.setFormatter(CustomFormatter())
31
- logger.addHandler(handler)
32
 
33
  app = Flask(__name__)
34
- logger = logging.getLogger(__name__)
35
 
36
  # 从环境变量中获取API密钥
37
  API_KEY = os.environ.get('PPLX_KEY')
@@ -54,7 +32,7 @@ sio = socketio.Client(http_session=transport, logger=False, engineio_logger=Fals
54
 
55
  # 连接选项
56
  connect_opts = {
57
- 'transports': ['websocket', 'polling'], # 允许回退到轮询
58
  }
59
 
60
  # 其他选项
@@ -68,10 +46,38 @@ sio_opts = {
68
  }
69
  }
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  def log_request(ip, route, status):
72
- logger.info(f"HTTP Request", extra={
73
- 'event_type': 'http_request',
 
74
  'data': {
 
75
  'ip': ip,
76
  'route': route,
77
  'status': status
@@ -156,7 +162,7 @@ def messages():
156
  def generate():
157
  nonlocal total_output_tokens
158
 
159
- yield create_event("message_start", {
160
  "type": "message_start",
161
  "message": {
162
  "id": msg_id,
@@ -169,8 +175,25 @@ def messages():
169
  "usage": {"input_tokens": input_tokens, "output_tokens": total_output_tokens},
170
  },
171
  })
172
- yield create_event("content_block_start", {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}})
173
- yield create_event("ping", {"type": "ping"})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  def on_query_progress(data):
176
  nonlocal total_output_tokens, response_text
@@ -181,22 +204,23 @@ def messages():
181
  response_text.append(chunk)
182
  chunk_tokens = calculate_tokens(chunk)
183
  total_output_tokens += chunk_tokens
184
- logger.info("Received chunk", extra={
185
- 'event_type': 'chunk_received',
 
 
 
 
 
186
  'data': {
187
  'chunk': chunk,
188
  'tokens': chunk_tokens,
189
- 'total_tokens': total_output_tokens
 
190
  }
191
  })
 
192
 
193
  if data.get('final', False):
194
- logger.info("Final response received", extra={
195
- 'event_type': 'response_complete',
196
- 'data': {
197
- 'total_tokens': total_output_tokens
198
- }
199
- })
200
  response_event.set()
201
 
202
  def on_connect():
@@ -231,16 +255,9 @@ def messages():
231
 
232
  while not response_event.is_set():
233
  sio.sleep(0.1)
234
- while response_text:
235
- chunk = response_text.pop(0)
236
- yield create_event("content_block_delta", {
237
- "type": "content_block_delta",
238
- "index": 0,
239
- "delta": {"type": "text_delta", "text": chunk},
240
- })
241
 
242
  except Exception as e:
243
- logger.error(f"Error during socket connection", extra={
244
  'event_type': 'connection_error',
245
  'data': {'error': str(e)}
246
  })
@@ -253,18 +270,35 @@ def messages():
253
  if sio.connected:
254
  sio.disconnect()
255
 
256
- yield create_event("content_block_stop", {"type": "content_block_stop", "index": 0})
257
- yield create_event("message_delta", {
 
 
 
 
 
 
258
  "type": "message_delta",
259
  "delta": {"stop_reason": "end_turn", "stop_sequence": None},
260
  "usage": {"output_tokens": total_output_tokens},
261
  })
262
- yield create_event("message_stop", {"type": "message_stop"})
 
 
 
 
 
 
 
 
 
 
 
263
 
264
  return Response(generate(), content_type='text/event-stream')
265
 
266
  except Exception as e:
267
- logger.error(f"Request error", extra={
268
  'event_type': 'request_error',
269
  'data': {'error': str(e)}
270
  })
@@ -328,11 +362,15 @@ def handle_non_stream(previous_messages, msg_id, model, input_tokens):
328
  "output_tokens": total_output_tokens,
329
  },
330
  }
 
 
 
 
331
  return Response(json.dumps(full_response, ensure_ascii=False), content_type='application/json')
332
 
333
  except Exception as e:
334
- logger.error(f"Error during non-stream socket connection", extra={
335
- 'event_type': 'non_stream_connection_error',
336
  'data': {'error': str(e)}
337
  })
338
  return jsonify({"error": str(e)}), 500
@@ -347,7 +385,7 @@ def not_found(error):
347
 
348
  @app.errorhandler(500)
349
  def server_error(error):
350
- logger.error(f"Server error", extra={
351
  'event_type': 'server_error',
352
  'data': {'error': str(error)}
353
  })
@@ -357,7 +395,7 @@ def server_error(error):
357
  if __name__ == '__main__':
358
  setup_logging()
359
  port = int(os.environ.get('PORT', 8081))
360
- logger.info(f"Perplexity proxy starting", extra={
361
  'event_type': 'server_start',
362
  'data': {'port': port}
363
  })
 
1
  import os
2
  import json
3
  import uuid
4
+ import re
5
  from datetime import datetime
6
  from flask import Flask, request, Response, jsonify
7
  import socketio
8
  import requests
9
  import logging
10
  from threading import Event
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  app = Flask(__name__)
 
13
 
14
  # 从环境变量中获取API密钥
15
  API_KEY = os.environ.get('PPLX_KEY')
 
32
 
33
  # 连接选项
34
  connect_opts = {
35
+ 'transports': ['websocket', 'polling'],
36
  }
37
 
38
  # 其他选项
 
46
  }
47
  }
48
 
49
+ class CustomFormatter(logging.Formatter):
50
+ def format(self, record):
51
+ log_data = {
52
+ "timestamp": self.formatTime(record, self.datefmt),
53
+ "level": record.levelname,
54
+ "message": self.remove_ansi_escape(record.getMessage()),
55
+ }
56
+ if hasattr(record, 'event_type'):
57
+ log_data['event_type'] = record.event_type
58
+ if hasattr(record, 'data'):
59
+ log_data['data'] = record.data
60
+ return json.dumps(log_data, ensure_ascii=False, indent=2)
61
+
62
+ def remove_ansi_escape(self, text):
63
+ ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
64
+ return ansi_escape.sub('', text)
65
+
66
+ def setup_logging():
67
+ logger = logging.getLogger()
68
+ logger.setLevel(logging.INFO)
69
+ handler = logging.StreamHandler()
70
+ handler.setFormatter(CustomFormatter())
71
+ logger.addHandler(handler)
72
+
73
+ logger = logging.getLogger(__name__)
74
+
75
  def log_request(ip, route, status):
76
+ timestamp = datetime.now().isoformat()
77
+ logger.info(f"Request received", extra={
78
+ 'event_type': 'request',
79
  'data': {
80
+ 'timestamp': timestamp,
81
  'ip': ip,
82
  'route': route,
83
  'status': status
 
162
  def generate():
163
  nonlocal total_output_tokens
164
 
165
+ start_event = create_event("message_start", {
166
  "type": "message_start",
167
  "message": {
168
  "id": msg_id,
 
175
  "usage": {"input_tokens": input_tokens, "output_tokens": total_output_tokens},
176
  },
177
  })
178
+ logger.info("Sending message_start event", extra={
179
+ 'event_type': 'message_start',
180
+ 'data': {'content': start_event}
181
+ })
182
+ yield start_event
183
+
184
+ block_start_event = create_event("content_block_start", {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}})
185
+ logger.info("Sending content_block_start event", extra={
186
+ 'event_type': 'content_block_start',
187
+ 'data': {'content': block_start_event}
188
+ })
189
+ yield block_start_event
190
+
191
+ ping_event = create_event("ping", {"type": "ping"})
192
+ logger.info("Sending ping event", extra={
193
+ 'event_type': 'ping',
194
+ 'data': {'content': ping_event}
195
+ })
196
+ yield ping_event
197
 
198
  def on_query_progress(data):
199
  nonlocal total_output_tokens, response_text
 
204
  response_text.append(chunk)
205
  chunk_tokens = calculate_tokens(chunk)
206
  total_output_tokens += chunk_tokens
207
+ delta_event = create_event("content_block_delta", {
208
+ "type": "content_block_delta",
209
+ "index": 0,
210
+ "delta": {"type": "text_delta", "text": chunk},
211
+ })
212
+ logger.info("Sending content_block_delta event", extra={
213
+ 'event_type': 'content_block_delta',
214
  'data': {
215
  'chunk': chunk,
216
  'tokens': chunk_tokens,
217
+ 'total_tokens': total_output_tokens,
218
+ 'content': delta_event
219
  }
220
  })
221
+ yield delta_event
222
 
223
  if data.get('final', False):
 
 
 
 
 
 
224
  response_event.set()
225
 
226
  def on_connect():
 
255
 
256
  while not response_event.is_set():
257
  sio.sleep(0.1)
 
 
 
 
 
 
 
258
 
259
  except Exception as e:
260
+ logger.error(f"Error during socket connection: {str(e)}", extra={
261
  'event_type': 'connection_error',
262
  'data': {'error': str(e)}
263
  })
 
270
  if sio.connected:
271
  sio.disconnect()
272
 
273
+ stop_event = create_event("content_block_stop", {"type": "content_block_stop", "index": 0})
274
+ logger.info("Sending content_block_stop event", extra={
275
+ 'event_type': 'content_block_stop',
276
+ 'data': {'content': stop_event}
277
+ })
278
+ yield stop_event
279
+
280
+ message_delta_event = create_event("message_delta", {
281
  "type": "message_delta",
282
  "delta": {"stop_reason": "end_turn", "stop_sequence": None},
283
  "usage": {"output_tokens": total_output_tokens},
284
  })
285
+ logger.info("Sending message_delta event", extra={
286
+ 'event_type': 'message_delta',
287
+ 'data': {'content': message_delta_event}
288
+ })
289
+ yield message_delta_event
290
+
291
+ message_stop_event = create_event("message_stop", {"type": "message_stop"})
292
+ logger.info("Sending message_stop event", extra={
293
+ 'event_type': 'message_stop',
294
+ 'data': {'content': message_stop_event}
295
+ })
296
+ yield message_stop_event
297
 
298
  return Response(generate(), content_type='text/event-stream')
299
 
300
  except Exception as e:
301
+ logger.error(f"Request error: {str(e)}", extra={
302
  'event_type': 'request_error',
303
  'data': {'error': str(e)}
304
  })
 
362
  "output_tokens": total_output_tokens,
363
  },
364
  }
365
+ logger.info("Sending non-stream response", extra={
366
+ 'event_type': 'non_stream_response',
367
+ 'data': {'content': full_response}
368
+ })
369
  return Response(json.dumps(full_response, ensure_ascii=False), content_type='application/json')
370
 
371
  except Exception as e:
372
+ logger.error(f"Error during socket connection: {str(e)}", extra={
373
+ 'event_type': 'connection_error_non_stream',
374
  'data': {'error': str(e)}
375
  })
376
  return jsonify({"error": str(e)}), 500
 
385
 
386
  @app.errorhandler(500)
387
  def server_error(error):
388
+ logger.error(f"Server error: {str(error)}", extra={
389
  'event_type': 'server_error',
390
  'data': {'error': str(error)}
391
  })
 
395
  if __name__ == '__main__':
396
  setup_logging()
397
  port = int(os.environ.get('PORT', 8081))
398
+ logger.info("Perplexity proxy starting", extra={
399
  'event_type': 'server_start',
400
  'data': {'port': port}
401
  })