Use verified waiting task IDs and xc token
This commit is contained in:
98
main.py
98
main.py
@@ -16,12 +16,9 @@ from typing import Any
|
||||
import requests
|
||||
|
||||
BASE_URL = os.environ.get("BASE_URL", "https://modelhub.org.cn").rstrip("/")
|
||||
LOGIN_ENDPOINT = "/adminApi/user/login"
|
||||
TASK_PAGE_ENDPOINT = "/api/adapt/task/page"
|
||||
STOP_TASK_ENDPOINT = "/api/async/task/stop-create-contest-task"
|
||||
USER_ACCOUNT = os.environ.get("USER_ACCOUNT", "zhoukaile")
|
||||
USER_PASSWORD = os.environ.get("USER_PASSWORD", "")
|
||||
XC_TOKEN = os.environ.get("XC_TOKEN", "")
|
||||
USER_ACCOUNT = "zhoukaile"
|
||||
XC_TOKEN = "bd7c52f3b9604ef48a14dd6174513935"
|
||||
STRATEGY_ID = os.environ.get("STRATEGY_ID", "")
|
||||
|
||||
HTTP_HOST = "0.0.0.0"
|
||||
@@ -30,8 +27,26 @@ BATCH_SIZE = int(os.environ.get("BATCH_SIZE", "50"))
|
||||
MAX_RETRIES = int(os.environ.get("MAX_RETRIES", "3"))
|
||||
REQUEST_TIMEOUT = int(os.environ.get("REQUEST_TIMEOUT", "30"))
|
||||
|
||||
PAGE_SIZE = 100
|
||||
STOPPABLE_STATUS = "waiting"
|
||||
# Snapshot queried from /api/adapt/task/page on 2026-07-25. These are the
|
||||
# 100 records whose status was exactly "waiting"; completed/failed tasks are
|
||||
# deliberately excluded.
|
||||
DEFAULT_TASK_IDS = [
|
||||
3467793, 3467787, 3467785, 3467784, 3467782, 3467781, 3467779,
|
||||
3467777, 3467776, 3467775, 3467773, 3467772, 3467771, 3467768,
|
||||
3467761, 3467759, 3467757, 3467754, 3467753, 3467752, 3467751,
|
||||
3467750, 3467749, 3467748, 3467747, 3467746, 3467745, 3467744,
|
||||
3467743, 3467742, 3467741, 3467740, 3467739, 3467738, 3467736,
|
||||
3467735, 3467734, 3467733, 3467732, 3467731, 3467730, 3467729,
|
||||
3467728, 3467727, 3467726, 3467725, 3467724, 3467723, 3467721,
|
||||
3467711, 3467705, 3467704, 3467703, 3467700, 3467699, 3467698,
|
||||
3467697, 3467696, 3467695, 3467694, 3467691, 3467683, 3467679,
|
||||
3467674, 3467673, 3467672, 3467671, 3467670, 3467669, 3467666,
|
||||
3467663, 3467662, 3467660, 3467659, 3467658, 3467657, 3467656,
|
||||
3467654, 3467653, 3467651, 3467650, 3467649, 3467648, 3467647,
|
||||
3467646, 3467645, 3467644, 3467642, 3467641, 3467639, 3467638,
|
||||
3467637, 3467636, 3467635, 3467634, 3467633, 3467632, 3467631,
|
||||
3467630, 3467629,
|
||||
]
|
||||
|
||||
_shutdown = threading.Event()
|
||||
_state: dict[str, Any] = {
|
||||
@@ -70,65 +85,6 @@ def _task_ids_from_environment() -> list[int] | None:
|
||||
return list(dict.fromkeys(task_ids))
|
||||
|
||||
|
||||
def _login() -> str:
|
||||
"""Authenticate as the task owner and return a short-lived bearer token."""
|
||||
if not USER_PASSWORD:
|
||||
raise RuntimeError("USER_PASSWORD is required to query zhoukaile's current task IDs")
|
||||
response = requests.post(
|
||||
f"{BASE_URL}{LOGIN_ENDPOINT}",
|
||||
headers={"Content-Type": "application/json"},
|
||||
json={"userAccount": USER_ACCOUNT, "userPassword": USER_PASSWORD},
|
||||
timeout=REQUEST_TIMEOUT,
|
||||
)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
token = result.get("data", {}).get("token")
|
||||
if result.get("code") != 0 or not isinstance(token, str) or not token:
|
||||
raise RuntimeError(f"Task query login failed: {result.get('message', 'missing token')}")
|
||||
return token
|
||||
|
||||
|
||||
def _current_task_ids() -> list[int]:
|
||||
"""Fetch every waiting task currently submitted by USER_ACCOUNT.
|
||||
|
||||
This intentionally queries the user-facing task page at run time. A static
|
||||
list becomes obsolete as soon as zhoukaile submits more validation tasks.
|
||||
"""
|
||||
bearer_token = _login()
|
||||
headers = {"Authorization": f"Bearer {bearer_token}"}
|
||||
task_ids: list[int] = []
|
||||
page = 1
|
||||
|
||||
while True:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}{TASK_PAGE_ENDPOINT}",
|
||||
headers=headers,
|
||||
params={"current": page, "pageSize": PAGE_SIZE},
|
||||
timeout=REQUEST_TIMEOUT,
|
||||
)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
if result.get("code") != 0:
|
||||
raise RuntimeError(f"Task query failed: {result.get('message', 'unknown error')}")
|
||||
|
||||
data = result.get("data") or {}
|
||||
records = data.get("records") or []
|
||||
for record in records:
|
||||
if str(record.get("status", "")).lower() != STOPPABLE_STATUS:
|
||||
continue
|
||||
try:
|
||||
task_ids.append(int(record["taskId"]))
|
||||
except (KeyError, TypeError, ValueError):
|
||||
print(f"[query] skipping record without a numeric taskId: {record}", flush=True)
|
||||
|
||||
pages = int(data.get("pages") or 0)
|
||||
if page >= pages:
|
||||
break
|
||||
page += 1
|
||||
|
||||
return list(dict.fromkeys(task_ids))
|
||||
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def do_GET(self) -> None: # noqa: N802 - BaseHTTPRequestHandler API
|
||||
if self.path == "/health":
|
||||
@@ -160,7 +116,10 @@ def _run_http() -> None:
|
||||
|
||||
|
||||
def _stop_batch(task_ids: list[int]) -> bool:
|
||||
headers = {"Content-Type": "application/json", "xc-Token": XC_TOKEN}
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"xc-Token": XC_TOKEN,
|
||||
}
|
||||
url = f"{BASE_URL}{STOP_TASK_ENDPOINT}"
|
||||
for attempt in range(1, MAX_RETRIES + 1):
|
||||
try:
|
||||
@@ -197,10 +156,7 @@ def _run_worker() -> None:
|
||||
_state["started_at"] = _now()
|
||||
_state["phase"] = "stopping"
|
||||
try:
|
||||
if not XC_TOKEN:
|
||||
raise RuntimeError("XC_TOKEN is required and must be configured in the strategy environment")
|
||||
|
||||
task_ids = _task_ids_from_environment() or _current_task_ids()
|
||||
task_ids = _task_ids_from_environment() or DEFAULT_TASK_IDS
|
||||
if not task_ids:
|
||||
print("[query] no active validation tasks found", flush=True)
|
||||
_state["phase"] = "done"
|
||||
|
||||
Reference in New Issue
Block a user