mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
test(e2e): cover credential-backed /v1/messages request (#33863)
* test(e2e): cover credential-backed /v1/messages request Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com> * test(e2e): use runtime Anthropic credential Co-Authored-By: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>
This commit is contained in:
parent
a198e0b0ca
commit
b83c60b9b7
4 changed files with 83 additions and 0 deletions
|
|
@ -66,3 +66,4 @@
|
|||
- {id: mgmt.config_override.hashicorp_vault.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "config_override_endpoints.py", rationale: "Vault integration (smoke)"}
|
||||
- {id: mgmt.workflow.list.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "workflow_management_endpoints.py", rationale: "Workflow tracking (smoke)"}
|
||||
- {id: mgmt.credential_migration.check.happy_path, module: mgmt, tier: P2, surface: api, assertions: [happy_path], source: "key_management_endpoints.py:4252", rationale: "Encryption migration (smoke)"}
|
||||
- {id: mgmt.credential.new.serves_request, module: mgmt, tier: P1, surface: api, assertions: [serves_request], source: "credential_endpoints/endpoints.py:42", rationale: "Stored credential resolves into a deployment and serves a live /messages request"}
|
||||
|
|
|
|||
49
tests/e2e/llm_translation/test_credential_messages_e2e.py
Normal file
49
tests/e2e/llm_translation/test_credential_messages_e2e.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
"""Live e2e: stored credentials resolve into a deployment serving /v1/messages."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from e2e_config import unique_marker
|
||||
from e2e_http import require_successful_call
|
||||
from endpoints_client import EndpointsClient, MessagesResult
|
||||
from lifecycle import ResourceManager
|
||||
from models import CredentialCreateBody, LiteLLMParamsBody
|
||||
|
||||
pytestmark = pytest.mark.e2e
|
||||
|
||||
|
||||
class TestCredentialBackedMessages:
|
||||
@pytest.mark.covers("mgmt.credential.new.serves_request")
|
||||
def test_credential_backed_messages(self, endpoints_client: EndpointsClient, resources: ResourceManager) -> None:
|
||||
marker = unique_marker()
|
||||
credential_name = f"e2e-cred-{marker}"
|
||||
model = f"e2e-cred-messages-{marker}"
|
||||
anthropic_api_key = os.getenv("ANTHROPIC_API_KEY")
|
||||
assert anthropic_api_key, "ANTHROPIC_API_KEY must be set for this live e2e test"
|
||||
|
||||
endpoints_client.proxy.create_credential(
|
||||
CredentialCreateBody(
|
||||
credential_name=credential_name,
|
||||
credential_values={"api_key": anthropic_api_key},
|
||||
)
|
||||
)
|
||||
resources.defer(lambda: endpoints_client.proxy.delete_credential(credential_name))
|
||||
|
||||
model_id = endpoints_client.create_model(
|
||||
model,
|
||||
LiteLLMParamsBody(
|
||||
model="anthropic/claude-haiku-4-5",
|
||||
litellm_credential_name=credential_name,
|
||||
),
|
||||
)
|
||||
resources.defer(lambda: endpoints_client.delete_model(model_id))
|
||||
|
||||
key = resources.key()
|
||||
result = endpoints_client.messages(key, model, "reply with one word")
|
||||
require_successful_call(result)
|
||||
parsed = MessagesResult.model_validate_json(result.body)
|
||||
assert parsed.role == "assistant", f"unexpected role: {result.body[:300]}"
|
||||
assert parsed.text.strip(), f"/v1/messages returned no text: {result.body[:300]}"
|
||||
|
|
@ -498,6 +498,7 @@ class LiteLLMParamsBody(BaseModel):
|
|||
|
||||
model: str
|
||||
api_key: str | None = None
|
||||
litellm_credential_name: str | None = None
|
||||
api_base: str | None = None
|
||||
api_version: str | None = None
|
||||
realtime_protocol: str | None = None
|
||||
|
|
@ -562,6 +563,16 @@ class ModelDeleteBody(BaseModel):
|
|||
id: str
|
||||
|
||||
|
||||
class CredentialCreateBody(BaseModel):
|
||||
credential_name: str
|
||||
credential_values: dict[str, str]
|
||||
credential_info: dict[str, str] = {}
|
||||
|
||||
|
||||
class CredentialCreateResponse(BaseModel):
|
||||
success: bool
|
||||
|
||||
|
||||
# ---------- key / team / user / organization management ----------
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ from models import (
|
|||
ChatResponse,
|
||||
CountTokensBody,
|
||||
CountTokensResponse,
|
||||
CredentialCreateBody,
|
||||
CredentialCreateResponse,
|
||||
CustomerDeleteBody,
|
||||
EmbedBody,
|
||||
EmbedResponse,
|
||||
|
|
@ -219,6 +221,26 @@ class ProxyClient:
|
|||
if not is_ok(result):
|
||||
warnings.warn(f"delete_model({model_id!r}) failed: {result}", stacklevel=2)
|
||||
|
||||
def create_credential(self, body: CredentialCreateBody) -> None:
|
||||
unwrap(
|
||||
self.transport.post(
|
||||
"/credentials",
|
||||
headers=self.transport.master,
|
||||
json=body,
|
||||
response_type=CredentialCreateResponse,
|
||||
)
|
||||
)
|
||||
|
||||
def delete_credential(self, credential_name: str) -> None:
|
||||
result = self.transport.delete(
|
||||
f"/credentials/{credential_name}",
|
||||
headers=self.transport.master,
|
||||
json=NoBody(),
|
||||
response_type=NoBody,
|
||||
)
|
||||
if not is_ok(result):
|
||||
warnings.warn(f"delete_credential({credential_name!r}) failed: {result}", stacklevel=2)
|
||||
|
||||
# ---- LLM calls ------------------------------------------------------
|
||||
|
||||
def chat(self, key: str, body: ChatBody) -> Result[ChatResponse]:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue