Update app.py
Browse files
app.py
CHANGED
@@ -11,6 +11,7 @@ import re
|
|
11 |
|
12 |
app = Flask(__name__)
|
13 |
|
|
|
14 |
class CustomFormatter(logging.Formatter):
|
15 |
def format(self, record):
|
16 |
log_data = {
|
@@ -37,9 +38,13 @@ def setup_logging():
|
|
37 |
|
38 |
logger = logging.getLogger(__name__)
|
39 |
|
|
|
40 |
API_KEY = os.environ.get('PPLX_KEY')
|
|
|
|
|
41 |
proxy_url = os.environ.get('PROXY_URL')
|
42 |
|
|
|
43 |
if proxy_url:
|
44 |
proxies = {
|
45 |
'http': proxy_url,
|
@@ -52,10 +57,12 @@ else:
|
|
52 |
|
53 |
sio = socketio.Client(http_session=transport, logger=False, engineio_logger=False)
|
54 |
|
|
|
55 |
connect_opts = {
|
56 |
'transports': ['websocket', 'polling'],
|
57 |
}
|
58 |
|
|
|
59 |
sio_opts = {
|
60 |
'extraHeaders': {
|
61 |
'Cookie': os.environ.get('PPLX_COOKIE'),
|
@@ -107,11 +114,6 @@ def create_event(event, data):
|
|
107 |
data = json.dumps(data, ensure_ascii=False)
|
108 |
return f"event: {event}\ndata: {data}\n\n"
|
109 |
|
110 |
-
def calculate_timeout(input_tokens):
|
111 |
-
base_timeout = 30
|
112 |
-
additional_time = min(max(input_tokens // 100 * 5, 0), 270)
|
113 |
-
return base_timeout + additional_time
|
114 |
-
|
115 |
@app.route('/')
|
116 |
def root():
|
117 |
log_request(request.remote_addr, request.path, 200)
|
@@ -127,8 +129,8 @@ def root():
|
|
127 |
},
|
128 |
"body": {
|
129 |
"messages": "Array of message objects",
|
130 |
-
"stream": "Boolean (
|
131 |
-
"model": "Model to be used (optional, defaults to claude-3-
|
132 |
}
|
133 |
}
|
134 |
}
|
@@ -147,7 +149,6 @@ def messages():
|
|
147 |
|
148 |
previous_messages = "\n\n".join([normalize_content(msg['content']) for msg in json_body['messages']])
|
149 |
input_tokens = calculate_tokens(previous_messages)
|
150 |
-
timeout = calculate_timeout(input_tokens)
|
151 |
|
152 |
msg_id = str(uuid.uuid4())
|
153 |
response_event = Event()
|
@@ -156,7 +157,7 @@ def messages():
|
|
156 |
total_output_tokens = 0
|
157 |
|
158 |
if not stream:
|
159 |
-
return handle_non_stream(previous_messages, msg_id, model, input_tokens
|
160 |
|
161 |
log_request(request.remote_addr, request.path, 200)
|
162 |
|
@@ -171,6 +172,7 @@ def messages():
|
|
171 |
})
|
172 |
yield event
|
173 |
|
|
|
174 |
yield from send_event("message_start", {
|
175 |
"type": "message_start",
|
176 |
"message": {
|
@@ -242,17 +244,11 @@ def messages():
|
|
242 |
sio.on('query_progress', on_query_progress)
|
243 |
|
244 |
def timeout_handler():
|
245 |
-
logger.warning("Request timed out", extra={
|
246 |
-
'event_type': 'request_timeout',
|
247 |
-
'data': {
|
248 |
-
'input_tokens': input_tokens,
|
249 |
-
'timeout': timeout
|
250 |
-
}
|
251 |
-
})
|
252 |
timeout_event.set()
|
253 |
response_event.set()
|
254 |
|
255 |
-
timer = Timer(
|
256 |
timer.start()
|
257 |
|
258 |
try:
|
@@ -287,6 +283,7 @@ def messages():
|
|
287 |
if sio.connected:
|
288 |
sio.disconnect()
|
289 |
|
|
|
290 |
yield from send_event("content_block_stop", {"type": "content_block_stop", "index": 0})
|
291 |
yield from send_event("message_delta", {
|
292 |
"type": "message_delta",
|
@@ -302,7 +299,7 @@ def messages():
|
|
302 |
log_request(request.remote_addr, request.path, 400)
|
303 |
return jsonify({"error": str(e)}), 400
|
304 |
|
305 |
-
def handle_non_stream(previous_messages, msg_id, model, input_tokens
|
306 |
try:
|
307 |
response_event = Event()
|
308 |
response_text = []
|
@@ -344,16 +341,11 @@ def handle_non_stream(previous_messages, msg_id, model, input_tokens, timeout):
|
|
344 |
|
345 |
sio.connect('wss://www.perplexity.ai/', **connect_opts, headers=sio_opts['extraHeaders'])
|
346 |
|
347 |
-
|
|
|
348 |
|
349 |
if not response_text:
|
350 |
-
logger.warning("No response received (non-stream)", extra={
|
351 |
-
'event_type': 'no_response_non_stream',
|
352 |
-
'data': {
|
353 |
-
'input_tokens': input_tokens,
|
354 |
-
'timeout': timeout
|
355 |
-
}
|
356 |
-
})
|
357 |
return jsonify({"error": "No response received"}), 504
|
358 |
|
359 |
full_response = {
|
|
|
11 |
|
12 |
app = Flask(__name__)
|
13 |
|
14 |
+
# 自定义日志格式化器
|
15 |
class CustomFormatter(logging.Formatter):
|
16 |
def format(self, record):
|
17 |
log_data = {
|
|
|
38 |
|
39 |
logger = logging.getLogger(__name__)
|
40 |
|
41 |
+
# 从环境变量中获取API密钥
|
42 |
API_KEY = os.environ.get('PPLX_KEY')
|
43 |
+
|
44 |
+
# 代理设置
|
45 |
proxy_url = os.environ.get('PROXY_URL')
|
46 |
|
47 |
+
# 设置代理
|
48 |
if proxy_url:
|
49 |
proxies = {
|
50 |
'http': proxy_url,
|
|
|
57 |
|
58 |
sio = socketio.Client(http_session=transport, logger=False, engineio_logger=False)
|
59 |
|
60 |
+
# 连接选项
|
61 |
connect_opts = {
|
62 |
'transports': ['websocket', 'polling'],
|
63 |
}
|
64 |
|
65 |
+
# 其他选项
|
66 |
sio_opts = {
|
67 |
'extraHeaders': {
|
68 |
'Cookie': os.environ.get('PPLX_COOKIE'),
|
|
|
114 |
data = json.dumps(data, ensure_ascii=False)
|
115 |
return f"event: {event}\ndata: {data}\n\n"
|
116 |
|
|
|
|
|
|
|
|
|
|
|
117 |
@app.route('/')
|
118 |
def root():
|
119 |
log_request(request.remote_addr, request.path, 200)
|
|
|
129 |
},
|
130 |
"body": {
|
131 |
"messages": "Array of message objects",
|
132 |
+
"stream": "Boolean (true for streaming response)",
|
133 |
+
"model": "Model to be used (optional, defaults to claude-3-opus-20240229)"
|
134 |
}
|
135 |
}
|
136 |
}
|
|
|
149 |
|
150 |
previous_messages = "\n\n".join([normalize_content(msg['content']) for msg in json_body['messages']])
|
151 |
input_tokens = calculate_tokens(previous_messages)
|
|
|
152 |
|
153 |
msg_id = str(uuid.uuid4())
|
154 |
response_event = Event()
|
|
|
157 |
total_output_tokens = 0
|
158 |
|
159 |
if not stream:
|
160 |
+
return handle_non_stream(previous_messages, msg_id, model, input_tokens)
|
161 |
|
162 |
log_request(request.remote_addr, request.path, 200)
|
163 |
|
|
|
172 |
})
|
173 |
yield event
|
174 |
|
175 |
+
# Send initial events
|
176 |
yield from send_event("message_start", {
|
177 |
"type": "message_start",
|
178 |
"message": {
|
|
|
244 |
sio.on('query_progress', on_query_progress)
|
245 |
|
246 |
def timeout_handler():
|
247 |
+
logger.warning("Request timed out", extra={'event_type': 'request_timeout'})
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
timeout_event.set()
|
249 |
response_event.set()
|
250 |
|
251 |
+
timer = Timer(60, timeout_handler) # 60 seconds timeout
|
252 |
timer.start()
|
253 |
|
254 |
try:
|
|
|
283 |
if sio.connected:
|
284 |
sio.disconnect()
|
285 |
|
286 |
+
# Send final events
|
287 |
yield from send_event("content_block_stop", {"type": "content_block_stop", "index": 0})
|
288 |
yield from send_event("message_delta", {
|
289 |
"type": "message_delta",
|
|
|
299 |
log_request(request.remote_addr, request.path, 400)
|
300 |
return jsonify({"error": str(e)}), 400
|
301 |
|
302 |
+
def handle_non_stream(previous_messages, msg_id, model, input_tokens):
|
303 |
try:
|
304 |
response_event = Event()
|
305 |
response_text = []
|
|
|
341 |
|
342 |
sio.connect('wss://www.perplexity.ai/', **connect_opts, headers=sio_opts['extraHeaders'])
|
343 |
|
344 |
+
# Wait for response with timeout
|
345 |
+
response_event.wait(timeout=30)
|
346 |
|
347 |
if not response_text:
|
348 |
+
logger.warning("No response received (non-stream)", extra={'event_type': 'no_response_non_stream'})
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
return jsonify({"error": "No response received"}), 504
|
350 |
|
351 |
full_response = {
|