mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
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:
parent
b7b780aaa9
commit
6200ba3963
4 changed files with 134 additions and 116 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue