Skip to content

Refactor internal http#119

Open
scotttrinh wants to merge 10 commits into
mainfrom
refactor-internal-http
Open

Refactor internal http#119
scotttrinh wants to merge 10 commits into
mainfrom
refactor-internal-http

Conversation

@scotttrinh

@scotttrinh scotttrinh commented May 15, 2026

Copy link
Copy Markdown
Collaborator

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.

@vercel

vercel Bot commented May 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vercel-py Ready Ready Preview Jun 16, 2026 5:31pm

Request Review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 RequestClient with transport-centric request flows (service-specific request clients + BaseTransport enhancements, retry policy split-out).
  • Introduces TokenProvider and updates Sandbox/Blob to resolve tokens per request (and project id lazily for Sandbox create/list).
  • Centralizes time helpers into vercel._internal.time and 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 use BaseTransport._build_request instead). 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.

Comment thread src/vercel/_internal/http/transport.py Outdated
Comment thread src/vercel/_internal/http/transport.py Outdated
Comment thread src/vercel/sandbox/sandbox.py Outdated
- 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.
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
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.

2 participants