Part of #1285.
Background
We want to minimize pyvespa's runtime dependency surface (see #1285). The httpx → httpr migration is mostly done, but application.py still carries httpx and requests for backwards-compat type hints and exception handling.
Scope
Drop import httpx and import requests from vespa/application.py. This is the most impactful PR in the series — it includes a public API break.
May be split into 3a + 3b during review if it gets heavy:
Part 3a — Remove httpx type-hint shim
application.py:38 — drop import httpx
application.py:2050 — timeout: Union[httpx.Timeout, int, float] → Union[int, float]. Drop the isinstance(timeout, httpx.Timeout) branch + DeprecationWarning at lines 2141–2147. The deprecation warning has been live a while — check git blame application.py | grep httpx.Timeout to confirm the window
application.py:2052 — client: Optional[Union[httpx.AsyncClient, httpr.AsyncClient]] → Optional[httpr.AsyncClient]
application.py:325-326, 371-373, 387 — same on the sync get_async_session factory
- Update docstrings (lines 348–387, 885, 1038, 1051, 1094, 1106) that say
httpx.AsyncClient
tests/unit/test_application.py:20 — drop import httpx; remove any test constructing httpx.Timeout / httpx.AsyncClient
Part 3b — Remove requests (exceptions + type hints)
application.py:14-16 — drop from requests import Session, Response, ConnectionError, HTTPError, JSONDecodeError
_is_connection_error (line 71) — requests.ConnectionError is mostly redundant with the builtin ConnectionError plus httpr.RequestError / httpr.ConnectError that the function already checks
raise_for_status (line 190) — currently raises requests.HTTPError. Define vespa.exceptions.HTTPError and raise that instead
JSONDecodeError — switch to json.JSONDecodeError (stdlib)
Session / Response type hints at lines 14-15 are dead weight on a path that returns httpr.Response. Drop or replace with a Protocol
- Docstrings at lines 426, 1425 mention
requests.Session → update to httpr.Client
- Update the comment at line 207 (
# Check if response has raise_for_status method (requests/httpx))
Public API impact
Breaking changes for downstream:
- Passing
httpx.Timeout to VespaAsync raises TypeError. Mitigation: the DeprecationWarning has been live for a while; remove cleanly and call out in changelog.
- Passing
httpx.AsyncClient to VespaAsync raises TypeError. Mitigation: require httpr.AsyncClient, call out in changelog.
- Catching
requests.HTTPError from raise_for_status no longer works. Mitigation: export vespa.exceptions.HTTPError AND keep vespa.exceptions.HTTPError = requests.HTTPError style alias for one release if/while requests is still in dev extras — OR just bump the minor version and call it out.
Recommend: re-export HTTPError from vespa.exceptions with a one-release deprecation alias.
Tasks
Out of scope
Risk
Medium. The public API break is real but contained. Most users probably already get an httpr.AsyncClient back from app.get_async_session() and don't construct httpx types themselves, but it's worth a release-notes call-out.
Part of #1285.
Background
We want to minimize pyvespa's runtime dependency surface (see #1285). The
httpx→httprmigration is mostly done, butapplication.pystill carrieshttpxandrequestsfor backwards-compat type hints and exception handling.Scope
Drop
import httpxandimport requestsfromvespa/application.py. This is the most impactful PR in the series — it includes a public API break.May be split into 3a + 3b during review if it gets heavy:
Part 3a — Remove
httpxtype-hint shimapplication.py:38— dropimport httpxapplication.py:2050—timeout: Union[httpx.Timeout, int, float]→Union[int, float]. Drop theisinstance(timeout, httpx.Timeout)branch +DeprecationWarningat lines 2141–2147. The deprecation warning has been live a while — checkgit blame application.py | grep httpx.Timeoutto confirm the windowapplication.py:2052—client: Optional[Union[httpx.AsyncClient, httpr.AsyncClient]]→Optional[httpr.AsyncClient]application.py:325-326, 371-373, 387— same on the syncget_async_sessionfactoryhttpx.AsyncClienttests/unit/test_application.py:20— dropimport httpx; remove any test constructinghttpx.Timeout/httpx.AsyncClientPart 3b — Remove
requests(exceptions + type hints)application.py:14-16— dropfrom requests import Session,Response,ConnectionError,HTTPError,JSONDecodeError_is_connection_error(line 71) —requests.ConnectionErroris mostly redundant with the builtinConnectionErrorplushttpr.RequestError/httpr.ConnectErrorthat the function already checksraise_for_status(line 190) — currently raisesrequests.HTTPError. Definevespa.exceptions.HTTPErrorand raise that insteadJSONDecodeError— switch tojson.JSONDecodeError(stdlib)Session/Responsetype hints at lines 14-15 are dead weight on a path that returnshttpr.Response. Drop or replace with aProtocolrequests.Session→ update tohttpr.Client# Check if response has raise_for_status method (requests/httpx))Public API impact
Breaking changes for downstream:
httpx.TimeouttoVespaAsyncraisesTypeError. Mitigation: theDeprecationWarninghas been live for a while; remove cleanly and call out in changelog.httpx.AsyncClienttoVespaAsyncraisesTypeError. Mitigation: requirehttpr.AsyncClient, call out in changelog.requests.HTTPErrorfromraise_for_statusno longer works. Mitigation: exportvespa.exceptions.HTTPErrorAND keepvespa.exceptions.HTTPError = requests.HTTPErrorstyle alias for one release if/whilerequestsis still in dev extras — OR just bump the minor version and call it out.Recommend: re-export
HTTPErrorfromvespa.exceptionswith a one-release deprecation alias.Tasks
import httpxand allhttpx.*type hintstests/unit/test_application.py(drophttpximport + adjust tests)vespa.exceptions.HTTPErrorraise_for_status,_is_connection_errorfrom requests ...importsrequests.Response)grep -rn 'import httpx\|from httpx\|import requests\|from requests' vespa/returns no hitsOut of scope
pyproject.toml— that's PR 4 (Deps cleanup PR 4: Remove requests/requests_toolbelt/httpx from pyproject.toml #1289)Risk
Medium. The public API break is real but contained. Most users probably already get an
httpr.AsyncClientback fromapp.get_async_session()and don't constructhttpxtypes themselves, but it's worth a release-notes call-out.