Ok, ty, at least I wasn't missing anything obvious to handle this.
I was playing with this a bit further and was finding that batching has a number of trade-offs that ended up creating more challenges.
For additional context: Essentially, I'm pulling data from one data source, enriching these records by calculating some values, then submitting the resulting relationships in this data to a different place. There's a lot of repeat data in subsequent runs as this workflow is more about maintaining consistency and making sure relationships are present in the destination system.
Limitations
1. I'm using caching to reduce duplicate requests which gets lost with batching
2. Failing a batch results in cascading failures and retries (perhaps not the correct term).
So sticking to one task for all requests or a single task per request is kind of where I've landed.
For caching, I was finding that using Prefect's caching drastically reduced the number of requests I had to make in subsequent runs. There's different caching mechanisms but I was finding the input values to a task to worked well enough. Moving to batching lost the benefit of using Prefect's caching (at least easily).
Retry logic on batches just resulted in far more requested
One failed request resulted in 1000 request attempts, so creates an opportunity for a cascading failure.
Of course, I could handle caching or retries outside of Prefect but it would be interesting to see what prefect can do. At this point this is code golf.
For now, I'm sticking to individual tasks for the 40k requests. I am initiating those tasks via an iterator that's yeilding the values to submit. Caching and retry logic is working well enough. To handle the UI issue, It would be interesting if there was a way to show summary info of the iterator that doesn't involve expanding the list of 40k tasks. (Succeeded, Failed, Running)
If I was to go the route of having one task represent all 40k requests.. that would involve using caching and retry logic in a different way outside of Prefect, as a down side. It would be interesting to make a custom retry that's more recursive in a sense. The input to the task is a list, the failure could return the list of items that haven't succeeded yet and start the retry logic with the shorter list. Additionally, I don't know if there is a concept of progress for a single task
I'll play with this a bit more. Unfortunately I think this pattern with be somewhat recurring for me.