mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-13 03:59:12 +00:00
* feat(lens): consume the independent Lens service and shared UI * fix(lens): keep embedded setup stable and vendor UI before builds * chore(lens): pin embedded UI provenance to published Lens source * fix(lens): complete embedded UI extraction across CI builds * docs(lens): record latest main and removal-boundary validation * fix(lens): wire external chart credentials and ingestion modes * test(lens): cover adapter failures and fix extraction CI * docs(lens): refresh bundled chart setup instructions * test(lens): restore gateway adapter test package marker * build(lens): pin clean-cut UI and supported storage chart * test(ui): await guardrail scope menu before checking options * perf(lens): omit unused trace-team lookup from product requests * docs(lens): record final-image adapter permission checks * test(lens): assert delegated investigation authorization * refactor(lens): remove copied trace runtime and preserve spend logging * test(lens): verify independent gateway image upgrades and outages * test(lens): pin the chart qualification database image * fix(lens): update embedded UI metadata filters * test: wait for Lens chart pod identity convergence * fix(e2e): select Lens chart pods by deployment ownership * fix(e2e): select Helm migration ownership for Lens upgrades * test(lens): retain migration Jobs through rollout assertions * docs(helm): require existing database for migration hooks * test(lens): qualify release boundaries with embedded navigation update * docs(lens): record browser qualification for embedded tabs * fix(lens): remove unrelated CI and guardrail test changes * test(lens): give qualification tenants unique key aliases * feat(lens): embed the latest canonical Lens interface * fix(lens): qualify split inference through the gateway * fix(lens): preserve scoped auth and isolate delegated credentials * chore(lens): remove unrelated documentation and lint changes * fix(lens): bound concurrent forwarding buffers through response delivery * fix(lens): preserve OAuth2 dispatch without inference policies * chore(lens): adopt current shared onboarding UI * fix(lens): refresh shared setup UI and review context * fix(lens): bound uploads before gateway authentication * docs(lens): remove extraction evidence from the gateway repo * docs(lens): refresh shared setup prompt for paired releases
86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
import json
|
|
from typing import Final
|
|
|
|
import httpx
|
|
import pytest
|
|
from pydantic import JsonValue
|
|
|
|
from litellm.tracing.remote import RemoteTraceStore
|
|
from litellm.tracing.storage import LensTraceStorage
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("body", "rows"),
|
|
(
|
|
(
|
|
json.dumps(
|
|
{
|
|
"meta": [{"name": "value", "type": "UInt64"}],
|
|
"data": [
|
|
{
|
|
"integer": 9007199254740993,
|
|
"integer_string": "9007199254740993",
|
|
"fraction": 2.5,
|
|
"nested": {"values": [True, None, "text", {"count": 2}]},
|
|
}
|
|
],
|
|
"rows": 1,
|
|
"statistics": {"elapsed": 0.01, "rows_read": 1, "bytes_read": 8},
|
|
"rows_before_limit_at_least": 1,
|
|
"unknown_extra": {"kept_by_internal_validator": True},
|
|
}
|
|
),
|
|
[
|
|
{
|
|
"integer": 9007199254740993,
|
|
"integer_string": "9007199254740993",
|
|
"fraction": 2.5,
|
|
"nested": {"values": [True, None, "text", {"count": 2}]},
|
|
}
|
|
],
|
|
),
|
|
(
|
|
json.dumps(
|
|
{
|
|
"meta": [],
|
|
"data": [],
|
|
"rows": 0,
|
|
"statistics": {"elapsed": 0, "rows_read": 0, "bytes_read": 0},
|
|
}
|
|
),
|
|
[],
|
|
),
|
|
),
|
|
)
|
|
async def test_sql_query_returns_only_rows_without_normalizing_json_values(
|
|
body: str, rows: list[dict[str, JsonValue]]
|
|
) -> None:
|
|
async with httpx.AsyncClient(
|
|
base_url="http://lens", transport=httpx.MockTransport(lambda request: httpx.Response(200, content=body))
|
|
) as client:
|
|
result: Final = await LensTraceStorage(RemoteTraceStore(client)).query_sql(
|
|
"SELECT 1", {"kind": "all"}, "secret"
|
|
)
|
|
|
|
assert result.model_dump(mode="json") == {"data": rows}
|
|
if rows:
|
|
row: Final = result.data[0]
|
|
assert type(row["integer"]) is int
|
|
assert type(row["integer_string"]) is str
|
|
assert type(row["fraction"]) is float
|
|
assert result.data == tuple(rows)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"body",
|
|
(
|
|
'{"meta":[],"data":[],"rows":0}',
|
|
'{"meta":[],"data":{},"rows":0,"statistics":{"elapsed":0,"rows_read":0,"bytes_read":0}}',
|
|
),
|
|
)
|
|
async def test_sql_query_rejects_malformed_clickhouse_envelopes(body: str) -> None:
|
|
async with httpx.AsyncClient(
|
|
base_url="http://lens", transport=httpx.MockTransport(lambda request: httpx.Response(200, content=body))
|
|
) as client:
|
|
with pytest.raises(RuntimeError, match="Lens trace query returned an invalid response"):
|
|
await LensTraceStorage(RemoteTraceStore(client)).query_sql("SELECT 1", {"kind": "all"}, "secret")
|