style: fix ruff lint/format and mypy errors for CI 3.12 pass

- Remove 101 trailing whitespace violations (W293), 2 unused imports
  (F401), 1 import sort issue (I001) in anthropic handler and test file
- Apply ruff format to anthropic handler and oauth routing test
- Fix mypy no-any-return in jitter_delay_ms by adding explicit type
- Fix mypy attr-defined for signal.SIGKILL on Windows using getattr

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
JerrettDavis 2026-04-20 13:23:20 -05:00
parent b7b780aaa9
commit 6200ba3963
4 changed files with 134 additions and 116 deletions

View file

@ -612,9 +612,10 @@ def _kill_proxy_by_pid(pid: int, port: int) -> bool:
if not _check_proxy(port):
return True
# SIGTERM didn't work — escalate to SIGKILL
# SIGTERM didn't work — escalate to SIGKILL (Unix) or terminate (Windows)
try:
os.kill(pid, signal.SIGKILL)
_kill_signal = getattr(signal, "SIGKILL", signal.SIGTERM)
os.kill(pid, _kill_signal)
except (ProcessLookupError, PermissionError):
pass

View file

@ -1082,7 +1082,10 @@ class AnthropicHandlerMixin:
# Non-stream: first-byte and connect are effectively
# the same horizon — ``send_message`` awaits until
# the response body is fully buffered.
if "upstream_first_byte" not in stage_timer and "upstream_connect" in stage_timer:
if (
"upstream_first_byte" not in stage_timer
and "upstream_connect" in stage_timer
):
stage_timer.record(
"upstream_first_byte",
stage_timer.summary()["upstream_connect"],
@ -1186,7 +1189,10 @@ class AnthropicHandlerMixin:
else:
async with stage_timer.measure("upstream_connect"):
response = await self._retry_request("POST", url, headers, body)
if "upstream_first_byte" not in stage_timer and "upstream_connect" in stage_timer:
if (
"upstream_first_byte" not in stage_timer
and "upstream_connect" in stage_timer
):
stage_timer.record(
"upstream_first_byte",
stage_timer.summary()["upstream_connect"],
@ -1319,7 +1325,9 @@ class AnthropicHandlerMixin:
}
# Reuse main client for CCR continuations (connection pooling)
logger.info(f"CCR: Making continuation request with {len(msgs)} messages")
logger.info(
f"CCR: Making continuation request with {len(msgs)} messages"
)
assert self.http_client is not None, "HTTP client not initialized"
try:
cont_response = await self.http_client.post(
@ -1453,7 +1461,9 @@ class AnthropicHandlerMixin:
output_tokens = usage.get("output_tokens", 0)
cr_tokens = usage.get("cache_read_input_tokens", 0)
cw_tokens = usage.get("cache_creation_input_tokens", 0)
cw_5m_tokens, cw_1h_tokens = self._extract_anthropic_cache_ttl_metrics(usage)
cw_5m_tokens, cw_1h_tokens = self._extract_anthropic_cache_ttl_metrics(
usage
)
uncached_input_tokens = usage.get("input_tokens", 0)
# Track cache bust: tokens that lost their cache discount due to compression.
@ -1562,7 +1572,9 @@ class AnthropicHandlerMixin:
cache_hit=cache_hit,
transforms_applied=transforms_applied,
waste_signals=waste_signals_dict,
request_messages=messages if self.config.log_full_messages else None,
request_messages=messages
if self.config.log_full_messages
else None,
)
)
@ -1673,6 +1685,7 @@ class AnthropicHandlerMixin:
# deep-copy) would otherwise leak the pre-upstream semaphore
# permanently. The emit function is idempotent.
await _finalize_pre_upstream()
async def handle_anthropic_batch_create(
self,
request: Request,

View file

@ -44,7 +44,8 @@ def jitter_delay_ms(base_ms: int, max_ms: int, attempt: int) -> float:
canonical formula used across proxy retry loops. Extracted so every
retry site shares one implementation.
"""
return min(base_ms * (2**attempt), max_ms) * (0.5 + random.random())
capped: float = min(base_ms * (2**attempt), max_ms)
return capped * (0.5 + random.random())
# Image compression (lazy-loaded to avoid heavy dependencies at startup)

View file

@ -1,12 +1,10 @@
"""Tests for OAuth Bearer token routing and auth detection."""
import httpx
import pytest
from fastapi.testclient import TestClient
from headroom.proxy.helpers import is_anthropic_auth
from headroom.proxy.server import HeadroomProxy, ProxyConfig, create_app
from headroom.proxy.server import ProxyConfig, create_app
# ---------------------------------------------------------------------------
# Unit tests: is_anthropic_auth
@ -39,10 +37,15 @@ class TestIsAnthropicAuth:
def test_anthropic_version_plus_bearer(self):
"""Claude Code sends both anthropic-version and Bearer token."""
assert is_anthropic_auth({
"anthropic-version": "2023-06-01",
"authorization": "Bearer 1a18a113-ab50-43c8",
}) is True
assert (
is_anthropic_auth(
{
"anthropic-version": "2023-06-01",
"authorization": "Bearer 1a18a113-ab50-43c8",
}
)
is True
)
def test_empty_authorization(self):
assert is_anthropic_auth({"authorization": ""}) is False