* Fix duplicate imports in SAP embedding transformation * fix: add missing prompt_spec parameter to HumanloopLogger.get_chat_completion_prompt - Add prompt_spec: Optional[PromptSpec] = None parameter to match base class signature - Import PromptSpec from litellm.types.prompts.init_prompts - Pass prompt_spec to super().get_chat_completion_prompt() call - Fixes mypy type error: Signature incompatible with supertype CustomLogger * fix: add missing parameters to AnthropicCacheControlHook.async_get_chat_completion_prompt - Add ignore_prompt_manager_model and ignore_prompt_manager_optional_params parameters - Change litellm_logging_obj type from Any to LiteLLMLoggingObj using TYPE_CHECKING pattern - Pass all parameters including prompt_spec to get_chat_completion_prompt call - Fixes mypy type errors: Signature incompatible with supertype CustomLogger and PromptManagementBase * fix: add missing parameters to DotpromptManager.async_get_chat_completion_prompt - Add ignore_prompt_manager_model and ignore_prompt_manager_optional_params parameters - Change litellm_logging_obj type from Any to LiteLLMLoggingObj using TYPE_CHECKING pattern - Pass all parameters including ignore flags to PromptManagementBase.async_get_chat_completion_prompt - Fixes mypy type errors: Signature incompatible with supertype CustomLogger and PromptManagementBase * fix: document envs * fix: add missing parameters to LangfusePromptManagement.async_get_chat_completion_prompt - Add ignore_prompt_manager_model and ignore_prompt_manager_optional_params parameters - Pass all parameters including prompt_spec and ignore flags to get_chat_completion_prompt - Fixes mypy type errors: Signature incompatible with supertype CustomLogger and PromptManagementBase * fix: add missing parameters to prompt management async methods (Category 1) - vector_store_pre_call_hook: add ignore_prompt_manager_model, ignore_prompt_manager_optional_params, prompt_spec - gitlab_prompt_manager: add ignore parameters, fix litellm_logging_obj type - bitbucket_prompt_manager: add ignore parameters, fix litellm_logging_obj type - proxy/custom_prompt_management: add prompt_spec parameter - Fixes mypy type errors: Signature incompatible with supertype * fix: fix arize_phoenix_prompt_manager and custom_prompt_management (Category 2) - arize_phoenix_prompt_manager: add prompt_spec to all methods, fix prompt_id types, implement async_compile_prompt_helper - custom_prompt_management: implement async_compile_prompt_helper abstract method - Fixes mypy type errors: Signature incompatible with supertype and abstract method errors * fix: fix obvious type errors (Category 3 - Quick Wins) - langfuse: change 'callable' to 'Callable' type annotation - presidio: add type narrowing check for Choices vs StreamingChoices - StreamingChoices doesn't have .message attribute, only Choices does - Add hasattr check before accessing choice.message - Fixes mypy type errors: callable? not callable and union-attr errors * fix: handle expires_after None in Azure files handler (Todo 14) - Extract logic to _prepare_create_file_data helper method - Remove expires_after from dict if None to match SDK's Omit pattern - Add type ignore for FileExpiresAfter -> file_create_params.ExpiresAfter mismatch - Fixes mypy error: Argument expires_after has incompatible type * fix: change purpose parameter type to OpenAIFilesPurpose (Todo 18) - Import OpenAIFilesPurpose in storage_backend_service.py - Change upload_file_to_storage_backend purpose parameter from str to OpenAIFilesPurpose - Change _create_file_object_with_storage_metadata purpose parameter from str to OpenAIFilesPurpose - Fixes mypy error: Argument purpose has incompatible type str; expected Literal type - Purpose is already validated in files_endpoints.py before reaching these functions * fix: handle UploadFile | str type for expires_after form fields (Todo 19) - Validate expires_after[anchor] and expires_after[seconds] are strings, not UploadFiles - Validate anchor equals 'created_at' before using literal in TypedDict - Use literal 'created_at' (not variable) in FileExpiresAfter to satisfy Literal type - Add proper error handling for invalid anchor values and int conversion - Fixes mypy errors: Incompatible types for anchor and seconds in FileExpiresAfter * fix: add type narrowing for expires_after_seconds_str to fix mypy error - Add assert statement after UploadFile validation to help mypy narrow type - Use validated variable with explicit str type annotation - Fixes: Argument of type 'UploadFile | str' cannot be assigned to int() * fix: trigger async_success_handler for MCP tool calls to enable cost tracking and logging - Set call_type to CallTypes.call_mcp_tool.value before calling async_success_handler - Update mcp_tool_call_metadata with cost info when server is found - Call async_success_handler to build standard_logging_object and trigger callbacks - Fixes test_mcp_cost_tracking by ensuring standard_logging_payload is populated * refactor: use positive isinstance check for safer type narrowing - Replace assert with positive isinstance(..., str) check - Matches codebase pattern (see pass_through_endpoints.py) - Safer than assert: assertions can be disabled with -O flag - Mypy properly narrows type after positive isinstance check - More explicit and readable than assert statement * fix: add missing REDIS_DAILY_AGENT_SPEND_UPDATE_QUEUE to ServiceTypes enum (Todo 17) - Add REDIS_DAILY_AGENT_SPEND_UPDATE_QUEUE enum value following the pattern of other daily spend queues - Add corresponding entry to DEFAULT_SERVICE_CONFIGS with GAUGE metrics - Fixes mypy error: 'type[ServiceTypes]' has no attribute 'REDIS_DAILY_AGENT_SPEND_UPDATE_QUEUE' - This enum value is already used in redis_update_buffer.py for agent spend tracking |
||
|---|---|---|
| .circleci | ||
| .devcontainer | ||
| .github | ||
| ci_cd | ||
| cookbook | ||
| db_scripts | ||
| deploy | ||
| dist | ||
| docker | ||
| docs/my-website | ||
| enterprise | ||
| litellm | ||
| litellm-js | ||
| litellm-proxy-extras | ||
| scripts | ||
| tests | ||
| ui/litellm-dashboard | ||
| .dockerignore | ||
| .env.example | ||
| .flake8 | ||
| .git-blame-ignore-revs | ||
| .gitattributes | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| AGENTS.md | ||
| batch_small.jsonl | ||
| CLAUDE.md | ||
| codecov.yaml | ||
| CONTRIBUTING.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| document.txt | ||
| GEMINI.md | ||
| index.yaml | ||
| LICENSE | ||
| Makefile | ||
| mcp_servers.json | ||
| model_prices_and_context_window.json | ||
| package-lock.json | ||
| package.json | ||
| poetry.lock | ||
| prometheus.yml | ||
| provider_endpoints_support.json | ||
| proxy_server_config.yaml | ||
| pyproject.toml | ||
| pyrightconfig.json | ||
| README.md | ||
| render.yaml | ||
| requirements.txt | ||
| ruff.toml | ||
| schema.prisma | ||
| security.md | ||
🚅 LiteLLM
Call all LLM APIs using the OpenAI format [Bedrock, Huggingface, VertexAI, TogetherAI, Azure, OpenAI, Groq etc.]
LiteLLM Proxy Server (LLM Gateway) | Hosted Proxy | Enterprise Tier
LiteLLM manages:
- Translate inputs to provider's
completion,embedding, andimage_generationendpoints - Consistent output, text responses will always be available at
['choices'][0]['message']['content'] - Retry/fallback logic across multiple deployments (e.g. Azure/OpenAI) - Router
- Set Budgets & Rate limits per project, api key, model LiteLLM Proxy Server (LLM Gateway)
LiteLLM Performance: 8ms P95 latency at 1k RPS (See benchmarks here)
Jump to LiteLLM Proxy (LLM Gateway) Docs
Jump to Supported LLM Providers
🚨 Stable Release: Use docker images with the -stable tag. These have undergone 12 hour load tests, before being published. More information about the release cycle here
Support for more providers. Missing a provider or LLM Platform, raise a feature request.
Usage (Docs)
pip install litellm
from litellm import completion
import os
## set ENV variables
os.environ["OPENAI_API_KEY"] = "your-openai-key"
os.environ["ANTHROPIC_API_KEY"] = "your-anthropic-key"
messages = [{ "content": "Hello, how are you?","role": "user"}]
# openai call
response = completion(model="openai/gpt-4o", messages=messages)
# anthropic call
response = completion(model="anthropic/claude-sonnet-4-20250514", messages=messages)
print(response)
Response (OpenAI Format)
{
"id": "chatcmpl-1214900a-6cdd-4148-b663-b5e2f642b4de",
"created": 1751494488,
"model": "claude-sonnet-4-20250514",
"object": "chat.completion",
"system_fingerprint": null,
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "Hello! I'm doing well, thank you for asking. I'm here and ready to help with whatever you'd like to discuss or work on. How are you doing today?",
"role": "assistant",
"tool_calls": null,
"function_call": null
}
}
],
"usage": {
"completion_tokens": 39,
"prompt_tokens": 13,
"total_tokens": 52,
"completion_tokens_details": null,
"prompt_tokens_details": {
"audio_tokens": null,
"cached_tokens": 0
},
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}
Note: LiteLLM also supports the Responses API (
litellm.responses())
Call any model supported by a provider, with model=<provider_name>/<model_name>. There might be provider-specific details here, so refer to provider docs for more information
Async (Docs)
from litellm import acompletion
import asyncio
async def test_get_response():
user_message = "Hello, how are you?"
messages = [{"content": user_message, "role": "user"}]
response = await acompletion(model="openai/gpt-4o", messages=messages)
return response
response = asyncio.run(test_get_response())
print(response)
Streaming (Docs)
LiteLLM supports streaming the model response back, pass stream=True to get a streaming iterator in response.
Streaming is supported for all models (Bedrock, Huggingface, TogetherAI, Azure, OpenAI, etc.)
from litellm import completion
messages = [{"content": "Hello, how are you?", "role": "user"}]
# gpt-4o
response = completion(model="openai/gpt-4o", messages=messages, stream=True)
for part in response:
print(part.choices[0].delta.content or "")
# claude sonnet 4
response = completion('anthropic/claude-sonnet-4-20250514', messages, stream=True)
for part in response:
print(part)
Response chunk (OpenAI Format)
{
"id": "chatcmpl-fe575c37-5004-4926-ae5e-bfbc31f356ca",
"created": 1751494808,
"model": "claude-sonnet-4-20250514",
"object": "chat.completion.chunk",
"system_fingerprint": null,
"choices": [
{
"finish_reason": null,
"index": 0,
"delta": {
"provider_specific_fields": null,
"content": "Hello",
"role": "assistant",
"function_call": null,
"tool_calls": null,
"audio": null
},
"logprobs": null
}
],
"provider_specific_fields": null,
"stream_options": null,
"citations": null
}
Logging Observability (Docs)
LiteLLM exposes pre defined callbacks to send data to Lunary, MLflow, Langfuse, DynamoDB, s3 Buckets, Helicone, Promptlayer, Traceloop, Athina, Slack
from litellm import completion
## set env variables for logging tools (when using MLflow, no API key set up is required)
os.environ["LUNARY_PUBLIC_KEY"] = "your-lunary-public-key"
os.environ["HELICONE_API_KEY"] = "your-helicone-auth-key"
os.environ["LANGFUSE_PUBLIC_KEY"] = ""
os.environ["LANGFUSE_SECRET_KEY"] = ""
os.environ["ATHINA_API_KEY"] = "your-athina-api-key"
os.environ["OPENAI_API_KEY"] = "your-openai-key"
# set callbacks
litellm.success_callback = ["lunary", "mlflow", "langfuse", "athina", "helicone"] # log input/output to lunary, langfuse, supabase, athina, helicone etc
#openai call
response = completion(model="openai/gpt-4o", messages=[{"role": "user", "content": "Hi 👋 - i'm openai"}])
LiteLLM Proxy Server (LLM Gateway) - (Docs)
Track spend + Load Balance across multiple projects
The proxy provides:
📖 Proxy Endpoints - Swagger Docs
Quick Start Proxy - CLI
pip install 'litellm[proxy]'
Step 1: Start litellm proxy
$ litellm --model huggingface/bigcode/starcoder
#INFO: Proxy running on http://0.0.0.0:4000
Step 2: Make ChatCompletions Request to Proxy
Important
import openai # openai v1.0.0+
client = openai.OpenAI(api_key="anything",base_url="http://0.0.0.0:4000") # set proxy to base_url
# request sent to model set on litellm proxy, `litellm --model`
response = client.chat.completions.create(model="gpt-3.5-turbo", messages = [
{
"role": "user",
"content": "this is a test request, write a short poem"
}
])
print(response)
Proxy Key Management (Docs)
Connect the proxy with a Postgres DB to create proxy keys
# Get the code
git clone https://github.com/BerriAI/litellm
# Go to folder
cd litellm
# Add the master key - you can change this after setup
echo 'LITELLM_MASTER_KEY="sk-1234"' > .env
# Add the litellm salt key - you cannot change this after adding a model
# It is used to encrypt / decrypt your LLM API Key credentials
# We recommend - https://1password.com/password-generator/
# password generator to get a random hash for litellm salt key
echo 'LITELLM_SALT_KEY="sk-1234"' >> .env
# Start
docker compose up
UI on /ui on your proxy server
Set budgets and rate limits across multiple projects
POST /key/generate
Request
curl 'http://0.0.0.0:4000/key/generate' \
--header 'Authorization: Bearer sk-1234' \
--header 'Content-Type: application/json' \
--data-raw '{"models": ["gpt-3.5-turbo", "gpt-4", "claude-2"], "duration": "20m","metadata": {"user": "ishaan@berri.ai", "team": "core-infra"}}'
Expected Response
{
"key": "sk-kdEXbIqZRwEeEiHwdg7sFA", # Bearer token
"expires": "2023-11-19T01:38:25.838000+00:00" # datetime object
}
Supported Providers (Website Supported Models | Docs)
Run in Developer mode
Services
- Setup .env file in root
- Run dependant services
docker-compose up db prometheus
Backend
- (In root) create virtual environment
python -m venv .venv - Activate virtual environment
source .venv/bin/activate - Install dependencies
pip install -e ".[all]" - Start proxy backend
python litellm/proxy_cli.py
Frontend
- Navigate to
ui/litellm-dashboard - Install dependencies
npm install - Run
npm run devto start the dashboard
Enterprise
For companies that need better security, user management and professional support
This covers:
- ✅ Features under the LiteLLM Commercial License:
- ✅ Feature Prioritization
- ✅ Custom Integrations
- ✅ Professional Support - Dedicated discord + slack
- ✅ Custom SLAs
- ✅ Secure access with Single Sign-On
Contributing
We welcome contributions to LiteLLM! Whether you're fixing bugs, adding features, or improving documentation, we appreciate your help.
Quick Start for Contributors
This requires poetry to be installed.
git clone https://github.com/BerriAI/litellm.git
cd litellm
make install-dev # Install development dependencies
make format # Format your code
make lint # Run all linting checks
make test-unit # Run unit tests
make format-check # Check formatting only
For detailed contributing guidelines, see CONTRIBUTING.md.
Code Quality / Linting
LiteLLM follows the Google Python Style Guide.
Our automated checks include:
- Black for code formatting
- Ruff for linting and code quality
- MyPy for type checking
- Circular import detection
- Import safety checks
All these checks must pass before your PR can be merged.
Support / talk with founders
- Schedule Demo 👋
- Community Discord 💭
- Community Slack 💭
- Our numbers 📞 +1 (770) 8783-106 / +1 (412) 618-6238
- Our emails ✉️ ishaan@berri.ai / krrish@berri.ai
Why did we build this
- Need for simplicity: Our code started to get extremely complicated managing & translating calls between Azure, OpenAI and Cohere.