Skip to content

refactor: clean up Anthropic _build_headers() side effect #159

Description

@Kamilbenkirane

Summary

_build_headers() in the Anthropic client mutates its request_body argument via .pop("_beta_features", []). A method named "build headers" shouldn't have the side effect of modifying the request body.

Current Code

def _build_headers(self, request_body: dict[str, Any]) -> dict[str, str]:
    """Build headers with beta features extracted from request."""
    beta_features: list[str] = request_body.pop("_beta_features", [])  # mutates request_body!

    headers: dict[str, str] = {
        **self.auth.get_headers(),
        config.HEADER_ANTHROPIC_VERSION: config.ANTHROPIC_VERSION,
        "Content-Type": ApplicationMimeType.JSON,
    }

    if beta_features:
        beta_values = [
            getattr(config, f"BETA_{f.upper().replace('-', '_')}")
            for f in beta_features
        ]
        headers[config.HEADER_ANTHROPIC_BETA] = ",".join(beta_values)

    return headers

Proposed Change

Move the .pop() to the callers (_make_request and _make_stream_request) and pass beta features as a parameter:

# In _make_request / _make_stream_request:
beta_features = request_body.pop("_beta_features", [])
headers = self._build_headers(beta_features=beta_features)

# _build_headers becomes pure:
def _build_headers(self, beta_features: list[str] | None = None) -> dict[str, str]:
    headers: dict[str, str] = {
        **self.auth.get_headers(),
        config.HEADER_ANTHROPIC_VERSION: config.ANTHROPIC_VERSION,
        "Content-Type": ApplicationMimeType.JSON,
    }
    if beta_features:
        beta_values = [
            getattr(config, f"BETA_{f.upper().replace('-', '_')}")
            for f in beta_features
        ]
        headers[config.HEADER_ANTHROPIC_BETA] = ",".join(beta_values)
    return headers

File to Modify

  • src/celeste/providers/anthropic/messages/client.py

Rationale

Makes data flow explicit - the mutation is visible at the call site. The _build_headers method becomes a pure function that only builds headers. This is a localized, low-risk change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions