mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-04-27 19:02:31 +08:00
- Wrap all scheduler.sync_* calls in automation_routes.py with asyncio.get_running_loop().run_in_executor() to avoid blocking the async event loop - Replace bare 'except: pass' in paper_search._save_papers_to_project with logging.warning - Make API base URL configurable via RESEARCH_API_BASE_URL env var Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
4.2 KiB
Python
104 lines
4.2 KiB
Python
"""Automation routes for job scheduling."""
|
|
import asyncio
|
|
from functools import partial
|
|
from aiohttp import web
|
|
from custom_nodes.research.automation.schedule import scheduler, Job
|
|
|
|
|
|
class AutomationRoutes:
|
|
def __init__(self):
|
|
self.routes: web.RouteTableDef = web.RouteTableDef()
|
|
self._app: web.Application = None
|
|
|
|
def get_app(self) -> web.Application:
|
|
if self._app is None:
|
|
self._app = web.Application()
|
|
self._app.add_routes(self.routes)
|
|
return self._app
|
|
|
|
def setup_routes(self):
|
|
# List all jobs
|
|
@self.routes.get("/research/automation/jobs/")
|
|
async def list_jobs(request):
|
|
loop = asyncio.get_running_loop()
|
|
jobs = await loop.run_in_executor(None, scheduler.list_jobs)
|
|
return web.json_response(jobs)
|
|
|
|
# Get a specific job
|
|
@self.routes.get("/research/automation/jobs/{job_id}")
|
|
async def get_job(request):
|
|
job_id = request.match_info["job_id"]
|
|
loop = asyncio.get_running_loop()
|
|
job = await loop.run_in_executor(None, lambda: scheduler.get_job(job_id))
|
|
if not job:
|
|
return web.json_response({"error": "Job not found"}, status=404)
|
|
return web.json_response({
|
|
"id": job.id,
|
|
"name": job.name,
|
|
"schedule": {
|
|
"interval_hours": job.schedule.interval_hours,
|
|
"cron_hour": job.schedule.cron_hour,
|
|
"cron_minute": job.schedule.cron_minute,
|
|
"enabled": job.schedule.enabled,
|
|
},
|
|
"last_run": job.last_run.isoformat() if job.last_run else None,
|
|
"last_result": str(job.last_result) if job.last_result else None,
|
|
"last_error": job.error,
|
|
"run_count": job.run_count,
|
|
})
|
|
|
|
# Trigger a job manually
|
|
@self.routes.post("/research/automation/jobs/{job_id}/run")
|
|
async def trigger_job(request):
|
|
job_id = request.match_info["job_id"]
|
|
loop = asyncio.get_running_loop()
|
|
result = await loop.run_in_executor(None, lambda: scheduler.trigger_now(job_id))
|
|
if result["status"] == "error" and "not found" in result.get("message", ""):
|
|
return web.json_response(result, status=404)
|
|
return web.json_response(result)
|
|
|
|
# Enable/disable a job
|
|
@self.routes.patch("/research/automation/jobs/{job_id}")
|
|
async def update_job(request):
|
|
job_id = request.match_info["job_id"]
|
|
loop = asyncio.get_running_loop()
|
|
job = await loop.run_in_executor(None, lambda: scheduler.get_job(job_id))
|
|
if not job:
|
|
return web.json_response({"error": "Job not found"}, status=404)
|
|
|
|
data = await request.json()
|
|
|
|
if "enabled" in data:
|
|
job.schedule.enabled = data["enabled"]
|
|
if "interval_hours" in data:
|
|
job.schedule.interval_hours = float(data["interval_hours"])
|
|
if "cron_hour" in data:
|
|
job.schedule.cron_hour = data["cron_hour"]
|
|
if "cron_minute" in data:
|
|
job.schedule.cron_minute = data["cron_minute"]
|
|
|
|
return web.json_response({"status": "ok", "job_id": job_id})
|
|
|
|
# Start/stop scheduler
|
|
@self.routes.post("/research/automation/scheduler/start")
|
|
async def start_scheduler(request):
|
|
loop = asyncio.get_running_loop()
|
|
await loop.run_in_executor(None, scheduler.start)
|
|
return web.json_response({"status": "started"})
|
|
|
|
@self.routes.post("/research/automation/scheduler/stop")
|
|
async def stop_scheduler(request):
|
|
loop = asyncio.get_running_loop()
|
|
await loop.run_in_executor(None, scheduler.stop)
|
|
return web.json_response({"status": "stopped"})
|
|
|
|
@self.routes.get("/research/automation/scheduler/status")
|
|
async def scheduler_status(request):
|
|
loop = asyncio.get_running_loop()
|
|
jobs = await loop.run_in_executor(None, scheduler.list_jobs)
|
|
return web.json_response({
|
|
"running": True,
|
|
"jobs_count": len(jobs),
|
|
"jobs": jobs,
|
|
})
|