Refactor internal http#119
Open
scotttrinh wants to merge 10 commits into
Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR refactors the internal HTTP layer to use transports + per-request token resolution (via async token providers), centralizes time/duration utilities, and updates the Sandbox/Blob public APIs + tests/examples to match the new auth and request flow (including OIDC support).
Changes:
- Replaces the shared
RequestClientwith transport-centric request flows (service-specific request clients +BaseTransportenhancements, retry policy split-out). - Introduces
TokenProviderand updates Sandbox/Blob to resolve tokens per request (and project id lazily for Sandbox create/list). - Centralizes time helpers into
vercel._internal.timeand updates call sites/tests accordingly.
Reviewed changes
Copilot reviewed 53 out of 54 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_time.py | Updates imports to the new centralized internal time module. |
| tests/unit/test_sandbox_token_provider.py | Adds comprehensive tests for Sandbox token provider behavior and per-call overrides. |
| tests/unit/test_sandbox_errors.py | Adjusts sandbox error tests to new transport + timeout typing and token provider usage. |
| tests/unit/test_sandbox_create_validation.py | Updates sandbox create validation tests for project id resolution and removed credentials mocking. |
| tests/unit/test_request_client.py | Removes tests for the deleted shared RequestClient. |
| tests/unit/test_blob_request_client_resolve_token.py | Adds unit tests for Blob request client token resolution and auth header injection. |
| tests/unit/test_blob_client_lifecycle.py | Updates Blob client lifecycle tests for new token plumbing (client vs per-call vs env). |
| tests/test_examples.py | Expands example credential gating to accept OIDC token. |
| tests/test_blob_ops.py | Updates blob ops tests to assert token is passed to operation calls (not via client construction). |
| tests/live/test_sandbox_live.py | Updates live sandbox tests for revised Sandbox auth inputs (no team_id parameter). |
| tests/live/test_sandbox_credentials.py | Adds tests for new sandbox credential gating logic (OIDC vs VERCEL_TOKEN). |
| tests/live/test_projects_live.py | Updates live projects test docs to accept OIDC token. |
| tests/live/test_blob_live.py | Updates live blob tests to pass token per operation rather than via client construction. |
| tests/live/conftest.py | Updates live-test credential detection and fixtures for OIDC support and optional team/project fixtures. |
| tests/integration/test_sandbox_sync_async.py | Updates integration tests for sandbox API signature changes and removed teamId query param behavior. |
| tests/integration/test_sandbox_streaming_errors.py | Updates streaming error tests to pass token per-call and removes team_id construction args. |
| tests/integration/test_http_url_construction.py | Updates to new TransportOptions factories; adds redirect and bearer injection coverage. |
| tests/integration/test_http_transport_timeout.py | Adds integration coverage for per-request timeout overriding client defaults. |
| tests/integration/test_http_transport_raw_body.py | Updates raw-body transport tests to new TransportOptions API. |
| tests/integration/test_blob_sync_async.py | Updates blob integration tests for new token routing (client token / per-call token / env token). |
| src/vercel/sandbox/snapshot.py | Refactors public Snapshot APIs to accept token providers and lazily resolve project id when needed. |
| src/vercel/sandbox/sandbox.py | Refactors public Sandbox APIs to accept token providers, remove team_id, and lazily resolve project id for create/list. |
| src/vercel/sandbox/README.md | Documents new sandbox credential resolution behavior and token/provider usage. |
| src/vercel/sandbox/command.py | Formatting-only adjustments to call sites for readability after core signature changes. |
| src/vercel/sandbox/init.py | Exposes TokenProvider in the public sandbox module exports. |
| src/vercel/projects/README.md | Adds guidance for authenticating grouped clients with OIDC-derived credentials. |
| src/vercel/deployments/README.md | Adds guidance for authenticating grouped clients with OIDC-derived credentials. |
| src/vercel/blob/README.md | Documents blob credential resolution precedence and multipart token behavior. |
| src/vercel/blob/ops.py | Updates module-level blob helpers to pass token per operation and normalize timeout types to timedelta. |
| src/vercel/blob/multipart/uploader.py | Updates auto multipart upload helpers to pass token per request rather than via client construction. |
| src/vercel/blob/multipart/api.py | Refactors multipart uploader creation to resolve token via provider and pass token per request. |
| src/vercel/blob/client.py | Updates BlobClient/AsyncBlobClient to accept keyword-only client token and allow per-operation token overrides. |
| src/vercel/_internal/time.py | Introduces shared duration helpers/constants (SECOND, MILLISECOND, coercion, conversions). |
| src/vercel/_internal/sandbox/snapshot.py | Switches sandbox snapshot internals to use centralized internal time utilities. |
| src/vercel/_internal/sandbox/pty_session.py | Switches PTY duration logic to centralized internal time utilities. |
| src/vercel/_internal/sandbox/pty_binary.py | Switches timeout conversion to centralized internal time utilities. |
| src/vercel/_internal/sandbox/models.py | Switches model duration parsing/conversion to centralized internal time utilities. |
| src/vercel/_internal/sandbox/core.py | Major refactor: replaces RequestClient usage with BaseTransport + token provider request client, adds project id provider, removes teamId base param. |
| src/vercel/_internal/http/transport.py | Adds per-request token injection, TransportOptions, per-request timeout handling, redirect override support, and structured error extraction. |
| src/vercel/_internal/http/retry.py | Introduces standalone RetryPolicy (used by new request flows). |
| src/vercel/_internal/http/request_client.py | Removes the shared request client implementation. |
| src/vercel/_internal/http/httpx.py | Adds httpx client factories that accept TransportOptions. |
| src/vercel/_internal/http/config.py | Changes default timeout type to timedelta. |
| src/vercel/_internal/http/clients.py | Removes old http client + RequestClient factory module. |
| src/vercel/_internal/http/init.py | Re-exports updated http primitives (transport/options/retry) and removes RequestClient exports. |
| src/vercel/_internal/blob/multipart.py | Refactors multipart client wrappers to pass tokens per request and add token resolution passthrough. |
| src/vercel/_internal/blob/core.py | Major refactor: replaces RequestClient dependency with transport-based client, per-request auth, retry loop, and timedelta timeouts. |
| src/vercel/_internal/auth.py | Introduces shared TokenProvider protocol and static_token_provider. |
| README.md | Updates top-level credential documentation for token + project/team + OIDC distinctions. |
| examples/projects_sync.py | Updates example to accept OIDC token and pass explicit token to project operations. |
| examples/projects_comparison.py | Updates comparison example to accept OIDC token and pass explicit token through all operations. |
| examples/projects_async.py | Updates async projects example to accept OIDC token and pass explicit token through all operations. |
| examples/blob_storage.py | Updates blob example to use per-operation token overrides and updated client construction. |
| examples/blob_storage_multipart.py | Updates multipart example to pass token at uploader creation and use new client constructors. |
Comments suppressed due to low confidence (1)
src/vercel/_internal/http/transport.py:71
- The module-level helper
_build_request(...)appears unused (the transports useBaseTransport._build_requestinstead). Keeping both with the same name increases confusion and maintenance cost; consider removing the unused function or refactoring to a single implementation used by both sync/async transports.
def _build_request(
*,
body: RequestBody,
headers: HeaderTypes | None,
) -> dict[str, Any]:
kwargs: dict[str, Any] = {}
request_headers = httpx.Headers(headers)
if isinstance(body, JSONBody):
kwargs["json"] = body.data
elif isinstance(body, BytesBody):
kwargs["content"] = body.data
request_headers.setdefault("content-type", body.content_type)
elif isinstance(body, RawBody):
kwargs["content"] = body.data
if request_headers:
kwargs["headers"] = request_headers
return kwargs
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Remove "RequestClient" abstraction, it wasn't doing much and made it a little more confusing to implement the downstream "RequestClient" that each service needs to implement. - Transport now knows what a "token" is, which was the only useful part of the old `RequestClient` aside from retries. - General cleanup of the code Note: This is backwards-incompatible so all of the downstream consumers need to be updated as well.
- Credential Factory -> Token Provider - Blob get's it's explicit token override back - Remove sandbox handles holding onto old credentials - Fix a few small bugs we found
Introduce TokenProvider helpers for sandbox and multipart flows so clients can resolve fresh auth per request without storing credentials on public handles. Collapse the sandbox public API to token= for either static strings or providers, and cover follow-up sandbox calls with request-level auth tests.
Preserve httpx client timeouts when no per-call timeout is set. Resolve implicit sandbox project ids using explicit public tokens.
698464b to
f4cf465
Compare
Resolve token, team, and project scope as one credential bundle so each sandbox request uses consistent authorization and query scope. Add shared response-reading and origin-neutral transport behavior while preserving existing Blob client initialization compatibility.
- Replace private httpx type imports with local aliases - Correct structured error return typing - Improve deprecated source mapping guidance - Remove the unused request builder - Cover the source warning fallback
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This refactors the shared HTTP layer into a thinner transport and updates Blob and Sandbox to build their service-specific request behavior on top of it. Credentials are resolved per request instead of being captured by long-lived handles, which keeps token providers and overrides fresh and ensures Sandbox token, team, and project scope stay together across follow-up calls.
It also aligns sync and async behavior around timeouts, retries, response reading, streaming, URL construction, and client lifecycle. Blob now supports consistent per-operation token overrides and transport reuse, while Sandbox uses the same token/provider model without retaining stale credentials on public objects.