mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
`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
144 lines
4.7 KiB
Python
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())
|