变量函数重命名

This commit is contained in:
2026-06-29 23:52:14 +08:00
parent 8714fb07c4
commit 92497d35a5
3 changed files with 41 additions and 41 deletions
+3 -3
View File
@@ -13,7 +13,7 @@ from models import (
SendMessageRequest,
SendMessageResponse,
)
from service import ChatService, DeepSeekUpstreamError
from service import ChatProviderError, ChatService
from storage import JsonSessionStorage, SessionNotFoundError, SessionStorageError
@@ -23,7 +23,7 @@ async def encode_sse(
try:
async for event in events:
yield f"data: {json.dumps(event, ensure_ascii=False)}\n\n"
except (DeepSeekUpstreamError, SessionStorageError) as exc:
except (ChatProviderError, SessionStorageError) as exc:
error = {"type": "error", "detail": str(exc)}
yield f"data: {json.dumps(error, ensure_ascii=False)}\n\n"
yield "data: [DONE]\n\n"
@@ -109,7 +109,7 @@ def create_app(
return JSONResponse(content=response.model_dump(mode="json"))
except SessionNotFoundError as exc:
raise HTTPException(status_code=404, detail="session not found") from exc
except DeepSeekUpstreamError as exc:
except ChatProviderError as exc:
raise HTTPException(status_code=502, detail=str(exc)) from exc
except SessionStorageError as exc:
raise HTTPException(status_code=500, detail=str(exc)) from exc
+5 -5
View File
@@ -7,7 +7,7 @@ from models import Message, SendMessageResponse, Session, TokenUsage
from storage import JsonSessionStorage
class DeepSeekUpstreamError(Exception):
class ChatProviderError(Exception):
pass
@@ -41,10 +41,10 @@ class ChatService:
)
assistant_content = completion.choices[0].message.content
except (APIError, IndexError, AttributeError) as exc:
raise DeepSeekUpstreamError("DeepSeek request failed") from exc
raise ChatProviderError("Upstream chat request failed") from exc
if assistant_content is None:
raise DeepSeekUpstreamError("DeepSeek returned an empty response")
raise ChatProviderError("Upstream chat provider returned an empty response")
assistant_message = await self._save_exchange(
session, content, user_created_at, assistant_content
@@ -94,11 +94,11 @@ class ChatService:
finally:
await stream.close()
except (APIError, AttributeError, TypeError) as exc:
raise DeepSeekUpstreamError("DeepSeek stream failed") from exc
raise ChatProviderError("Upstream chat stream failed") from exc
assistant_content = "".join(parts)
if not assistant_content:
raise DeepSeekUpstreamError("DeepSeek returned an empty response")
raise ChatProviderError("Upstream chat provider returned an empty response")
assistant_message = await self._save_exchange(
session, content, user_created_at, assistant_content
+33 -33
View File
@@ -80,8 +80,8 @@ class FakeClient:
@pytest.fixture
def client_and_deepseek(tmp_path: Path) -> tuple[TestClient, FakeClient]:
deepseek = FakeClient()
def client_and_provider(tmp_path: Path) -> tuple[TestClient, FakeClient]:
provider = FakeClient()
settings = Settings(
api_key=None,
base_url="https://api.deepseek.com",
@@ -89,9 +89,9 @@ def client_and_deepseek(tmp_path: Path) -> tuple[TestClient, FakeClient]:
default_system_prompt="default prompt",
data_dir=tmp_path,
)
app = create_app(settings=settings, client=deepseek) # type: ignore[arg-type]
app = create_app(settings=settings, client=provider) # type: ignore[arg-type]
with TestClient(app) as client:
yield client, deepseek
yield client, provider
def create_session(client: TestClient, **body: str) -> str:
@@ -101,9 +101,9 @@ def create_session(client: TestClient, **body: str) -> str:
def test_create_session_uses_default_prompt(
client_and_deepseek: tuple[TestClient, FakeClient], tmp_path: Path
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
) -> None:
client, _ = client_and_deepseek
client, _ = client_and_provider
session_id = create_session(client)
data = json.loads((tmp_path / f"{session_id}.json").read_text())
@@ -112,9 +112,9 @@ def test_create_session_uses_default_prompt(
def test_create_session_without_body(
client_and_deepseek: tuple[TestClient, FakeClient]
client_and_provider: tuple[TestClient, FakeClient]
) -> None:
client, _ = client_and_deepseek
client, _ = client_and_provider
response = client.post("/sessions")
@@ -123,9 +123,9 @@ def test_create_session_without_body(
def test_create_session_accepts_custom_prompt(
client_and_deepseek: tuple[TestClient, FakeClient]
client_and_provider: tuple[TestClient, FakeClient]
) -> None:
client, _ = client_and_deepseek
client, _ = client_and_provider
response = client.post("/sessions", json={"system_prompt": "回答中文"})
assert response.status_code == 201
@@ -133,9 +133,9 @@ def test_create_session_accepts_custom_prompt(
def test_multi_turn_request_contains_full_history(
client_and_deepseek: tuple[TestClient, FakeClient], tmp_path: Path
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
) -> None:
client, deepseek = client_and_deepseek
client, provider = client_and_provider
session_id = create_session(client, system_prompt="system")
first = client.post(
@@ -146,7 +146,7 @@ def test_multi_turn_request_contains_full_history(
)
assert first.status_code == second.status_code == 200
assert deepseek.completions.calls[1]["messages"] == [
assert provider.completions.calls[1]["messages"] == [
{"role": "system", "content": "system"},
{"role": "user", "content": "first"},
{"role": "assistant", "content": "reply-1"},
@@ -169,9 +169,9 @@ def test_multi_turn_request_contains_full_history(
def test_invalid_session_and_blank_message(
client_and_deepseek: tuple[TestClient, FakeClient]
client_and_provider: tuple[TestClient, FakeClient]
) -> None:
client, _ = client_and_deepseek
client, _ = client_and_provider
missing = client.post(
"/sessions/00000000-0000-0000-0000-000000000000/messages",
@@ -187,12 +187,12 @@ def test_invalid_session_and_blank_message(
def test_upstream_failure_does_not_change_history(
client_and_deepseek: tuple[TestClient, FakeClient], tmp_path: Path
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
) -> None:
client, deepseek = client_and_deepseek
client, provider = client_and_provider
session_id = create_session(client)
before = (tmp_path / f"{session_id}.json").read_text()
deepseek.completions.error = APIConnectionError(request=object()) # type: ignore[arg-type]
provider.completions.error = APIConnectionError(request=object()) # type: ignore[arg-type]
response = client.post(
f"/sessions/{session_id}/messages", json={"content": "hello"}
@@ -203,9 +203,9 @@ def test_upstream_failure_does_not_change_history(
def test_corrupt_session_returns_500(
client_and_deepseek: tuple[TestClient, FakeClient], tmp_path: Path
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
) -> None:
client, _ = client_and_deepseek
client, _ = client_and_provider
session_id = create_session(client)
(tmp_path / f"{session_id}.json").write_text("not-json")
@@ -217,9 +217,9 @@ def test_corrupt_session_returns_500(
def test_streaming_response_is_sse_and_persists_complete_message(
client_and_deepseek: tuple[TestClient, FakeClient], tmp_path: Path
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
) -> None:
client, deepseek = client_and_deepseek
client, provider = client_and_provider
session_id = create_session(client, system_prompt="system")
response = client.post(
@@ -241,8 +241,8 @@ def test_streaming_response_is_sse_and_persists_complete_message(
]
assert json.loads(payloads[-2])["usage"]["total_tokens"] == 14
assert payloads[-1] == "[DONE]"
assert deepseek.completions.calls[0]["stream"] is True
assert deepseek.completions.calls[0]["stream_options"] == {
assert provider.completions.calls[0]["stream"] is True
assert provider.completions.calls[0]["stream_options"] == {
"include_usage": True
}
@@ -255,12 +255,12 @@ def test_streaming_response_is_sse_and_persists_complete_message(
def test_streaming_failure_emits_error_and_does_not_persist(
client_and_deepseek: tuple[TestClient, FakeClient], tmp_path: Path
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
) -> None:
client, deepseek = client_and_deepseek
client, provider = client_and_provider
session_id = create_session(client)
before = (tmp_path / f"{session_id}.json").read_text()
deepseek.completions.stream_error = APIConnectionError( # type: ignore[arg-type]
provider.completions.stream_error = APIConnectionError( # type: ignore[arg-type]
request=object()
)
@@ -276,9 +276,9 @@ def test_streaming_failure_emits_error_and_does_not_persist(
def test_legacy_messages_without_timestamp_remain_usable(
client_and_deepseek: tuple[TestClient, FakeClient], tmp_path: Path
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
) -> None:
client, _ = client_and_deepseek
client, _ = client_and_provider
session_id = create_session(client)
path = tmp_path / f"{session_id}.json"
data = json.loads(path.read_text())
@@ -296,13 +296,13 @@ def test_legacy_messages_without_timestamp_remain_usable(
def test_same_session_concurrent_messages_are_serialized(tmp_path: Path) -> None:
async def scenario() -> None:
deepseek = FakeClient()
deepseek.completions.delay = 0.01
provider = FakeClient()
provider.completions.delay = 0.01
storage = JsonSessionStorage(tmp_path)
session = await storage.create("system")
service = ChatService(
storage=storage,
client=deepseek, # type: ignore[arg-type]
client=provider, # type: ignore[arg-type]
model="deepseek-v4-flash",
)
@@ -311,7 +311,7 @@ def test_same_session_concurrent_messages_are_serialized(tmp_path: Path) -> None
service.generate_response(session.session_id, "second"),
)
assert deepseek.completions.calls[1]["messages"] == [
assert provider.completions.calls[1]["messages"] == [
{"role": "system", "content": "system"},
{"role": "user", "content": "first"},
{"role": "assistant", "content": "reply-1"},