Skip to content

Add UNAVAILABLE_WITHOUT_CONTAINER_NAME feature flag - #1335

Merged
r33drichards merged 1 commit into
mainfrom
claude/document-container-name-5veGY
Apr 17, 2026
Merged

Add UNAVAILABLE_WITHOUT_CONTAINER_NAME feature flag#1335
r33drichards merged 1 commit into
mainfrom
claude/document-container-name-5veGY

Conversation

@r33drichards

@r33drichards r33drichards commented Apr 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a new feature flag UNAVAILABLE_WITHOUT_CONTAINER_NAME that allows the server to reject all requests with a configurable HTTP status code when CONTAINER_NAME is required but not set, while maintaining backwards compatibility with local development mode.

Key Changes

  • New helper functions: Added _parse_bool_env() and _unavailable_status_code() to parse environment variables and determine when the server should be unavailable
  • New ASGI middleware: Implemented UnavailableWithoutContainerMiddleware that intercepts all HTTP and WebSocket requests and rejects them when the flag is enabled and CONTAINER_NAME is unset
  • Environment variables:
    • UNAVAILABLE_WITHOUT_CONTAINER_NAME: Feature flag (accepts various truthy values: "1", "true", "yes", "y", "on")
    • UNAVAILABLE_WITHOUT_CONTAINER_NAME_RESPONSE_STATUS_CODE: Configurable HTTP status code for rejections (defaults to 503)
  • Comprehensive test suite: Added 189 lines of integration and unit tests covering:
    • Backwards compatibility (local dev mode still works when flag is unset)
    • HTTP endpoint behavior (/cmd, /status)
    • PTY endpoints via auth gate
    • Playwright exec endpoint
    • WebSocket endpoint with proper error messaging
    • Custom status code configuration
    • Various truthy/falsy value handling

Implementation Details

  • The middleware reads environment variables on each request, enabling dynamic configuration and test isolation
  • HTTP rejections return JSON error responses with appropriate status codes
  • WebSocket rejections accept the connection first, send a structured JSON error message (preserving existing client error handling), then close with code 1008 (Policy Violation)
  • When CONTAINER_NAME is set, the unavailable flag is ignored, allowing normal auth flow to proceed
  • Maintains full backwards compatibility: when neither env var is set, the server operates in local development mode as before

https://claude.ai/code/session_01VUPZ5JsZUpYKVKxgaSwYXt

Summary by CodeRabbit

  • New Features

    • Added request handling middleware configurable via environment variables to respond with specific HTTP status codes when the application runs without a container name, with support for both standard HTTP and WebSocket connections.
  • Tests

    • Comprehensive integration tests added to validate the new middleware behavior across multiple endpoints and connection types, including custom status code configurations.

Add UNAVAILABLE_WITHOUT_CONTAINER_NAME env var that, when truthy, causes the
server to reject every HTTP and WebSocket request with a configurable status
code (UNAVAILABLE_WITHOUT_CONTAINER_NAME_RESPONSE_STATUS_CODE, default 503)
whenever CONTAINER_NAME is not set -- replacing the silent pass-through to
local development mode.

Implemented as a single ASGI middleware so the gate applies uniformly across
/ws, /cmd, /pty/*, /responses, /playwright_exec, and /status, instead of
duplicating an inline check at each auth site. Backwards-compatible: with
neither env var set, behavior is unchanged.

Integration tests cover the helper, HTTP endpoints, PTY endpoints, the
WebSocket handshake, custom status codes, invalid status codes, multiple
truthy value variants, and CONTAINER_NAME taking precedence over the flag.

https://claude.ai/code/session_01VUPZ5JsZUpYKVKxgaSwYXt
@vercel

vercel Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Apr 17, 2026 10:21pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📦 Publishable packages changed

  • pypi/computer-server

Add release:<service> labels to auto-release on merge (+ optional bump:minor or bump:major, default is patch).
Or add no-release to skip.

@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Added ASGI middleware that gates incoming requests based on environment configuration, returning an unavailable status code when CONTAINER_NAME is unset and UNAVAILABLE_WITHOUT_CONTAINER_NAME is enabled. Includes comprehensive integration tests covering HTTP and WebSocket endpoints.

Changes

Cohort / File(s) Summary
Middleware Implementation
libs/python/computer-server/computer_server/main.py
Added UnavailableWithoutContainerMiddleware ASGI middleware with configuration helpers (DEFAULT_UNAVAILABLE_STATUS_CODE, _parse_bool_env, _unavailable_status_code). Middleware intercepts HTTP and WebSocket requests; returns 503 (or custom status code) when CONTAINER_NAME is unset and UNAVAILABLE_WITHOUT_CONTAINER_NAME is truthy. For WebSocket, accepts connection, sends error JSON, then closes with code 1008.
Integration Tests
libs/python/computer-server/tests/test_auth_availability.py
New test module validating middleware and configuration behavior. Covers _unavailable_status_code() function with various environment configurations, and integration tests across multiple endpoints (/cmd, /pty/{pid}, /playwright_exec, /status, /ws) ensuring middleware correctly gates requests and respects CONTAINER_NAME bypass.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Middleware as UnavailableWithoutContainer<br/>Middleware
    participant App as Application Handler
    
    alt Container Name Missing & Flag Enabled
        Client->>Middleware: HTTP Request
        Middleware->>Middleware: Check CONTAINER_NAME & flag
        Middleware->>Client: 503/Custom Status + JSON Error
        
        Client->>Middleware: WebSocket Upgrade
        Middleware->>Middleware: Check CONTAINER_NAME & flag
        Middleware->>Client: Accept Connection
        Middleware->>Client: Send Error JSON
        Middleware->>Client: Close (1008)
    else Normal Operation
        Client->>Middleware: Request
        Middleware->>App: Pass Through
        App->>Client: Response
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A middleware hops into place,
Checking containers with swift grace,
WebSockets and HTTP it does greet,
Gating requests both incomplete,
Environment vars make the call—ready set!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding the UNAVAILABLE_WITHOUT_CONTAINER_NAME feature flag. It is concise, specific, and clearly conveys the primary purpose of the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/document-container-name-5veGY

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sentry

sentry Bot commented Apr 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 3.24675% with 149 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...on/computer-server/tests/test_auth_availability.py 4.38% 109 Missing ⚠️
...ibs/python/computer-server/computer_server/main.py 0.00% 40 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
libs/python/computer-server/computer_server/main.py (1)

129-139: Middleware also gates /status and any health/readiness endpoints.

The middleware uniformly rejects every HTTP request (including /status) when the flag is enabled. If this server runs behind an orchestrator (K8s liveness/readiness, load balancer health checks, uptime monitors), those probes will start failing with 503 as soon as UNAVAILABLE_WITHOUT_CONTAINER_NAME=1 is set without CONTAINER_NAME, which could trigger pod restarts or remove the instance from rotation — even though "unconfigured" is exactly the state you want the probe to surface differently from "dead".

Consider exempting a small allowlist (e.g. /status, or an explicit /healthz) from the gate so health endpoints can still report configuration state, or document this behavior prominently so operators configure their probes accordingly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/python/computer-server/computer_server/main.py` around lines 129 - 139,
The middleware in __call__ uses _unavailable_status_code() to reject all "http"
and "websocket" requests (via _reject_http/_reject_websocket), which currently
blocks health endpoints like /status; update __call__ to exempt a small
allowlist of health paths (e.g., "/status" or "/healthz") by checking
scope.get("path") before applying _unavailable_status_code() and, if the path is
in the allowlist, call await self.app(scope, receive, send) instead of
rejecting; ensure both http and websocket flows consult the same allowlist and
keep references to _unavailable_status_code, _reject_http and _reject_websocket
to preserve existing behavior for other paths.
libs/python/computer-server/tests/test_auth_availability.py (1)

137-145: test_backwards_compat_local_dev_accepts_auth is brittle — depends on browser_manager behavior.

This test issues {"command": "noop", ...} and only asserts resp.status_code not in (401, 503). If a future refactor causes browser_manager.execute_command to raise and the handler returns 500, the test still passes (vacuously confirming "not gated"); but if the handler ever starts returning 401/503 for unknown commands (e.g., a config-related 503 from the browser subsystem), the test fails for reasons unrelated to the middleware under test.

Consider asserting on a more specific outcome — e.g. resp.status_code in (200, 400, 500) — or (better) point this test at a lightweight endpoint like /commands that has no external dependency, to isolate the assertion to "middleware did not intercept".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/python/computer-server/tests/test_auth_availability.py` around lines 137
- 145, The test test_backwards_compat_local_dev_accepts_auth is brittle because
it hits /playwright_exec which depends on browser_manager.execute_command;
change it to assert a specific allowed set or call a lightweight handler without
external deps. Either replace client.post("/playwright_exec", ...) with a
request to a simple endpoint (e.g. "/commands" or an equivalent no-external-deps
route) to ensure only middleware is exercised, or tighten the assertion to
assert resp.status_code in (200, 400, 500) so future browser_manager failures
(500) don’t cause false negatives.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@libs/python/computer-server/computer_server/main.py`:
- Around line 129-139: The middleware in __call__ uses
_unavailable_status_code() to reject all "http" and "websocket" requests (via
_reject_http/_reject_websocket), which currently blocks health endpoints like
/status; update __call__ to exempt a small allowlist of health paths (e.g.,
"/status" or "/healthz") by checking scope.get("path") before applying
_unavailable_status_code() and, if the path is in the allowlist, call await
self.app(scope, receive, send) instead of rejecting; ensure both http and
websocket flows consult the same allowlist and keep references to
_unavailable_status_code, _reject_http and _reject_websocket to preserve
existing behavior for other paths.

In `@libs/python/computer-server/tests/test_auth_availability.py`:
- Around line 137-145: The test test_backwards_compat_local_dev_accepts_auth is
brittle because it hits /playwright_exec which depends on
browser_manager.execute_command; change it to assert a specific allowed set or
call a lightweight handler without external deps. Either replace
client.post("/playwright_exec", ...) with a request to a simple endpoint (e.g.
"/commands" or an equivalent no-external-deps route) to ensure only middleware
is exercised, or tighten the assertion to assert resp.status_code in (200, 400,
500) so future browser_manager failures (500) don’t cause false negatives.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c7373be-8f9a-484f-815e-5989fef0e3a2

📥 Commits

Reviewing files that changed from the base of the PR and between 86e3d32 and bc212e7.

📒 Files selected for processing (2)
  • libs/python/computer-server/computer_server/main.py
  • libs/python/computer-server/tests/test_auth_availability.py

@r33drichards r33drichards added the release:pypi/computer-server Release pypi/computer-server on merge label Apr 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📦 Publishable packages changed

  • pypi/computer-server — will auto-release on merge

@r33drichards
r33drichards merged commit 5a21c78 into main Apr 17, 2026
16 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:pypi/computer-server Release pypi/computer-server on merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants