Spaces:
Running
Running
Trisha Tomy
commited on
Commit
·
0d53358
1
Parent(s):
f19a4ca
Fix asyncio event loop management in app.py for Gunicorn workers
Browse files
app.py
CHANGED
@@ -5,21 +5,17 @@ from proxy_lite import Runner, RunnerConfig
|
|
5 |
import os
|
6 |
import logging
|
7 |
|
8 |
-
# Configure logging for better visibility in Space logs
|
9 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
10 |
logger = logging.getLogger(__name__)
|
11 |
|
12 |
app = Flask(__name__)
|
13 |
|
14 |
-
# Global runner instance. It will be initialized once.
|
15 |
_runner = None
|
16 |
|
17 |
async def initialize_runner():
|
18 |
-
"""Initializes the Proxy-lite Runner asynchronously."""
|
19 |
global _runner
|
20 |
if _runner is None:
|
21 |
logger.info("Initializing Proxy-lite Runner...")
|
22 |
-
# Retrieve Hugging Face API Token from environment variables (set as Space Secret)
|
23 |
hf_api_token = os.environ.get("HF_API_TOKEN")
|
24 |
if not hf_api_token:
|
25 |
logger.error("HF_API_TOKEN environment variable not set. Cannot initialize Runner.")
|
@@ -29,7 +25,7 @@ async def initialize_runner():
|
|
29 |
"environment": {
|
30 |
"name": "webbrowser",
|
31 |
"homepage": "https://www.google.com",
|
32 |
-
"headless": True,
|
33 |
},
|
34 |
"solver": {
|
35 |
"name": "simple",
|
@@ -38,9 +34,8 @@ async def initialize_runner():
|
|
38 |
"client": {
|
39 |
"name": "convergence",
|
40 |
"model_id": "convergence-ai/proxy-lite-3b",
|
41 |
-
# THIS IS THE HUGGING FACE INFERENCE API ENDPOINT
|
42 |
"api_base": "https://api-inference.huggingface.co/models/convergence-ai/proxy-lite-3b",
|
43 |
-
"api_key": hf_api_token
|
44 |
}
|
45 |
}
|
46 |
}
|
@@ -49,15 +44,27 @@ async def initialize_runner():
|
|
49 |
logger.info("Proxy-lite Runner initialized successfully.")
|
50 |
return _runner
|
51 |
|
52 |
-
#
|
53 |
def run_async_task(coro):
|
54 |
-
"""
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
return loop.run_until_complete(coro)
|
|
|
|
|
57 |
|
58 |
@app.route('/run_proxy_task', methods=['POST'])
|
59 |
def run_proxy_task_endpoint():
|
60 |
-
"""API endpoint to receive a task and execute it with Proxy-lite."""
|
61 |
data = request.json
|
62 |
task = data.get('task')
|
63 |
if not task:
|
@@ -66,32 +73,23 @@ def run_proxy_task_endpoint():
|
|
66 |
|
67 |
logger.info(f"Received task for proxy-lite: '{task}'")
|
68 |
try:
|
69 |
-
# Initialize runner if not already done
|
70 |
runner = run_async_task(initialize_runner())
|
71 |
-
# Run the task using the proxy-lite runner
|
72 |
result = run_async_task(runner.run(task))
|
73 |
|
74 |
-
logger.info(f"Proxy-lite task completed. Output: {result[:200]}...")
|
75 |
-
# Return the result as a JSON response
|
76 |
return jsonify({"output": result})
|
77 |
except Exception as e:
|
78 |
-
logger.exception(f"Error processing task '{task}':")
|
79 |
return jsonify({"error": f"An error occurred: {str(e)}. Check logs for details."}), 500
|
80 |
|
81 |
@app.route('/')
|
82 |
def root():
|
83 |
-
"""Basic root endpoint for health check."""
|
84 |
logger.info("Root endpoint accessed.")
|
85 |
return "Proxy-lite API is running. Send POST requests to /run_proxy_task with a 'task' in JSON body."
|
86 |
|
87 |
if __name__ == '__main__':
|
88 |
-
# Check if HF_API_TOKEN is set during local development/testing
|
89 |
if not os.environ.get("HF_API_TOKEN"):
|
90 |
logger.error("HF_API_TOKEN environment variable is not set. Please set it for local testing.")
|
91 |
-
|
92 |
-
# For deployment on Hugging Face Spaces, it MUST be set as a Secret.
|
93 |
-
# exit(1) # Uncomment this if you want to force exit without token locally
|
94 |
-
|
95 |
logger.info("Starting Flask development server on 0.0.0.0:7860...")
|
96 |
-
|
97 |
-
app.run(host='0.0.0.0', port=7860, debug=True) # debug=True for local, disable for production
|
|
|
5 |
import os
|
6 |
import logging
|
7 |
|
|
|
8 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
9 |
logger = logging.getLogger(__name__)
|
10 |
|
11 |
app = Flask(__name__)
|
12 |
|
|
|
13 |
_runner = None
|
14 |
|
15 |
async def initialize_runner():
|
|
|
16 |
global _runner
|
17 |
if _runner is None:
|
18 |
logger.info("Initializing Proxy-lite Runner...")
|
|
|
19 |
hf_api_token = os.environ.get("HF_API_TOKEN")
|
20 |
if not hf_api_token:
|
21 |
logger.error("HF_API_TOKEN environment variable not set. Cannot initialize Runner.")
|
|
|
25 |
"environment": {
|
26 |
"name": "webbrowser",
|
27 |
"homepage": "https://www.google.com",
|
28 |
+
"headless": True,
|
29 |
},
|
30 |
"solver": {
|
31 |
"name": "simple",
|
|
|
34 |
"client": {
|
35 |
"name": "convergence",
|
36 |
"model_id": "convergence-ai/proxy-lite-3b",
|
|
|
37 |
"api_base": "https://api-inference.huggingface.co/models/convergence-ai/proxy-lite-3b",
|
38 |
+
"api_key": hf_api_token
|
39 |
}
|
40 |
}
|
41 |
}
|
|
|
44 |
logger.info("Proxy-lite Runner initialized successfully.")
|
45 |
return _runner
|
46 |
|
47 |
+
# --- MODIFIED run_async_task FUNCTION ---
|
48 |
def run_async_task(coro):
|
49 |
+
"""
|
50 |
+
Helper to run async coroutines in a synchronous context (like Flask routes).
|
51 |
+
Ensures an event loop exists and runs the coroutine.
|
52 |
+
"""
|
53 |
+
try:
|
54 |
+
# Try to get the running loop (for current thread/greenlet)
|
55 |
+
loop = asyncio.get_running_loop()
|
56 |
+
except RuntimeError:
|
57 |
+
# If no loop is running, create a new one for this thread
|
58 |
+
loop = asyncio.new_event_loop()
|
59 |
+
asyncio.set_event_loop(loop)
|
60 |
+
|
61 |
+
# Run the coroutine until it completes
|
62 |
return loop.run_until_complete(coro)
|
63 |
+
# --- END MODIFIED run_async_task FUNCTION ---
|
64 |
+
|
65 |
|
66 |
@app.route('/run_proxy_task', methods=['POST'])
|
67 |
def run_proxy_task_endpoint():
|
|
|
68 |
data = request.json
|
69 |
task = data.get('task')
|
70 |
if not task:
|
|
|
73 |
|
74 |
logger.info(f"Received task for proxy-lite: '{task}'")
|
75 |
try:
|
|
|
76 |
runner = run_async_task(initialize_runner())
|
|
|
77 |
result = run_async_task(runner.run(task))
|
78 |
|
79 |
+
logger.info(f"Proxy-lite task completed. Output: {result[:200]}...")
|
|
|
80 |
return jsonify({"output": result})
|
81 |
except Exception as e:
|
82 |
+
logger.exception(f"Error processing task '{task}':")
|
83 |
return jsonify({"error": f"An error occurred: {str(e)}. Check logs for details."}), 500
|
84 |
|
85 |
@app.route('/')
|
86 |
def root():
|
|
|
87 |
logger.info("Root endpoint accessed.")
|
88 |
return "Proxy-lite API is running. Send POST requests to /run_proxy_task with a 'task' in JSON body."
|
89 |
|
90 |
if __name__ == '__main__':
|
|
|
91 |
if not os.environ.get("HF_API_TOKEN"):
|
92 |
logger.error("HF_API_TOKEN environment variable is not set. Please set it for local testing.")
|
93 |
+
exit(1)
|
|
|
|
|
|
|
94 |
logger.info("Starting Flask development server on 0.0.0.0:7860...")
|
95 |
+
app.run(host='0.0.0.0', port=7860, debug=True)
|
|