litellm/tests/base_sdk_tests/check_base_sdk_install.py
Mateo a2928efc75 test(cli): cover the keyless token record and keep keyring to the cli extra
`lite up` treats a token record whose key the keychain would not hand over as no
login at all, and that clause had no test: every existing freshness test passed a
record carrying a real key, so deleting the clause left the whole suite green

The base install smoke check now also asserts keyring is absent, which is what
makes the lazy import in cli_keyring meaningful. keyring ships in the cli extra
only, so a plain `pip install litellm` must not be able to reach it
2026-08-20 03:45:00 -07:00

144 lines
4.7 KiB
Python

"""Smoke-check that a base ``pip install litellm`` (no extras) is importable and usable.
Run against a virtualenv that has the built wheel installed with no extras, using
that venv's own interpreter and nothing else. Deliberately stdlib-only: pytest would
pull ``packaging``, ``pluggy`` and ``iniconfig`` into the environment and could mask
the very class of undeclared-dependency bug this guards against.
"""
import importlib.util
import sys
import traceback
from collections.abc import Callable
EXTRAS_ONLY_MODULES = ("fastapi", "uvicorn", "keyring")
def _require(condition: bool, message: str) -> None:
if not condition:
raise AssertionError(message)
def check_environment_is_base_only() -> str:
present = tuple(name for name in EXTRAS_ONLY_MODULES if importlib.util.find_spec(name) is not None)
_require(
not present,
f"{', '.join(present)} installed, so this environment is not base-only and the run proves nothing",
)
return f"no extras-only packages present ({', '.join(EXTRAS_ONLY_MODULES)})"
def check_import() -> str:
from importlib.metadata import version
import litellm
_require(bool(litellm.__file__), "litellm has no __file__")
return f"imported litellm {version('litellm')}"
def check_completion() -> str:
import litellm
response = litellm.completion(
model="gpt-4o",
messages=[{"role": "user", "content": "ping"}],
mock_response="pong",
)
content = response.choices[0].message.content
_require(content == "pong", f"mock completion returned {content!r}")
return "mock completion round-trips"
def check_embedding() -> str:
import litellm
response = litellm.embedding(
model="text-embedding-3-small",
input=["ping"],
mock_response=[[0.1, 0.2]],
)
_require(len(response.data) == 1, f"mock embedding returned {len(response.data)} rows")
return "mock embedding round-trips"
def check_bundled_model_metadata() -> str:
import litellm
max_input_tokens = litellm.get_model_info("gpt-4o")["max_input_tokens"]
_require(
isinstance(max_input_tokens, int) and max_input_tokens > 0,
f"get_model_info returned max_input_tokens={max_input_tokens!r}",
)
prompt_cost, completion_cost = litellm.cost_per_token(model="gpt-4o", prompt_tokens=1000, completion_tokens=1000)
_require(
prompt_cost > 0 and completion_cost > 0,
f"cost_per_token returned ({prompt_cost}, {completion_cost})",
)
return f"bundled pricing metadata readable (gpt-4o max_input_tokens={max_input_tokens})"
def check_token_counter() -> str:
import litellm
count = litellm.token_counter(model="gpt-4o", text="hello world")
_require(count > 0, f"token_counter returned {count!r}")
return f"token_counter returned {count}"
def check_bedrock_credential_resolution() -> str:
import os
from unittest import mock
from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM
non_aws_environ = {k: v for k, v in os.environ.items() if not k.startswith("AWS_")}
with mock.patch.dict(os.environ, non_aws_environ, clear=True):
credentials = BaseAWSLLM().get_credentials(
aws_access_key_id="AKIA-fake-base-sdk-check",
aws_secret_access_key="fake-secret",
aws_region_name="us-east-1",
)
_require(
credentials.access_key == "AKIA-fake-base-sdk-check",
f"get_credentials returned access_key={credentials.access_key!r}",
)
return "bedrock credential resolution works (boto3 ships with the base SDK)"
CHECKS: tuple[tuple[str, Callable[[], str]], ...] = (
("environment is base-only", check_environment_is_base_only),
("import litellm", check_import),
("chat completion", check_completion),
("embedding", check_embedding),
("bundled model metadata", check_bundled_model_metadata),
("token counter", check_token_counter),
("bedrock credential resolution", check_bedrock_credential_resolution),
)
def _run(check: Callable[[], str]) -> tuple[bool, str]:
try:
return True, check()
except Exception:
return False, traceback.format_exc()
def main() -> int:
print(f"base SDK smoke check on {sys.executable}")
for label, check in CHECKS:
passed, detail = _run(check)
if not passed:
print(f"FAIL {label}:\n{detail}")
print(f"A base `pip install litellm` is broken at: {label}")
print("Something needed at import or call time is missing from [project].dependencies")
print("in pyproject.toml. Declaring it only in an extra is what causes this.")
return 1
print(f"PASS {label}: {detail}")
print(f"\nall {len(CHECKS)} checks passed")
return 0
if __name__ == "__main__":
raise SystemExit(main())