Conversation
Introduce a Transport protocol and two concrete implementations (RequestsTransport and HTTPXTransport) to allow users to choose between requests and httpx as the HTTP backend. All three client classes (VWS, CloudRecoService, VuMarkService) now accept an optional transport parameter, defaulting to RequestsTransport for backwards compatibility. The transport abstraction handles the full HTTP lifecycle and returns the library's Response dataclass. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Users should import transports from vws.transports directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make VuMarkService.__init__ keyword-only to fix too-many-positional-arguments. Suppress unnecessary-ellipsis on Transport protocol method body. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
||
| def __init__( | ||
| self, | ||
| *, |
There was a problem hiding this comment.
Breaking API change: VuMarkService now requires keyword-only arguments
High Severity
The bare * added to VuMarkService.__init__ forces server_access_key and server_secret_key to be keyword-only arguments. Previously these could be passed positionally (e.g., VuMarkService("key", "secret")). The other two clients (VWS and CloudRecoService) already had *, but VuMarkService did not, so this is a new breaking change to the public API — contradicting the PR's "full backwards compatibility" claim.
There was a problem hiding this comment.
This is an intentional change. VWS and CloudRecoService already used * for keyword-only arguments, so VuMarkService was the odd one out. Making it consistent also avoids a pylint too-many-positional-arguments error now that transport is a new parameter.
There was a problem hiding this comment.
Good catch. Fixed in e2bf8ce — the float path now explicitly sets connect=timeout, read=timeout, write=None, pool=None to match the tuple path and requests semantics.
Remove `from __future__ import annotations` from transports.py. Add tests for HTTPXTransport covering both float and tuple timeout branches to achieve 100% coverage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| text=httpx_response.text, | ||
| url=str(object=httpx_response.url), | ||
| status_code=httpx_response.status_code, | ||
| headers=dict(httpx_response.headers), |
There was a problem hiding this comment.
HTTPXTransport produces lowercase header keys unlike RequestsTransport
Low Severity
dict(httpx_response.headers) normalizes all header keys to lowercase (e.g., "content-type"), while dict(requests_response.headers) preserves the server's original casing (e.g., "Content-Type"). Since Response.headers is a plain dict[str, str] exposed as public API, any consumer doing case-sensitive key lookups like response.headers["Content-Type"] would get a KeyError with HTTPXTransport but work fine with RequestsTransport.
There was a problem hiding this comment.
HTTP headers are case-insensitive per RFC 7230. Both requests and httpx use case-insensitive header mappings internally — the difference only surfaces after calling dict(). In practice, this library's consumers access headers through the Response object, and any code doing case-sensitive key lookups on HTTP headers has a latent bug regardless of transport. Not changing this.
- Set tell_position to len(content) instead of 0 - Add follow_redirects=True to httpx.request() - Handle request_body None when content is empty Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use @staticmethod on test methods that don't reference self. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0e93cf7 to
c307654
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
Both paths now only set connect and read timeouts, matching requests behavior. Previously the float path also set write and pool timeouts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>


Summary
Introduces a
Transportprotocol and two concrete implementations (RequestsTransportandHTTPXTransport) to allow users to choose between requests and httpx as the HTTP backend. All three client classes now accept an optionaltransportparameter, defaulting toRequestsTransport()for full backwards compatibility.Changes
src/vws/transports.pywithTransportprotocol and both transport implementationsVWS,CloudRecoService,VuMarkService) accept optionaltransportparameterTesting
All 184 existing tests pass unchanged. The default transport (requests) maintains identical behavior to the original implementation.
🤖 Generated with Claude Code
Note
Medium Risk
Touches the core HTTP request path across all clients and adds a new required dependency (
httpx), so regressions could affect all API calls despite defaulting to the existingrequestsbehavior.Overview
Adds a pluggable HTTP layer via a new
vws.transportsmodule (Transportprotocol plusRequestsTransportandHTTPXTransport) so callers can choose the underlying HTTP client.Refactors
VWS,CloudRecoService,VuMarkService, and the internaltarget_api_requesthelper to accept/use an optionaltransport(defaulting toRequestsTransport()), and updates packaging/docs/tests accordingly (addshttpxdependency, API reference entry, spelling/vulture ignores, and newHTTPXTransporttests).Written by Cursor Bugbot for commit b977b52. This will update automatically on new commits. Configure here.