Nobody has started this yet — be first.
Business impact
Submitting N jobs today means N separate POST /jobs round-trips from the client. For a caller that legitimately wants to kick off a batch -- e.g. transcoding every file in a folder someone just uploaded -- that's N times the network overhead and N times the places a partial failure can happen (job 3 of 10 fails to submit; now the caller has to reconcile which of the other 9 actually went through).
Problem
POST /jobs/batch matches the path pattern of the existing GET /jobs/{job_id} route (treating batch as a job id), but no route is registered for that path on POST.
Current behavior
POST /jobs/batch returns 405 Method Not Allowed -- it matches the path pattern of the existing GET /jobs/{job_id} route (treating batch as a job id) but no route is registered for that path on POST.
Expected behavior
POST /jobs/batch accepts {"jobs": [<JobCreateRequest>, ...]} and returns 202 with {"job_ids": [...]}, one id per spec submitted, in the same order. An empty jobs list is rejected (400/422), not silently accepted as a no-op.
Steps to reproduce
pytest practice_tickets/tests/test_ticket_10_batch_submit_endpoint.py -vPOST /jobs/batch with 3 job specs returns 405 -- this route doesn't exist yet.Why this matters
This is almost entirely a thin wrapper around the existing single-job path -- create_job()'s logic (validate, create the Redis document, register a handle, spawn the worker task) doesn't need to change at all, it just needs to run once per spec in the batch instead of once per request. The interesting design question is failure handling: does one invalid spec in a batch of 10 reject the whole batch, or only that one entry? (Acceptance criteria here only require rejecting a fully empty batch.)
Suggested approach
app/schemas.py needs a request/response pair for the batch shape (a list of JobCreateRequest in, a list of job_ids out). app/routers/jobs.py's existing create_job() body is the reference for what "submit one job" actually does -- a batch route calling that same sequence of steps once per spec keeps the two paths from drifting apart.
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_10_batch_submit_endpoint.py -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
Sign in to create it automatically, or do it yourself:
$git checkout -b feat/batch-submit-endpointFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/batch-submit-endpointSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign inhttp://localhost:8000localhost:6379curl localhost:8000/healthz{"status": "ok", "redis": true}Work the tickets in practice_tickets/tickets/ (ordered easy → hard); each names one dedicated pytest file in practice_tickets/tests/:
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pytest practice_tickets/tests/test_ticket_01_completed_jobs_counted_as_failed.py -v # a single ticket
./practice_tickets/run_tickets.sh # all 15, clean pass/fail summary
Each ticket test runs in its own pytest process with a 60s timeout, so one hung/crashed ticket can't take down the whole run or hide another ticket's result. Run pytest tests/ (the project's own suite, against fakeredis, hermetic and fast) after each fix to check for regressions -- the README documents exactly which fixes are expected to change that suite's results.
Level 2
Implement a feature
Extend the system within its own patterns.