feat: add ids filter to GET /api/jobs for batch polling

Add an optional comma-separated `ids` query parameter to GET /api/jobs so a
caller can poll a known set of jobs in a single request instead of one call
per job. The filter narrows the result to the requested job ids and composes
with the existing status / workflow_id filters; an absent or empty `ids` means
no filter.

The handler caps the request at 100 ids (checked before validation) and
validates each id with the existing validate_job_id helper, returning HTTP 400
on overflow or a malformed id. get_all_jobs gains an optional ids argument that
narrows the normalized job list by id.

Adds unit coverage for the filter logic and the endpoint's validation contract.
This commit is contained in:
Matt Miller
2026-06-30 14:58:15 -07:00
parent 50e5270b86
commit 44fb02e510
4 changed files with 273 additions and 0 deletions

View File

@@ -31,6 +31,11 @@ class JobStatus:
ALL = [PENDING, IN_PROGRESS, COMPLETED, FAILED, CANCELLED]
# Maximum number of ids accepted by the `ids` filter on the jobs listing.
# Bounds the work a single batch-poll request can ask for.
MAX_JOB_IDS_FILTER = 100
def validate_job_id(value) -> str:
"""Validate a client-supplied job (prompt) id.
@@ -362,6 +367,7 @@ def get_all_jobs(
history: dict,
status_filter: Optional[list[str]] = None,
workflow_id: Optional[str] = None,
ids: Optional[list[str]] = None,
sort_by: str = "created_at",
sort_order: str = "desc",
limit: Optional[int] = None,
@@ -376,6 +382,7 @@ def get_all_jobs(
history: Dict of history items keyed by prompt_id
status_filter: List of statuses to include (from JobStatus.ALL)
workflow_id: Filter by workflow ID
ids: Restrict the result to these job ids (None/empty = no filter)
sort_by: Field to sort by ('created_at', 'execution_duration')
sort_order: 'asc' or 'desc'
limit: Maximum number of items to return
@@ -408,6 +415,10 @@ def get_all_jobs(
if workflow_id:
jobs = [j for j in jobs if j.get('workflow_id') == workflow_id]
if ids:
id_set = set(ids)
jobs = [j for j in jobs if j['id'] in id_set]
jobs = apply_sorting(jobs, sort_by, sort_order)
total_count = len(jobs)