Skip to content

Fail loudly when a URL blob input cannot be downloaded - #23

Open
deepgori wants to merge 1 commit into
deepinfra:mainfrom
deepgori:fix/url-download-errors
Open

deepgori wants to merge 1 commit into
deepinfra:mainfrom
deepgori:fix/url-download-errors

Conversation

@deepgori

Copy link
Copy Markdown

Fixes #22.

Problem

ReadStreamUtils.url_to_stream returned the response body without checking the status:

response = httpx.get(url, follow_redirects=True)
return BytesIO(response.content)

A blob field given as a URL is fetched through this path by FormDataUtils.get_form_data, so when the URL 404s the error page's bytes are uploaded as the file:

AutomaticSpeechRecognition(...).generate({"audio": "https://…/missing.mp3", ...})
# uploads b'<html><body><h1>404 Not Found</h1></body></html>' as the audio

The user then gets a model-side error with nothing pointing at the dead URL. It is the only place in the SDK where a failed HTTP response is neither raised nor surfaced: the client maps every error status onto APIStatusError, and a wrong local path already raises FileNotFoundError.

Changes

  • url_to_stream raises APIStatusError (with the status code and the response) when the download answers with an error status, and APIConnectionError / APITimeoutError on transport failures, matching _map_transport_error in the client.
  • The download gets an explicit 30s timeout; it previously used httpx's 5s default.
  • tests/test_read_stream.py covers the success path, 404/401/500, connect errors, timeouts, propagation through FormDataUtils.get_form_data, and that bytes, data: URIs and missing local files are unaffected.

Without the change, 6 of the 9 new tests fail.

Verification

Python 3.12, from a clean install of .[dev]:

$ pytest tests
118 passed
$ ruff check .
All checks passed!
$ mypy
Success: no issues found in 39 source files

Not included

The issue mentions three smaller points in the same file (a local path beginning with http being treated as a URL, a data: URI without a comma raising IndexError, and BaseModel._warn_about_missing_api_key sending an empty bearer token instead of raising AuthenticationError). They are left out to keep this focused, and I'm happy to send them separately if you want them.

url_to_stream returned the response body without checking the status, so a
404 page was uploaded to the API as if it were the file. Error statuses now
raise APIStatusError, and transport failures raise APIConnectionError /
APITimeoutError, matching how the rest of the SDK reports failures. The
download also gets an explicit timeout.

Fixes deepinfra#22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A failed URL download is uploaded to the API as if it were the file

1 participant