Bump version to 0.1.2; update logging paths and enhance CLI with version command
This commit is contained in:
@@ -4,6 +4,7 @@ import json
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from nexus_claude_api import __version__
|
||||
from nexus_claude_api.cli import main
|
||||
from nexus_claude_api.config import (
|
||||
Settings,
|
||||
@@ -62,6 +63,38 @@ def test_missing_api_key_fails(monkeypatch) -> None:
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_version_prints_package_version(capsys) -> None:
|
||||
try:
|
||||
main(["--version"])
|
||||
except SystemExit as exc:
|
||||
assert exc.code == 0
|
||||
|
||||
output = capsys.readouterr()
|
||||
assert output.out.strip() == f"nexus-claude-api {__version__}"
|
||||
|
||||
|
||||
def test_invalid_user_config_returns_clean_error(monkeypatch, capsys) -> None:
|
||||
tmp_path = _workspace_tmp("invalid-user-config")
|
||||
user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json"
|
||||
user_config.parent.mkdir(parents=True, exist_ok=True)
|
||||
user_config.write_text("{not json", encoding="utf-8")
|
||||
monkeypatch.setattr("nexus_claude_api.config.USER_CONFIG_FILE", user_config)
|
||||
monkeypatch.delenv("NEXUS_API_KEY", raising=False)
|
||||
monkeypatch.delenv("AWS_BEARER_TOKEN_BEDROCK", raising=False)
|
||||
monkeypatch.chdir(tmp_path)
|
||||
|
||||
try:
|
||||
exit_code = main(["start", "--dry-run"])
|
||||
finally:
|
||||
monkeypatch.chdir(Path(__file__).parents[1])
|
||||
shutil.rmtree(tmp_path, ignore_errors=True)
|
||||
|
||||
output = capsys.readouterr()
|
||||
assert exit_code == 2
|
||||
assert "Invalid configuration: Invalid JSON" in output.err
|
||||
assert "Traceback" not in output.err
|
||||
|
||||
|
||||
def test_user_config_api_key(monkeypatch) -> None:
|
||||
tmp_path = _workspace_tmp("user-config")
|
||||
user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json"
|
||||
|
||||
@@ -5,6 +5,7 @@ import logging
|
||||
from botocore.exceptions import ClientError
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from nexus_claude_api.errors import NexusClaudeError
|
||||
from nexus_claude_api.config import Settings
|
||||
from nexus_claude_api.nexus_client import _map_client_error
|
||||
from nexus_claude_api.server import create_app
|
||||
@@ -52,6 +53,21 @@ class AccessDeniedNexusClient:
|
||||
)
|
||||
|
||||
|
||||
class StreamErrorNexusClient:
|
||||
def converse_stream(self, request: dict, *, correlation_id: str | None = None):
|
||||
assert correlation_id
|
||||
|
||||
def events():
|
||||
yield {"contentBlockDelta": {"contentBlockIndex": 0, "delta": {"text": "Hi"}}}
|
||||
raise NexusClaudeError(
|
||||
"stream failed",
|
||||
status_code=502,
|
||||
error_type="api_error",
|
||||
)
|
||||
|
||||
return events()
|
||||
|
||||
|
||||
def client(nexus_client: object | None = None) -> TestClient:
|
||||
settings = Settings.from_values(api_key="test", require_api_key=False)
|
||||
return TestClient(
|
||||
@@ -183,6 +199,26 @@ def test_messages_stream() -> None:
|
||||
assert "event: message_stop" in body
|
||||
|
||||
|
||||
def test_messages_stream_returns_sse_error_when_stream_iteration_fails() -> None:
|
||||
with client(StreamErrorNexusClient()).stream(
|
||||
"POST",
|
||||
"/v1/messages",
|
||||
json={
|
||||
"model": "claude-opus-4.6",
|
||||
"messages": [{"role": "user", "content": "Hello"}],
|
||||
"max_tokens": 32,
|
||||
"stream": True,
|
||||
},
|
||||
) as response:
|
||||
body = response.read().decode("utf-8")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert "event: content_block_delta" in body
|
||||
assert "event: error" in body
|
||||
assert "stream failed" in body
|
||||
assert "correlation_id" in body
|
||||
|
||||
|
||||
def test_count_tokens() -> None:
|
||||
response = client().post(
|
||||
"/v1/messages/count_tokens",
|
||||
|
||||
@@ -28,6 +28,22 @@ def test_text_request_translation() -> None:
|
||||
assert request["inferenceConfig"]["temperature"] == 0.2
|
||||
|
||||
|
||||
def test_stop_sequences_are_translated_into_inference_config() -> None:
|
||||
payload = AnthropicMessagesRequest.model_validate(
|
||||
{
|
||||
"model": "claude-opus-4.6",
|
||||
"messages": [{"role": "user", "content": "Hello"}],
|
||||
"max_tokens": 100,
|
||||
"stop_sequences": ["STOP"],
|
||||
}
|
||||
)
|
||||
|
||||
request = anthropic_to_bedrock_request(payload)
|
||||
|
||||
assert request["inferenceConfig"]["stopSequences"] == ["STOP"]
|
||||
assert "stopSequences" not in request
|
||||
|
||||
|
||||
def test_image_request_translation() -> None:
|
||||
image_data = base64.b64encode(b"image-bytes").decode("ascii")
|
||||
payload = AnthropicMessagesRequest.model_validate(
|
||||
|
||||
Reference in New Issue
Block a user