Cut a long file into chunks a hosted request can outlive

An hour and a half of speech came back as "OpenRouter: HTTP 502: The
operation was aborted due to timeout", every time. The upload limit was
the only thing deciding where the file was cut, and mp3 at 48 kbps
reaches 24 MB after an hour, so a 90 minute file became two chunks and
the first one was 63 minutes of audio in a single request. Nothing
between here and the model stays on the line that long.

A chunk is capped at fifteen minutes now, whatever it weighs, and the
call is finally handed a timeout of its own: it was going out on the 300
second default sized for a dictation, which the same chunk would have
hit first anyway.

The other half is not throwing the run away when one request fails.
ApiError carries whether a second try can fix it, which is true of the
statuses a gateway raises itself and of a dropped connection, and false
of a rejected key. A chunk is asked for three times, waiting five then
ten seconds, with the Stop button still able to get through. If it does
fail in the end, what was already heard goes to the output box rather
than the bin, with the status line saying where it stops.
This commit is contained in:
2026-08-20 12:27:42 +03:00
parent 0a70484d84
commit f55e201785
5 changed files with 217 additions and 47 deletions
+27
View File
@@ -79,6 +79,33 @@ class Explain(DikteTest):
def test_the_status_is_carried_through(self):
self.assertEqual(self.error(429).status, 429)
def test_so_is_whether_it_is_worth_asking_again(self):
self.assertTrue(self.error(502).retryable)
self.assertFalse(self.error(401).retryable)
class Retryable(unittest.TestCase):
"""Which failures a second try can fix, and which will fail the same way."""
def test_a_gateway_that_gave_up_waiting(self):
for status in (408, 429, 500, 502, 503, 504):
with self.subTest(status=status):
self.assertTrue(api.ApiError("x", status).retryable)
def test_a_request_that_was_wrong(self):
for status in (400, 401, 402, 403, 404, 413, 422):
with self.subTest(status=status):
self.assertFalse(api.ApiError("x", status).retryable)
def test_an_error_of_our_own_is_not_the_network(self):
self.assertFalse(api.ApiError("Transcript came back empty.").retryable)
def test_a_connection_that_dropped_is_worth_a_second_try(self):
with fake_urlopen(url_error("connection reset")):
with self.assertRaises(api.ApiError) as caught:
api._request("https://example.test", b"{}", {})
self.assertTrue(caught.exception.retryable)
class ExtractError(unittest.TestCase):
def test_the_usual_shape(self):