Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -13,6 +13,8 @@ import threading
|
|
13 |
import aiohttp
|
14 |
import asyncio
|
15 |
from quart import Quart, request, jsonify
|
|
|
|
|
16 |
|
17 |
# Create a queue for log messages
|
18 |
log_queue = queue.Queue()
|
@@ -30,16 +32,23 @@ queue_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(me
|
|
30 |
logger.addHandler(queue_handler)
|
31 |
logger.setLevel(logging.INFO)
|
32 |
|
|
|
|
|
33 |
app = Flask(__name__)
|
34 |
-
|
|
|
35 |
CORS(app, resources={
|
36 |
r"/*": {
|
37 |
-
"origins": "
|
38 |
"methods": ["GET", "POST", "OPTIONS"],
|
39 |
-
"allow_headers": ["Content-Type", "Authorization"]
|
|
|
40 |
}
|
41 |
})
|
42 |
|
|
|
|
|
|
|
43 |
# Configuration
|
44 |
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
45 |
OPENROUTER_API_KEY = os.getenv('OPENROUTER_API_KEY')
|
@@ -48,6 +57,39 @@ SERPAPI_API_KEY = os.getenv('SERPAPI_API_KEY')
|
|
48 |
|
49 |
ssl._create_default_https_context = ssl._create_unverified_context
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
def generate_preliminary_plan(cluster_data):
|
52 |
logger.info("Generating preliminary plan...")
|
53 |
try:
|
@@ -601,32 +643,6 @@ async def generate_from_csv_text():
|
|
601 |
logger.error(f"Error in generate_from_csv_text: {e}")
|
602 |
return jsonify({'error': str(e)}), 500
|
603 |
|
604 |
-
@app.route('/logs/stream')
|
605 |
-
def stream_logs():
|
606 |
-
def generate():
|
607 |
-
while True:
|
608 |
-
try:
|
609 |
-
# Get log message from queue, timeout after 1 second
|
610 |
-
log_message = log_queue.get(timeout=1)
|
611 |
-
yield f"data: {log_message}\n\n"
|
612 |
-
except queue.Empty:
|
613 |
-
# Send a heartbeat to keep the connection alive
|
614 |
-
yield "data: heartbeat\n\n"
|
615 |
-
except GeneratorExit:
|
616 |
-
break
|
617 |
-
|
618 |
-
response = Response(stream_with_context(generate()), mimetype='text/event-stream')
|
619 |
-
response.headers['Cache-Control'] = 'no-cache'
|
620 |
-
response.headers['Connection'] = 'keep-alive'
|
621 |
-
response.headers['Access-Control-Allow-Origin'] = '*'
|
622 |
-
return response
|
623 |
-
|
624 |
if __name__ == '__main__':
|
625 |
-
logger.info("Starting Flask API server...")
|
626 |
-
|
627 |
-
import hypercorn.config
|
628 |
-
|
629 |
-
config = hypercorn.config.Config()
|
630 |
-
config.bind = ["127.0.0.1:5001"]
|
631 |
-
|
632 |
-
asyncio.run(hypercorn.asyncio.serve(app, config))
|
|
|
13 |
import aiohttp
|
14 |
import asyncio
|
15 |
from quart import Quart, request, jsonify
|
16 |
+
from flask_socketio import SocketIO, emit
|
17 |
+
import eventlet
|
18 |
|
19 |
# Create a queue for log messages
|
20 |
log_queue = queue.Queue()
|
|
|
32 |
logger.addHandler(queue_handler)
|
33 |
logger.setLevel(logging.INFO)
|
34 |
|
35 |
+
# Initialize Flask app with eventlet
|
36 |
+
eventlet.monkey_patch()
|
37 |
app = Flask(__name__)
|
38 |
+
|
39 |
+
# Configure CORS with WebSocket support
|
40 |
CORS(app, resources={
|
41 |
r"/*": {
|
42 |
+
"origins": ["http://localhost:8000", "http://127.0.0.1:8000"], # Add your Laravel domains
|
43 |
"methods": ["GET", "POST", "OPTIONS"],
|
44 |
+
"allow_headers": ["Content-Type", "Authorization"],
|
45 |
+
"supports_credentials": True
|
46 |
}
|
47 |
})
|
48 |
|
49 |
+
# Initialize SocketIO with CORS support
|
50 |
+
socketio = SocketIO(app, cors_allowed_origins=["http://localhost:8000", "http://127.0.0.1:8000"], async_mode='eventlet')
|
51 |
+
|
52 |
# Configuration
|
53 |
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
54 |
OPENROUTER_API_KEY = os.getenv('OPENROUTER_API_KEY')
|
|
|
57 |
|
58 |
ssl._create_default_https_context = ssl._create_unverified_context
|
59 |
|
60 |
+
# WebSocket event handlers
|
61 |
+
@socketio.on('connect')
|
62 |
+
def handle_connect():
|
63 |
+
logger.info("Client connected")
|
64 |
+
emit('connection_response', {'status': 'connected'})
|
65 |
+
|
66 |
+
@socketio.on('disconnect')
|
67 |
+
def handle_disconnect():
|
68 |
+
logger.info("Client disconnected")
|
69 |
+
|
70 |
+
@socketio.on_error()
|
71 |
+
def error_handler(e):
|
72 |
+
logger.error(f"SocketIO error: {str(e)}")
|
73 |
+
emit('error', {'error': str(e)})
|
74 |
+
|
75 |
+
# Modified stream_logs route to use WebSocket
|
76 |
+
@socketio.on('subscribe_logs')
|
77 |
+
def handle_subscribe_logs():
|
78 |
+
try:
|
79 |
+
while True:
|
80 |
+
try:
|
81 |
+
log_message = log_queue.get(timeout=1)
|
82 |
+
emit('log_message', {'message': log_message})
|
83 |
+
except queue.Empty:
|
84 |
+
emit('heartbeat', {'message': 'heartbeat'})
|
85 |
+
except Exception as e:
|
86 |
+
logger.error(f"Error in log streaming: {e}")
|
87 |
+
emit('error', {'error': str(e)})
|
88 |
+
eventlet.sleep(0.1) # Prevent CPU overuse
|
89 |
+
except Exception as e:
|
90 |
+
logger.error(f"Error in log subscription: {e}")
|
91 |
+
emit('error', {'error': str(e)})
|
92 |
+
|
93 |
def generate_preliminary_plan(cluster_data):
|
94 |
logger.info("Generating preliminary plan...")
|
95 |
try:
|
|
|
643 |
logger.error(f"Error in generate_from_csv_text: {e}")
|
644 |
return jsonify({'error': str(e)}), 500
|
645 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
if __name__ == '__main__':
|
647 |
+
logger.info("Starting Flask API server with SocketIO...")
|
648 |
+
socketio.run(app, host='127.0.0.1', port=5001, debug=True)
|
|
|
|
|
|
|
|
|
|
|
|