mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
fix(security): remove the publicly known master key from the repo (#44718)
* fix(security): hash the publicly known master key Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * docs: replace weak master key examples and regenerate artifacts Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test: replace weak key fixtures with generated test keys Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: generate master keys for proxy startup Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: preserve lens dev key entropy Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: restore proxy key compatibility in scrub examples Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: scrub merged SSO fixture and refresh dashboard bundle Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): stabilize test keys and metadata collection Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * chore: drop the rebuilt dashboard bundle Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: mateo <mateo@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
ab61410a39
commit
837c6a7481
286 changed files with 1895 additions and 1591 deletions
|
|
@ -1706,6 +1706,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -1729,9 +1734,8 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4001:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL="postgresql://postgres:postgres@host.docker.internal:5432/litellm_test" \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
--name schema-seed \
|
||||
--add-host=host.docker.internal:host-gateway \
|
||||
-v $(pwd)/litellm/proxy/example_config_yaml/simple_config.yaml:/app/config.yaml \
|
||||
|
|
@ -1802,6 +1806,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- attach_workspace:
|
||||
at: ~/project
|
||||
|
|
@ -1825,9 +1834,8 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e USE_PRISMA_MIGRATE=True \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e AZURE_API_KEY=$AZURE_API_KEY \
|
||||
|
|
@ -1872,7 +1880,7 @@ jobs:
|
|||
name: Seed the routing strategy through /config/update
|
||||
command: |
|
||||
curl --noproxy '*' -sSf -X POST http://localhost:4000/config/update \
|
||||
-H 'Authorization: Bearer sk-1234' -H 'Content-Type: application/json' \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" -H 'Content-Type: application/json' \
|
||||
-d '{"router_settings": {"routing_strategy": "usage-based-routing-v2"}}'
|
||||
- run:
|
||||
name: Run tests
|
||||
|
|
@ -1901,6 +1909,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -1922,9 +1935,8 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e AZURE_API_KEY=$AZURE_API_KEY \
|
||||
-e AZURE_API_BASE=$AZURE_API_BASE \
|
||||
-e AZURE_API_VERSION="2024-05-01-preview" \
|
||||
|
|
@ -1987,6 +1999,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -2012,12 +2029,11 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e REDIS_HOST=$REDIS_HOST \
|
||||
-e REDIS_PASSWORD=$REDIS_PASSWORD \
|
||||
-e REDIS_PORT=$REDIS_PORT \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e LITELLM_LICENSE=$LITELLM_LICENSE \
|
||||
|
|
@ -2073,12 +2089,11 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e REDIS_HOST=$REDIS_HOST \
|
||||
-e REDIS_PASSWORD=$REDIS_PASSWORD \
|
||||
-e REDIS_PORT=$REDIS_PORT \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e LITELLM_LICENSE="bad-license" \
|
||||
|
|
@ -2122,6 +2137,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -2151,11 +2171,10 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e REDIS_HOST=host.docker.internal \
|
||||
-e REDIS_PORT=6379 \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e LITELLM_LICENSE=$LITELLM_LICENSE \
|
||||
|
|
@ -2210,6 +2229,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -2234,12 +2258,11 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e REDIS_HOST=$REDIS_HOST \
|
||||
-e REDIS_PASSWORD=$REDIS_PASSWORD \
|
||||
-e REDIS_PORT=$REDIS_PORT \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e LITELLM_LICENSE=$LITELLM_LICENSE \
|
||||
-e USE_DDTRACE=True \
|
||||
|
|
@ -2257,12 +2280,11 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4001:4001 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e REDIS_HOST=$REDIS_HOST \
|
||||
-e REDIS_PASSWORD=$REDIS_PASSWORD \
|
||||
-e REDIS_PORT=$REDIS_PORT \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e LITELLM_LICENSE=$LITELLM_LICENSE \
|
||||
-e USE_DDTRACE=True \
|
||||
|
|
@ -2309,6 +2331,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -2335,10 +2362,9 @@ jobs:
|
|||
docker run -d \
|
||||
--restart on-failure \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e STORE_MODEL_IN_DB="True" \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e TEAM_METADATA_VALIDATION_SERVICE_URL=http://host.docker.internal:9414/validate \
|
||||
-e LITELLM_LICENSE=$LITELLM_LICENSE \
|
||||
|
|
@ -2388,6 +2414,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
# Remove Docker CLI installation since it's already available in machine executor
|
||||
|
|
@ -2410,12 +2441,11 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e REDIS_HOST=$REDIS_HOST \
|
||||
-e REDIS_PASSWORD=$REDIS_PASSWORD \
|
||||
-e REDIS_PORT=$REDIS_PORT \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
||||
-e FAKE_OPENAI_API_BASE=http://host.docker.internal:8190 \
|
||||
-e LITELLM_LICENSE=$LITELLM_LICENSE \
|
||||
|
|
@ -2472,6 +2502,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -2493,9 +2528,8 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
||||
-e GEMINI_API_KEY=$GEMINI_API_KEY \
|
||||
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
|
||||
|
|
@ -2563,6 +2597,11 @@ jobs:
|
|||
working_directory: ~/project
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes
|
||||
- setup_google_dns
|
||||
- install_uv
|
||||
|
|
@ -2585,9 +2624,8 @@ jobs:
|
|||
command: |
|
||||
docker run -d \
|
||||
-p 4000:4000 \
|
||||
-e LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true \
|
||||
-e DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/circle_test \
|
||||
-e LITELLM_MASTER_KEY="sk-1234" \
|
||||
-e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
|
||||
-e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
|
||||
-e RECORDER_ANTHROPIC_BASE_URL=http://host.docker.internal:8090/__recorder_upstream/api.anthropic.com \
|
||||
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
|
||||
|
|
@ -2613,7 +2651,7 @@ jobs:
|
|||
command: |
|
||||
mkdir -p test-results
|
||||
export LITELLM_PROXY_URL="http://localhost:4000"
|
||||
export LITELLM_API_KEY="sk-1234"
|
||||
export LITELLM_API_KEY="$LITELLM_MASTER_KEY"
|
||||
TEST_FILES=$(circleci tests glob "tests/proxy_e2e_anthropic_messages_tests/**/test_*.py")
|
||||
echo "$TEST_FILES" | circleci tests run \
|
||||
--verbose \
|
||||
|
|
@ -2676,6 +2714,11 @@ jobs:
|
|||
PROXY_LOGOUT_URL: "https://www.example.com"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes:
|
||||
category: client
|
||||
- setup_google_dns
|
||||
|
|
@ -2766,8 +2809,6 @@ jobs:
|
|||
- run:
|
||||
name: Start LiteLLM proxy
|
||||
environment:
|
||||
LITELLM_MASTER_KEY: "sk-1234"
|
||||
LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY: "true"
|
||||
MOCK_LLM_URL: "http://127.0.0.1:8090/v1"
|
||||
DISABLE_SCHEMA_UPDATE: "true"
|
||||
SERVER_ROOT_PATH: ""
|
||||
|
|
@ -2787,7 +2828,7 @@ jobs:
|
|||
name: Wait for proxy to be ready
|
||||
command: |
|
||||
for i in $(seq 1 60); do
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:4000/health -H "Authorization: Bearer sk-1234" 2>/dev/null || true)
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:4000/health -H "Authorization: Bearer $LITELLM_MASTER_KEY" 2>/dev/null || true)
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "Proxy is ready"
|
||||
exit 0
|
||||
|
|
@ -2834,6 +2875,11 @@ jobs:
|
|||
SERVER_ROOT_PATH: "/litellm"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Generate LiteLLM master key
|
||||
command: |
|
||||
key="$(openssl rand -hex 16)"
|
||||
printf 'export LITELLM_MASTER_KEY=sk-%s\n' "$key" >> "$BASH_ENV"
|
||||
- skip_if_unrelated_changes:
|
||||
category: client
|
||||
- setup_google_dns
|
||||
|
|
@ -2910,8 +2956,6 @@ jobs:
|
|||
- run:
|
||||
name: Start LiteLLM proxy under a server root path
|
||||
environment:
|
||||
LITELLM_MASTER_KEY: "sk-1234"
|
||||
LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY: "true"
|
||||
MOCK_LLM_URL: "http://127.0.0.1:8090/v1"
|
||||
DISABLE_SCHEMA_UPDATE: "true"
|
||||
# Output flows to this step's own log, so a boot crash is visible here
|
||||
|
|
@ -2926,7 +2970,7 @@ jobs:
|
|||
name: Wait for prefixed proxy to be ready
|
||||
command: |
|
||||
for i in $(seq 1 60); do
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -H "Authorization: Bearer sk-1234" http://127.0.0.1:4000/litellm/health 2>/dev/null || true)
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -H "Authorization: Bearer $LITELLM_MASTER_KEY" http://127.0.0.1:4000/litellm/health 2>/dev/null || true)
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "Prefixed proxy is ready"
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export PATH="$PWD/.venv/bin:$PATH"
|
|||
export PYTHONPATH="$PWD:$PWD/tests:$PWD/tests/e2e"
|
||||
export DATABASE_URL="postgresql://postgres:postgres@127.0.0.1:5432/circle_test"
|
||||
export REDIS_HOST=127.0.0.1 REDIS_PORT=6379
|
||||
export LITELLM_MASTER_KEY=sk-integration-master LITELLM_SALT_KEY=sk-integration-salt
|
||||
export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 16)" LITELLM_SALT_KEY=sk-integration-salt
|
||||
export LITELLM_MODE=PRODUCTION LITELLM_LOCAL_MODEL_COST_MAP=True
|
||||
export STORE_MODEL_IN_DB=True AWS_EC2_METADATA_DISABLED=true DO_NOT_TRACK=1
|
||||
export INTEGRATION_PROXY_URL=http://127.0.0.1:4000
|
||||
|
|
|
|||
|
|
@ -84,10 +84,6 @@ secret:
|
|||
- name: Langfuse test credentials in test_completion
|
||||
match: c39310f68cc3d3e22f7b298bb6353c4f45759adcc37080d8b7f4e535d3cfd7f4
|
||||
|
||||
# Test password "sk-1234" in e2e test fixtures - test fixture, not a real secret
|
||||
- name: Test password in e2e test fixtures
|
||||
match: ce32b547202e209ec1dd50107b64be4cfcf2eb15c3b4f8e9dc611ef747af634f
|
||||
|
||||
# === Preventive patterns for test keys (pattern-based) ===
|
||||
|
||||
# Test API keys (124 instances across 45 files)
|
||||
|
|
@ -108,4 +104,3 @@ secret:
|
|||
|
||||
- name: Short fake sk keys (1–9 digits only)
|
||||
match: \bsk-\d{1,9}\b
|
||||
|
||||
|
|
|
|||
3
.github/PULL_REQUEST_TEMPLATE/general.md
vendored
3
.github/PULL_REQUEST_TEMPLATE/general.md
vendored
|
|
@ -150,7 +150,7 @@ For each e2e test you added or changed, list the manual steps a reviewer can fol
|
|||
Example checklists:
|
||||
|
||||
- tests/e2e/quota_management/ratelimit/test_rate_limit_e2e.py::TestKeyRateLimits::test_rpm_limit_blocks_over_limit - a key allowed 2 requests a minute serves exactly 2 and refuses the 3rd
|
||||
- [ ] Generate a limited key: curl -X POST http://localhost:4000/key/generate -H "Authorization: Bearer sk-1234" -d '{"rpm_limit": 2}'
|
||||
- [ ] Generate a limited key: curl -X POST http://localhost:4000/key/generate -H "Authorization: Bearer $LITELLM_MASTER_KEY" -d '{"rpm_limit": 2}'
|
||||
- [ ] Send three /v1/chat/completions requests with that key inside one minute
|
||||
- [ ] Expect the first two to return 200 and the third to return 429 naming the rpm limit
|
||||
- [ ] Sanity check: this test makes sense to add and is not hand-wavey (e.g., assert actual expected spend instead of just spend > 0) or potentially flaky
|
||||
|
|
@ -164,4 +164,3 @@ Example checklists:
|
|||
## Final Attestation
|
||||
|
||||
- [ ] The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR
|
||||
|
||||
|
|
|
|||
7
.github/workflows/test-code-quality.yml
vendored
7
.github/workflows/test-code-quality.yml
vendored
|
|
@ -95,7 +95,9 @@ jobs:
|
|||
- name: test_e2e_metadata
|
||||
env:
|
||||
PYTHONPATH: tests/e2e
|
||||
run: uv run --no-sync pytest -q --noconftest -p no:cacheprovider -c /dev/null tests/code_coverage_tests/test_e2e_metadata.py tests/code_coverage_tests/test_e2e_junit_report.py
|
||||
run: |
|
||||
export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 16)"
|
||||
uv run --no-sync pytest -q --noconftest -p no:cacheprovider -c /dev/null tests/code_coverage_tests/test_e2e_metadata.py tests/code_coverage_tests/test_e2e_junit_report.py
|
||||
|
||||
- name: Check merge smoke harness
|
||||
run: uv run --no-sync pytest -q --noconftest -p no:cacheprovider -c /dev/null tests/code_coverage_tests/test_merge_smoke.py
|
||||
|
|
@ -163,6 +165,9 @@ jobs:
|
|||
- name: check_migrations_no_data_rewrites
|
||||
run: uv run --no-sync python ./tests/code_coverage_tests/check_migrations_no_data_rewrites.py
|
||||
|
||||
- name: check_no_publicly_known_master_key
|
||||
run: uv run --no-sync python ./tests/code_coverage_tests/check_no_publicly_known_master_key.py
|
||||
|
||||
- name: check_unbounded_in_lists (fails on findings not in the baseline)
|
||||
run: uv run --no-sync python ./tests/code_coverage_tests/check_unbounded_in_lists.py
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Standard patterns for test/mock keys and credentials in the LiteLLM codebase to
|
|||
## How GitGuardian Works
|
||||
|
||||
GitGuardian uses **machine learning and entropy analysis**, not just pattern matching:
|
||||
- **Low entropy** values (like `sk-1234`, `postgres`) are automatically ignored
|
||||
- **Low entropy** values (like `sk-test`, `postgres`) are automatically ignored
|
||||
- **High entropy** values (realistic-looking secrets) trigger detection
|
||||
- **Context-aware** detection understands code syntax like `os.environ["KEY"]`
|
||||
|
||||
|
|
@ -15,8 +15,8 @@ GitGuardian uses **machine learning and entropy analysis**, not just pattern mat
|
|||
These won't trigger GitGuardian's ML detector:
|
||||
|
||||
```python
|
||||
api_key = "sk-1234"
|
||||
api_key = "sk-12345"
|
||||
api_key = "sk-test"
|
||||
api_key = "sk-mock"
|
||||
database_password = "postgres"
|
||||
token = "test123"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
"\n",
|
||||
"These are **selected examples**. LiteLLM Proxy is **OpenAI-Compatible**, it works with any project that calls OpenAI. Just change the `base_url`, `api_key` and `model`.\n",
|
||||
"\n",
|
||||
"Set `LITELLM_MASTER_KEY` in the notebook environment to the same key configured on the proxy before running authenticated examples\n",
|
||||
"\n",
|
||||
"For more examples, [go here](https://docs.litellm.ai/docs/proxy/user_keys)\n",
|
||||
"\n",
|
||||
"To pass provider-specific args, [go here](https://docs.litellm.ai/docs/completion/provider_specific_params#proxy-usage)\n",
|
||||
|
|
@ -95,9 +97,10 @@
|
|||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from openai import OpenAI\n",
|
||||
"client = OpenAI(\n",
|
||||
" api_key=\"sk-1234\", # [OPTIONAL] set if you set one on proxy, else set \"\"\n",
|
||||
" api_key=os.environ[\"LITELLM_MASTER_KEY\"],\n",
|
||||
" base_url=\"http://0.0.0.0:4000\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
|
|
@ -298,14 +301,14 @@
|
|||
" engine=\"azure-gpt-3.5\", # model_name on litellm proxy\n",
|
||||
" temperature=0.0,\n",
|
||||
" azure_endpoint=\"http://0.0.0.0:4000\", # litellm proxy endpoint\n",
|
||||
" api_key=\"sk-1234\", # litellm proxy API Key\n",
|
||||
" api_key=os.environ[\"LITELLM_MASTER_KEY\"],\n",
|
||||
" api_version=\"2023-07-01-preview\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"embed_model = AzureOpenAIEmbedding(\n",
|
||||
" deployment_name=\"azure-embedding-model\",\n",
|
||||
" azure_endpoint=\"http://0.0.0.0:4000\",\n",
|
||||
" api_key=\"sk-1234\",\n",
|
||||
" api_key=os.environ[\"LITELLM_MASTER_KEY\"],\n",
|
||||
" api_version=\"2023-07-01-preview\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
|
|
@ -341,7 +344,7 @@
|
|||
"\n",
|
||||
"const model = new ChatOpenAI({\n",
|
||||
" modelName: \"gpt-4\",\n",
|
||||
" openAIApiKey: \"sk-1234\",\n",
|
||||
" openAIApiKey: process.env.LITELLM_MASTER_KEY,\n",
|
||||
" modelKwargs: {\"metadata\": \"hello world\"} // 👈 PASS Additional params here\n",
|
||||
"}, {\n",
|
||||
" basePath: \"http://0.0.0.0:4000\",\n",
|
||||
|
|
@ -372,7 +375,7 @@
|
|||
"const { OpenAI } = require('openai');\n",
|
||||
"\n",
|
||||
"const openai = new OpenAI({\n",
|
||||
" apiKey: \"sk-1234\", // This is the default and can be omitted\n",
|
||||
" apiKey: process.env.LITELLM_MASTER_KEY,\n",
|
||||
" baseURL: \"http://0.0.0.0:4000\"\n",
|
||||
"});\n",
|
||||
"\n",
|
||||
|
|
|
|||
7
cookbook/Proxy_Batch_Users.ipynb
vendored
7
cookbook/Proxy_Batch_Users.ipynb
vendored
|
|
@ -6,7 +6,9 @@
|
|||
"id": "680oRk1af-xJ"
|
||||
},
|
||||
"source": [
|
||||
"# Environment Setup"
|
||||
"# Environment Setup\n",
|
||||
"\n",
|
||||
"Set `LITELLM_MASTER_KEY` in the notebook environment to the same key configured on the proxy before running the cells"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -17,6 +19,7 @@
|
|||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import csv\n",
|
||||
"from typing import Optional\n",
|
||||
"import httpx\n",
|
||||
|
|
@ -24,7 +27,7 @@
|
|||
"import asyncio\n",
|
||||
"\n",
|
||||
"proxy_base_url = \"http://0.0.0.0:4000\" # 👈 SET TO PROXY URL\n",
|
||||
"master_key = \"sk-1234\" # 👈 SET TO PROXY MASTER KEY"
|
||||
"master_key = os.environ[\"LITELLM_MASTER_KEY\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ Set your environment variables:
|
|||
|
||||
```bash
|
||||
export ANTHROPIC_API_KEY="your-anthropic-api-key"
|
||||
export LITELLM_MASTER_KEY="sk-1234567890" # Generate a secure key
|
||||
export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 32)"
|
||||
```
|
||||
|
||||
## Step 2: Start Proxy
|
||||
|
|
@ -292,4 +292,3 @@ model_list:
|
|||
- [LiteLLM Documentation](https://docs.litellm.ai/)
|
||||
- [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code/overview)
|
||||
- [Anthropic's LiteLLM Configuration Guide](https://docs.anthropic.com/en/docs/claude-code/llm-gateway#litellm-configuration)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@ litellm --model claude-sonnet-4-20250514
|
|||
litellm --config config.yaml
|
||||
```
|
||||
|
||||
Generate a master key before starting the proxy:
|
||||
|
||||
```bash
|
||||
export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 32)"
|
||||
```
|
||||
|
||||
### 3. Run the chat
|
||||
|
||||
**Basic Agent (no MCP):**
|
||||
|
|
@ -58,7 +64,7 @@ Set these environment variables if needed:
|
|||
|
||||
```bash
|
||||
export LITELLM_PROXY_URL="http://localhost:4000"
|
||||
export LITELLM_API_KEY="sk-1234"
|
||||
export LITELLM_API_KEY="$LITELLM_MASTER_KEY"
|
||||
export LITELLM_MODEL="bedrock-claude-sonnet-4.5"
|
||||
```
|
||||
|
||||
|
|
@ -98,7 +104,7 @@ The key is pointing the Agent SDK to LiteLLM instead of directly to Anthropic:
|
|||
```python
|
||||
# Point to LiteLLM gateway (not Anthropic)
|
||||
os.environ["ANTHROPIC_BASE_URL"] = "http://localhost:4000"
|
||||
os.environ["ANTHROPIC_API_KEY"] = "sk-1234" # Your LiteLLM key
|
||||
os.environ["ANTHROPIC_API_KEY"] = os.environ["LITELLM_API_KEY"]
|
||||
|
||||
# Use any model configured in LiteLLM
|
||||
options = ClaudeAgentOptions(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class Config:
|
|||
LITELLM_PROXY_URL = os.getenv("LITELLM_PROXY_URL", "http://localhost:4000")
|
||||
|
||||
# LiteLLM API key (master key or virtual key)
|
||||
LITELLM_API_KEY = os.getenv("LITELLM_API_KEY", "sk-1234")
|
||||
LITELLM_API_KEY = os.environ["LITELLM_API_KEY"]
|
||||
|
||||
# Model name as configured in LiteLLM (e.g., "bedrock-claude-sonnet-4", "gpt-4", etc.)
|
||||
LITELLM_MODEL = os.getenv("LITELLM_MODEL", "bedrock-claude-sonnet-4.5")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import os
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
client = OpenAI(
|
||||
base_url="http://0.0.0.0:4000",
|
||||
api_key="sk-1234",
|
||||
api_key=os.environ["LITELLM_MASTER_KEY"],
|
||||
)
|
||||
|
||||
BEDROCK_BATCH_MODEL = "bedrock/batch-anthropic.claude-3-5-sonnet-20240620-v1:0"
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ Use LiteLLM Proxy MCP Gateway to call MCP tools.
|
|||
When using LiteLLM Proxy, you can use the same MCP tools across all your LLM providers.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import openai
|
||||
|
||||
client = openai.OpenAI(
|
||||
api_key="sk-1234", # paste your litellm proxy api key here
|
||||
api_key=os.environ["LITELLM_MASTER_KEY"],
|
||||
base_url="http://localhost:4000", # paste your litellm proxy base url here
|
||||
)
|
||||
print("Making API request to Responses API with MCP tools")
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@ pip install livekit-agents[xai] websockets
|
|||
```bash
|
||||
# With xAI
|
||||
export XAI_API_KEY="your-xai-key"
|
||||
export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 32)"
|
||||
litellm --config config.yaml --port 4000
|
||||
```
|
||||
|
||||
### 3. Run the voice agent
|
||||
|
||||
```bash
|
||||
export LITELLM_API_KEY="$LITELLM_MASTER_KEY"
|
||||
python main.py
|
||||
```
|
||||
|
||||
|
|
@ -32,7 +34,7 @@ Set these environment variables if needed:
|
|||
|
||||
```bash
|
||||
export LITELLM_PROXY_URL="http://localhost:4000"
|
||||
export LITELLM_API_KEY="sk-1234"
|
||||
export LITELLM_API_KEY="$LITELLM_MASTER_KEY"
|
||||
export LITELLM_MODEL="grok-voice-agent"
|
||||
```
|
||||
|
||||
|
|
@ -59,7 +61,7 @@ model_list:
|
|||
mode: realtime
|
||||
|
||||
general_settings:
|
||||
master_key: sk-1234
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
```
|
||||
|
||||
Then start: `litellm --config config.yaml --port 4000`
|
||||
|
|
@ -73,7 +75,7 @@ from livekit.plugins import xai
|
|||
|
||||
model = xai.realtime.RealtimeModel(
|
||||
voice="ara",
|
||||
api_key="sk-1234", # LiteLLM proxy key
|
||||
api_key=os.environ["LITELLM_MASTER_KEY"],
|
||||
base_url="http://localhost:4000", # Point to LiteLLM
|
||||
)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@ litellm_settings:
|
|||
drop_params: True
|
||||
|
||||
general_settings:
|
||||
master_key: sk-1234 # Change this to a secure key
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import websockets
|
|||
|
||||
# Configuration
|
||||
PROXY_URL = os.getenv("LITELLM_PROXY_URL", "http://localhost:4000")
|
||||
API_KEY = os.getenv("LITELLM_API_KEY", "sk-1234")
|
||||
API_KEY = os.environ["LITELLM_API_KEY"]
|
||||
MODEL = os.getenv("LITELLM_MODEL", "grok-voice-agent")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ litellm_settings:
|
|||
context_window_fallbacks: [{"gpt-3.5-turbo": ["gpt-3.5-turbo-large"]}]
|
||||
|
||||
general_settings:
|
||||
master_key: sk-1234 # [OPTIONAL] Use to enforce auth on proxy. See - https://docs.litellm.ai/docs/proxy/virtual_keys
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
store_model_in_db: True
|
||||
proxy_budget_rescheduler_min_time: 60
|
||||
proxy_budget_rescheduler_max_time: 64
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ Step 2: reads `model_list` and loops through all models
|
|||
Step 3: calls `<proxy-base-url>/model/new` for each model
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import yaml
|
||||
import requests
|
||||
|
||||
|
|
@ -89,7 +91,7 @@ def migrate_models(config_file, proxy_base_url):
|
|||
# Usage
|
||||
config_file = "config.yaml"
|
||||
proxy_base_url = "http://0.0.0.0:4000"
|
||||
master_key = "sk-1234"
|
||||
master_key = os.environ["LITELLM_MASTER_KEY"]
|
||||
print(f"config_file: {config_file}")
|
||||
print(f"proxy_base_url: {proxy_base_url}")
|
||||
migrate_models(config_file, proxy_base_url)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import base64
|
||||
import os
|
||||
|
||||
from openai import OpenAI
|
||||
import time
|
||||
|
||||
client = OpenAI(base_url="http://0.0.0.0:4001", api_key="sk-1234")
|
||||
client = OpenAI(base_url="http://0.0.0.0:4001", api_key=os.environ["LITELLM_MASTER_KEY"])
|
||||
|
||||
|
||||
# Function to encode the image
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Databricks Notebook with MLFlow AutoLogging for LiteLLM Proxy calls\n"
|
||||
"# Databricks Notebook with MLFlow AutoLogging for LiteLLM Proxy calls\n",
|
||||
"\n",
|
||||
"Set `LITELLM_PROXY_API_KEY` in the notebook environment to a key accepted by the proxy before running the model cell\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -160,11 +162,13 @@
|
|||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"model = ChatOpenAI(\n",
|
||||
" openai_api_base=\"LITELLM_PROXY_BASE_URL\", # e.g.: http://0.0.0.0:4000\n",
|
||||
" model = \"gpt-3.5-turbo\", # LITELLM 'model_name'\n",
|
||||
" temperature=0.1, \n",
|
||||
" api_key=\"LITELLM_PROXY_API_KEY\" # e.g.: \"sk-1234\"\n",
|
||||
" api_key=os.environ[\"LITELLM_PROXY_API_KEY\"]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ litellm --config config.yaml
|
|||
```bash
|
||||
curl http://0.0.0.0:4000/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"prompt_id": "hello-world-prompt",
|
||||
|
|
@ -290,4 +290,3 @@ Before deploying to production:
|
|||
## Questions?
|
||||
|
||||
This is a reference implementation for the LiteLLM Generic Prompt Management API. For questions or issues, please open an issue on the [LiteLLM GitHub repository](https://github.com/BerriAI/litellm).
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Prerequisites:
|
|||
- websockets installed: pip install websockets
|
||||
|
||||
Usage:
|
||||
export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 32)"
|
||||
python nova_sonic_realtime.py
|
||||
"""
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ CHUNK_SIZE = 1024
|
|||
|
||||
# LiteLLM proxy configuration
|
||||
LITELLM_PROXY_URL = "ws://localhost:4000/v1/realtime?model=bedrock-sonic"
|
||||
LITELLM_API_KEY = "sk-12345" # Your LiteLLM API key
|
||||
LITELLM_API_KEY = os.environ["LITELLM_MASTER_KEY"]
|
||||
|
||||
|
||||
class RealtimeClient:
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class VeoVideoGenerator:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
api_key: str,
|
||||
base_url: str = "http://localhost:4000/gemini/v1beta",
|
||||
api_key: str = "sk-1234",
|
||||
):
|
||||
"""
|
||||
Initialize the Veo video generator.
|
||||
|
|
@ -274,12 +274,12 @@ def main():
|
|||
|
||||
Configure these environment variables:
|
||||
- LITELLM_BASE_URL: Your LiteLLM proxy URL (default: http://localhost:4000/gemini/v1beta)
|
||||
- LITELLM_API_KEY: Your LiteLLM API key (default: sk-1234)
|
||||
- LITELLM_API_KEY: API key for LiteLLM proxy authentication
|
||||
"""
|
||||
|
||||
# Configuration from environment or defaults
|
||||
base_url = os.getenv("LITELLM_BASE_URL", "http://localhost:4000/gemini/v1beta")
|
||||
api_key = os.getenv("LITELLM_API_KEY", "sk-1234")
|
||||
api_key = os.environ["LITELLM_API_KEY"]
|
||||
|
||||
print("🚀 Starting Veo Video Generation Example")
|
||||
print(f"📡 Using LiteLLM proxy at: {base_url}")
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ docker build --build-arg LITELLM_RELEASE_TAG="$LITELLM_RELEASE_TAG" \
|
|||
docker compose -f docker/docker-compose.tracing.yml up -d --build
|
||||
```
|
||||
|
||||
Open `http://localhost:4002/ui/` and sign in as `admin` with password `sk-1234`. Go to **Lens > Investigations > Connect worker**, choose a model and monthly budget, then **Get install command**. Expand **Using Docker Compose or Helm?** and copy the worker token. In the same terminal, run:
|
||||
Open `http://localhost:4002/ui/` and sign in as `admin` with the key saved in `.lens-dev/master_key`. Go to **Lens > Investigations > Connect worker**, choose a model and monthly budget, then **Get install command**. Expand **Using Docker Compose or Helm?** and copy the worker token. In the same terminal, run:
|
||||
|
||||
```bash
|
||||
export LITELLM_URL=http://litellm:4000
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ services:
|
|||
LITELLM_RELEASE_TAG: ${LITELLM_RELEASE_TAG:-}
|
||||
command: ["--config", "/app/tracing-config.yaml", "--port", "4000"]
|
||||
environment:
|
||||
LITELLM_MASTER_KEY: sk-1234
|
||||
LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY: "true"
|
||||
LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY:?set LITELLM_MASTER_KEY}
|
||||
LITELLM_SALT_KEY: sk-local-tracing-salt-key
|
||||
DATABASE_URL: postgresql://litellm:litellm@db:5432/litellm
|
||||
STORE_MODEL_IN_DB: "True"
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ async def new_project(
|
|||
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/project/new' \\
|
||||
--header 'Authorization: Bearer sk-1234' \\
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data '{
|
||||
"project_alias": "flight-search-assistant",
|
||||
|
|
@ -460,7 +460,7 @@ async def new_project(
|
|||
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/project/new' \\
|
||||
--header 'Authorization: Bearer sk-1234' \\
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data '{
|
||||
"project_alias": "hotel-recommendations",
|
||||
|
|
@ -648,7 +648,7 @@ async def update_project(
|
|||
Example:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/project/update' \\
|
||||
--header 'Authorization: Bearer sk-1234' \\
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data '{
|
||||
"project_id": "project-123",
|
||||
|
|
@ -876,7 +876,7 @@ async def delete_project(
|
|||
Example:
|
||||
```bash
|
||||
curl --location --request DELETE 'http://0.0.0.0:4000/project/delete' \\
|
||||
--header 'Authorization: Bearer sk-1234' \\
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data '{
|
||||
"project_ids": ["project-123", "project-456"]
|
||||
|
|
@ -983,7 +983,7 @@ async def project_info(
|
|||
Example:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/project/info?project_id=project-123' \\
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
|
@ -1052,7 +1052,7 @@ async def list_projects(
|
|||
Example:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/project/list' \\
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ async fn enforces_configured_keys_without_exposing_secrets(
|
|||
#[rstest]
|
||||
fn hash_token_matches_python_sha256_hexdigest() {
|
||||
assert_eq!(
|
||||
hash_token("sk-1234"),
|
||||
"88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b"
|
||||
hash_token("sk-9876"),
|
||||
"595b23af2e99cee580245f388d3244a39247a25a3846e898e9c78841f8471a3e"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ class LoggingCallbackManager:
|
|||
callback_type: generic_api
|
||||
endpoint: https://webhook-test.com/30343bc33591bc5e6dc44217ceae3e0a
|
||||
headers:
|
||||
Authorization: Bearer sk-1234
|
||||
Authorization: Bearer $LITELLM_MASTER_KEY
|
||||
"""
|
||||
callback_config: Final = litellm.callback_settings.get(callback)
|
||||
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ def _redact_sequence(values: Sequence[object], depth: int) -> Sequence[object]:
|
|||
"""
|
||||
masker = SensitiveDataMasker()
|
||||
data = {
|
||||
"api_key": "sk-1234567890abcdef",
|
||||
"api_key": "sk-9876543210abcdef",
|
||||
"redis_password": "very_secret_pass",
|
||||
"port": 6379,
|
||||
"tags": ["East US 2", "production", "test"]
|
||||
|
|
|
|||
|
|
@ -1241,7 +1241,7 @@
|
|||
"paths": {
|
||||
"/access_group/list": {
|
||||
"get": {
|
||||
"description": "List all access groups.\n\nReturns a list of all access groups with their model names, deployment counts, shared budget\nand the spend drawn against it.\n\nExample:\n```bash\ncurl -X GET 'http://localhost:4000/access_group/list' \\\n -H 'Authorization: Bearer sk-1234'\n```\n\nReturns:\n- ListAccessGroupsResponse with all access groups",
|
||||
"description": "List all access groups.\n\nReturns a list of all access groups with their model names, deployment counts, shared budget\nand the spend drawn against it.\n\nExample:\n```bash\ncurl -X GET 'http://localhost:4000/access_group/list' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```\n\nReturns:\n- ListAccessGroupsResponse with all access groups",
|
||||
"operationId": "list_access_groups_access_group_list_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -1268,7 +1268,7 @@
|
|||
},
|
||||
"/access_group/new": {
|
||||
"post": {
|
||||
"description": "Create a new access group containing multiple model names.\n\nAn access group is a named collection of model groups that can be referenced\nby teams/keys for simplified access control.\n\nExample:\n```bash\ncurl -X POST 'http://localhost:4000/access_group/new' \\\n -H 'Authorization: Bearer sk-1234' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"access_group\": \"production-models\",\n \"model_names\": [\"gpt-4\", \"claude-3-opus\", \"gemini-pro\"]\n }'\n```\n\nParameters:\n- access_group: str - The access group name (e.g., \"production-models\")\n- model_names: List[str] - List of existing model groups to include\n\nReturns:\n- NewModelGroupResponse with the created access group details\n\nRaises:\n- HTTPException 400: If any model names don't exist\n- HTTPException 500: If database operations fail",
|
||||
"description": "Create a new access group containing multiple model names.\n\nAn access group is a named collection of model groups that can be referenced\nby teams/keys for simplified access control.\n\nExample:\n```bash\ncurl -X POST 'http://localhost:4000/access_group/new' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"access_group\": \"production-models\",\n \"model_names\": [\"gpt-4\", \"claude-3-opus\", \"gemini-pro\"]\n }'\n```\n\nParameters:\n- access_group: str - The access group name (e.g., \"production-models\")\n- model_names: List[str] - List of existing model groups to include\n\nReturns:\n- NewModelGroupResponse with the created access group details\n\nRaises:\n- HTTPException 400: If any model names don't exist\n- HTTPException 500: If database operations fail",
|
||||
"operationId": "create_model_group_access_group_new_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
|
|
@ -1315,7 +1315,7 @@
|
|||
},
|
||||
"/access_group/{access_group}/budget": {
|
||||
"delete": {
|
||||
"description": "Clear the shared budget of an access group, leaving the group itself in place.\n\nExample:\n```bash\ncurl -X DELETE 'http://localhost:4000/access_group/production-models/budget' \\\n -H 'Authorization: Bearer sk-1234'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- DeleteAccessGroupBudgetResponse; budget_deleted is false when there was nothing to clear\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"description": "Clear the shared budget of an access group, leaving the group itself in place.\n\nExample:\n```bash\ncurl -X DELETE 'http://localhost:4000/access_group/production-models/budget' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- DeleteAccessGroupBudgetResponse; budget_deleted is false when there was nothing to clear\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"operationId": "delete_access_group_budget_access_group__access_group__budget_delete",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1361,7 +1361,7 @@
|
|||
]
|
||||
},
|
||||
"get": {
|
||||
"description": "Get the shared budget of an access group, and the spend drawn against it.\n\nExample:\n```bash\ncurl -X GET 'http://localhost:4000/access_group/production-models/budget' \\\n -H 'Authorization: Bearer sk-1234'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- AccessGroupBudgetResponse; budget is null when the group has no budget set\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"description": "Get the shared budget of an access group, and the spend drawn against it.\n\nExample:\n```bash\ncurl -X GET 'http://localhost:4000/access_group/production-models/budget' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- AccessGroupBudgetResponse; budget is null when the group has no budget set\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"operationId": "get_access_group_budget_access_group__access_group__budget_get",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1407,7 +1407,7 @@
|
|||
]
|
||||
},
|
||||
"put": {
|
||||
"description": "Set or replace the shared budget of an access group. Idempotent.\n\nEvery key that can reach a model in the group draws from this one budget.\n\nExample:\n```bash\ncurl -X PUT 'http://localhost:4000/access_group/production-models/budget' \\\n -H 'Authorization: Bearer sk-1234' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"max_budget\": 100.0,\n \"budget_duration\": \"30d\"\n }'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n- max_budget: Optional[float] - Requests fail once the group's shared spend exceeds this\n- soft_budget: Optional[float] - Fires an alert when reached; requests still succeed\n- budget_duration: Optional[str] - Frequency of resetting the group's spend (e.g. '30d')\n- budget_id: Optional[str] - Link an existing budget instead of creating one\n\nReturns:\n- AccessGroupBudgetResponse with the stored budget and current spend\n\nRaises:\n- HTTPException 400: If no budget field is given, or budget_duration cannot be parsed\n- HTTPException 404: If access group not found",
|
||||
"description": "Set or replace the shared budget of an access group. Idempotent.\n\nEvery key that can reach a model in the group draws from this one budget.\n\nExample:\n```bash\ncurl -X PUT 'http://localhost:4000/access_group/production-models/budget' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"max_budget\": 100.0,\n \"budget_duration\": \"30d\"\n }'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n- max_budget: Optional[float] - Requests fail once the group's shared spend exceeds this\n- soft_budget: Optional[float] - Fires an alert when reached; requests still succeed\n- budget_duration: Optional[str] - Frequency of resetting the group's spend (e.g. '30d')\n- budget_id: Optional[str] - Link an existing budget instead of creating one\n\nReturns:\n- AccessGroupBudgetResponse with the stored budget and current spend\n\nRaises:\n- HTTPException 400: If no budget field is given, or budget_duration cannot be parsed\n- HTTPException 404: If access group not found",
|
||||
"operationId": "set_access_group_budget_access_group__access_group__budget_put",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1465,7 +1465,7 @@
|
|||
},
|
||||
"/access_group/{access_group}/delete": {
|
||||
"delete": {
|
||||
"description": "Delete an access group.\n\nRemoves the access group from all deployments that have it.\n\nExample:\n```bash\ncurl -X DELETE 'http://localhost:4000/access_group/production-models/delete' \\\n -H 'Authorization: Bearer sk-1234'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- DeleteModelGroupResponse with deletion details\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"description": "Delete an access group.\n\nRemoves the access group from all deployments that have it.\n\nExample:\n```bash\ncurl -X DELETE 'http://localhost:4000/access_group/production-models/delete' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- DeleteModelGroupResponse with deletion details\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"operationId": "delete_access_group_access_group__access_group__delete_delete",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1513,7 +1513,7 @@
|
|||
},
|
||||
"/access_group/{access_group}/info": {
|
||||
"get": {
|
||||
"description": "Get information about a specific access group.\n\nExample:\n```bash\ncurl -X GET 'http://localhost:4000/access_group/production-models/info' \\\n -H 'Authorization: Bearer sk-1234'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- AccessGroupInfo with the access group details, its shared budget and its spend\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"description": "Get information about a specific access group.\n\nExample:\n```bash\ncurl -X GET 'http://localhost:4000/access_group/production-models/info' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n\nReturns:\n- AccessGroupInfo with the access group details, its shared budget and its spend\n\nRaises:\n- HTTPException 404: If access group not found",
|
||||
"operationId": "get_access_group_info_access_group__access_group__info_get",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -1561,7 +1561,7 @@
|
|||
},
|
||||
"/access_group/{access_group}/update": {
|
||||
"put": {
|
||||
"description": "Update an access group's model names.\n\nThis will:\n1. Remove the access group from all current deployments\n2. Add the access group to all deployments for the new model_names list\n\nExample:\n```bash\ncurl -X PUT 'http://localhost:4000/access_group/production-models/update' \\\n -H 'Authorization: Bearer sk-1234' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"model_names\": [\"gpt-4\", \"claude-3-sonnet\"]\n }'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n- model_names: List[str] - New list of model groups to include\n\nReturns:\n- NewModelGroupResponse with the updated access group details\n\nRaises:\n- HTTPException 400: If any model names don't exist\n- HTTPException 404: If access group not found",
|
||||
"description": "Update an access group's model names.\n\nThis will:\n1. Remove the access group from all current deployments\n2. Add the access group to all deployments for the new model_names list\n\nExample:\n```bash\ncurl -X PUT 'http://localhost:4000/access_group/production-models/update' \\\n -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"model_names\": [\"gpt-4\", \"claude-3-sonnet\"]\n }'\n```\n\nParameters:\n- access_group: str - The access group name (URL path parameter)\n- model_names: List[str] - New list of model groups to include\n\nReturns:\n- NewModelGroupResponse with the updated access group details\n\nRaises:\n- HTTPException 400: If any model names don't exist\n- HTTPException 404: If access group not found",
|
||||
"operationId": "update_access_group_access_group__access_group__update_put",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -26692,7 +26692,7 @@
|
|||
},
|
||||
"/cursor/chat/completions": {
|
||||
"post": {
|
||||
"description": "Cursor BYOK endpoint. Accepts both request shapes Cursor sends to its OpenAI-compatible\nbase URL and always answers in chat completions format.\n\nCursor agent mode sends Responses API format bodies (`input`, flat tool defs, `reasoning`,\ncustom tools) to the chat/completions path while expecting chat completions responses;\nthose are routed through the Responses API pipeline and converted back. Genuine chat\ncompletions bodies (`messages` present) are routed through the standard chat completions\npipeline, after normalizing each level of the `tools` array and `tool_choice` to the chat\ncompletions shapes OpenAI requires. Cursor mixes Responses API shapes into chat bodies\nper level, independently: a flat tool def (`{\"type\": \"custom\", \"name\": \"ApplyPatch\", ...}`)\ngets nested under `custom`, and a flat grammar format\n(`{\"type\": \"grammar\", \"definition\", \"syntax\"}`) gets wrapped as\n`{\"type\": \"grammar\", \"grammar\": {...}}` wherever it appears, including inside tool defs\nCursor already sent pre-nested.\n\n```bash\ncurl -X POST http://localhost:4000/cursor/chat/completions -H \"Content-Type: application/json\" -H \"Authorization: Bearer sk-1234\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": [{\"role\": \"user\", \"content\": \"Hello\"}]\n}'\nResponds back in chat completions format.\n```",
|
||||
"description": "Cursor BYOK endpoint. Accepts both request shapes Cursor sends to its OpenAI-compatible\nbase URL and always answers in chat completions format.\n\nCursor agent mode sends Responses API format bodies (`input`, flat tool defs, `reasoning`,\ncustom tools) to the chat/completions path while expecting chat completions responses;\nthose are routed through the Responses API pipeline and converted back. Genuine chat\ncompletions bodies (`messages` present) are routed through the standard chat completions\npipeline, after normalizing each level of the `tools` array and `tool_choice` to the chat\ncompletions shapes OpenAI requires. Cursor mixes Responses API shapes into chat bodies\nper level, independently: a flat tool def (`{\"type\": \"custom\", \"name\": \"ApplyPatch\", ...}`)\ngets nested under `custom`, and a flat grammar format\n(`{\"type\": \"grammar\", \"definition\", \"syntax\"}`) gets wrapped as\n`{\"type\": \"grammar\", \"grammar\": {...}}` wherever it appears, including inside tool defs\nCursor already sent pre-nested.\n\n```bash\ncurl -X POST http://localhost:4000/cursor/chat/completions -H \"Content-Type: application/json\" -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": [{\"role\": \"user\", \"content\": \"Hello\"}]\n}'\nResponds back in chat completions format.\n```",
|
||||
"operationId": "cursor_chat_completions_cursor_chat_completions_post",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -28532,7 +28532,7 @@
|
|||
},
|
||||
"/openai/deployments/{model}/chat/completions": {
|
||||
"post": {
|
||||
"description": "Follows the exact same API spec as `OpenAI's Chat API https://platform.openai.com/docs/api-reference/chat`\n\n```bash\ncurl -X POST http://localhost:4000/v1/chat/completions \n-H \"Content-Type: application/json\" \n-H \"Authorization: Bearer sk-1234\" \n-d '{\n \"model\": \"gpt-4o\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n}'\n```",
|
||||
"description": "Follows the exact same API spec as `OpenAI's Chat API https://platform.openai.com/docs/api-reference/chat`\n\n```bash\ncurl -X POST http://localhost:4000/v1/chat/completions \n-H \"Content-Type: application/json\" \n-H \"Authorization: Bearer $LITELLM_MASTER_KEY\" \n-d '{\n \"model\": \"gpt-4o\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n}'\n```",
|
||||
"operationId": "chat_completion_openai_deployments__model__chat_completions_post",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -28665,7 +28665,7 @@
|
|||
},
|
||||
"/openai/deployments/{model}/completions": {
|
||||
"post": {
|
||||
"description": "Follows the exact same API spec as `OpenAI's Completions API https://platform.openai.com/docs/api-reference/completions`\n\n```bash\ncurl -X POST http://localhost:4000/v1/completions \n-H \"Content-Type: application/json\" \n-H \"Authorization: Bearer sk-1234\" \n-d '{\n \"model\": \"gpt-3.5-turbo-instruct\",\n \"prompt\": \"Once upon a time\",\n \"max_tokens\": 50,\n \"temperature\": 0.7\n}'\n```",
|
||||
"description": "Follows the exact same API spec as `OpenAI's Completions API https://platform.openai.com/docs/api-reference/completions`\n\n```bash\ncurl -X POST http://localhost:4000/v1/completions \n-H \"Content-Type: application/json\" \n-H \"Authorization: Bearer $LITELLM_MASTER_KEY\" \n-d '{\n \"model\": \"gpt-3.5-turbo-instruct\",\n \"prompt\": \"Once upon a time\",\n \"max_tokens\": 50,\n \"temperature\": 0.7\n}'\n```",
|
||||
"operationId": "completion_openai_deployments__model__completions_post",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -28718,7 +28718,7 @@
|
|||
},
|
||||
"/openai/deployments/{model}/embeddings": {
|
||||
"post": {
|
||||
"description": "Follows the exact same API spec as `OpenAI's Embeddings API https://platform.openai.com/docs/api-reference/embeddings`\n\n```bash\ncurl -X POST http://localhost:4000/v1/embeddings \n-H \"Content-Type: application/json\" \n-H \"Authorization: Bearer sk-1234\" \n-d '{\n \"model\": \"text-embedding-ada-002\",\n \"input\": \"The quick brown fox jumps over the lazy dog\"\n}'\n```",
|
||||
"description": "Follows the exact same API spec as `OpenAI's Embeddings API https://platform.openai.com/docs/api-reference/embeddings`\n\n```bash\ncurl -X POST http://localhost:4000/v1/embeddings \n-H \"Content-Type: application/json\" \n-H \"Authorization: Bearer $LITELLM_MASTER_KEY\" \n-d '{\n \"model\": \"text-embedding-ada-002\",\n \"input\": \"The quick brown fox jumps over the lazy dog\"\n}'\n```",
|
||||
"operationId": "embeddings_openai_deployments__model__embeddings_post",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -28771,7 +28771,7 @@
|
|||
},
|
||||
"/openai/deployments/{model}/images/edits": {
|
||||
"post": {
|
||||
"description": "Follows the OpenAI Images API spec: https://platform.openai.com/docs/api-reference/images/create\n\n```bash\ncurl -s -D >(grep -i x-request-id >&2) -o >(jq -r '.data[0].b64_json' | base64 --decode > gift-basket.png) -X POST \"http://localhost:4000/v1/images/edits\" -H \"Authorization: Bearer sk-1234\" -F \"model=gpt-image-1\" -F \"image[]=@soap.png\" -F 'prompt=Create a studio ghibli image of this'\n```",
|
||||
"description": "Follows the OpenAI Images API spec: https://platform.openai.com/docs/api-reference/images/create\n\n```bash\ncurl -s -D >(grep -i x-request-id >&2) -o >(jq -r '.data[0].b64_json' | base64 --decode > gift-basket.png) -X POST \"http://localhost:4000/v1/images/edits\" -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" -F \"model=gpt-image-1\" -F \"image[]=@soap.png\" -F 'prompt=Create a studio ghibli image of this'\n```",
|
||||
"operationId": "image_edit_api_openai_deployments__model__images_edits_post",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -28957,7 +28957,7 @@
|
|||
},
|
||||
"/openai/v1/responses": {
|
||||
"post": {
|
||||
"description": "Follows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses\n\nSupports background mode with polling_via_cache for partial response retrieval.\nWhen background=true and polling_via_cache is enabled, returns a polling_id immediately\nand streams the response in the background, updating Redis cache.\n\n```bash\n# Normal request\ncurl -X POST http://localhost:4000/v1/responses -H \"Content-Type: application/json\" -H \"Authorization: Bearer sk-1234\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": \"Tell me about AI\"\n}'\n\n# Background request with polling\ncurl -X POST http://localhost:4000/v1/responses -H \"Content-Type: application/json\" -H \"Authorization: Bearer sk-1234\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": \"Tell me about AI\",\n \"background\": true\n}'\n```",
|
||||
"description": "Follows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses\n\nSupports background mode with polling_via_cache for partial response retrieval.\nWhen background=true and polling_via_cache is enabled, returns a polling_id immediately\nand streams the response in the background, updating Redis cache.\n\n```bash\n# Normal request\ncurl -X POST http://localhost:4000/v1/responses -H \"Content-Type: application/json\" -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": \"Tell me about AI\"\n}'\n\n# Background request with polling\ncurl -X POST http://localhost:4000/v1/responses -H \"Content-Type: application/json\" -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": \"Tell me about AI\",\n \"background\": true\n}'\n```",
|
||||
"operationId": "responses_api_openai_v1_responses_post",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -28990,7 +28990,7 @@
|
|||
},
|
||||
"/openai/v1/responses/compact": {
|
||||
"post": {
|
||||
"description": "Compact a response by running a compaction pass over a conversation.\n\nReturns encrypted, opaque items that can be used to reduce context size.\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/compact\n\n```bash\ncurl -X POST http://localhost:4000/v1/responses/compact -H \"Content-Type: application/json\" -H \"Authorization: Bearer sk-1234\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": [{\"role\": \"user\", \"content\": \"Hello\"}]\n}'\n```",
|
||||
"description": "Compact a response by running a compaction pass over a conversation.\n\nReturns encrypted, opaque items that can be used to reduce context size.\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/compact\n\n```bash\ncurl -X POST http://localhost:4000/v1/responses/compact -H \"Content-Type: application/json\" -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": [{\"role\": \"user\", \"content\": \"Hello\"}]\n}'\n```",
|
||||
"operationId": "compact_response_openai_v1_responses_compact_post",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -29015,7 +29015,7 @@
|
|||
},
|
||||
"/openai/v1/responses/input_tokens": {
|
||||
"post": {
|
||||
"description": "Count the input tokens of a Responses API request without calling the model.\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/input-tokens\n\n```bash\ncurl -X POST http://localhost:4000/v1/responses/input_tokens -H \"Content-Type: application/json\" -H \"Authorization: Bearer sk-1234\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": \"Hello, how are you?\"\n}'\n```\n\nReturns: `{\"object\": \"response.input_tokens\", \"input_tokens\": <count>}`",
|
||||
"description": "Count the input tokens of a Responses API request without calling the model.\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/input-tokens\n\n```bash\ncurl -X POST http://localhost:4000/v1/responses/input_tokens -H \"Content-Type: application/json\" -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" -d '{\n \"model\": \"gpt-4o\",\n \"input\": \"Hello, how are you?\"\n}'\n```\n\nReturns: `{\"object\": \"response.input_tokens\", \"input_tokens\": <count>}`",
|
||||
"operationId": "responses_input_tokens_openai_v1_responses_input_tokens_post",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -29040,7 +29040,7 @@
|
|||
},
|
||||
"/openai/v1/responses/{response_id}": {
|
||||
"delete": {
|
||||
"description": "Delete a response by ID.\n\nSupports both:\n- Polling IDs (litellm_poll_*): Deletes from Redis cache\n- Provider response IDs: Passes through to provider API\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/delete\n\n```bash\ncurl -X DELETE http://localhost:4000/v1/responses/resp_abc123 -H \"Authorization: Bearer sk-1234\"\n```",
|
||||
"description": "Delete a response by ID.\n\nSupports both:\n- Polling IDs (litellm_poll_*): Deletes from Redis cache\n- Provider response IDs: Passes through to provider API\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/delete\n\n```bash\ncurl -X DELETE http://localhost:4000/v1/responses/resp_abc123 -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```",
|
||||
"operationId": "delete_response_openai_v1_responses__response_id__delete",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -29086,7 +29086,7 @@
|
|||
]
|
||||
},
|
||||
"get": {
|
||||
"description": "Get a response by ID.\n\nSupports both:\n- Polling IDs (litellm_poll_*): Returns cumulative cached content from background responses\n- Provider response IDs: Passes through to provider API\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/get\n\n```bash\n# Get polling response\ncurl -X GET http://localhost:4000/v1/responses/litellm_poll_abc123 -H \"Authorization: Bearer sk-1234\"\n\n# Get provider response\ncurl -X GET http://localhost:4000/v1/responses/resp_abc123 -H \"Authorization: Bearer sk-1234\"\n```",
|
||||
"description": "Get a response by ID.\n\nSupports both:\n- Polling IDs (litellm_poll_*): Returns cumulative cached content from background responses\n- Provider response IDs: Passes through to provider API\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/get\n\n```bash\n# Get polling response\ncurl -X GET http://localhost:4000/v1/responses/litellm_poll_abc123 -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n\n# Get provider response\ncurl -X GET http://localhost:4000/v1/responses/resp_abc123 -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```",
|
||||
"operationId": "get_response_openai_v1_responses__response_id__get",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -29134,7 +29134,7 @@
|
|||
},
|
||||
"/openai/v1/responses/{response_id}/cancel": {
|
||||
"post": {
|
||||
"description": "Cancel a response by ID.\n\nSupports both:\n- Polling IDs (litellm_poll_*): Cancels background response and updates status in Redis\n- Provider response IDs: Passes through to provider API\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/cancel\n\n```bash\n# Cancel polling response\ncurl -X POST http://localhost:4000/v1/responses/litellm_poll_abc123/cancel -H \"Authorization: Bearer sk-1234\"\n\n# Cancel provider response\ncurl -X POST http://localhost:4000/v1/responses/resp_abc123/cancel -H \"Authorization: Bearer sk-1234\"\n```",
|
||||
"description": "Cancel a response by ID.\n\nSupports both:\n- Polling IDs (litellm_poll_*): Cancels background response and updates status in Redis\n- Provider response IDs: Passes through to provider API\n\nFollows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/cancel\n\n```bash\n# Cancel polling response\ncurl -X POST http://localhost:4000/v1/responses/litellm_poll_abc123/cancel -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n\n# Cancel provider response\ncurl -X POST http://localhost:4000/v1/responses/resp_abc123/cancel -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```",
|
||||
"operationId": "cancel_response_openai_v1_responses__response_id__cancel_post",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -56443,7 +56443,7 @@
|
|||
"paths": {
|
||||
"/v1/indexes": {
|
||||
"get": {
|
||||
"description": "List all vector store indexes. Proxy admin only.\n\n```bash\ncurl -L -X GET 'http://0.0.0.0:4000/v1/indexes' -H 'Authorization: Bearer sk-1234'\n```",
|
||||
"description": "List all vector store indexes. Proxy admin only.\n\n```bash\ncurl -L -X GET 'http://0.0.0.0:4000/v1/indexes' -H \"Authorization: Bearer $LITELLM_MASTER_KEY\"\n```",
|
||||
"operationId": "index_list_v1_indexes_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -56468,7 +56468,7 @@
|
|||
]
|
||||
},
|
||||
"post": {
|
||||
"description": "Create an index. Just writes the index to the database.\n\n```bash\ncurl -L -X POST 'http://0.0.0.0:4000/v1/indexes' -H 'Content-Type: application/json' -H 'Authorization: Bearer sk-1234' -d '{\n \"index_name\": \"dall-e-3\",\n \"litellm_params\": {\n \"vector_store_index\": \"real-index-name\",\n \"vector_store_name\": \"azure-ai-search\"\n }\n }'\n```",
|
||||
"description": "Create an index. Just writes the index to the database.\n\n```bash\ncurl -L -X POST 'http://0.0.0.0:4000/v1/indexes' -H 'Content-Type: application/json' -H \"Authorization: Bearer $LITELLM_MASTER_KEY\" -d '{\n \"index_name\": \"dall-e-3\",\n \"litellm_params\": {\n \"vector_store_index\": \"real-index-name\",\n \"vector_store_name\": \"azure-ai-search\"\n }\n }'\n```",
|
||||
"operationId": "index_create_v1_indexes_post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
|
|
|
|||
|
|
@ -731,7 +731,7 @@ def route_in_additonal_public_routes(current_route: str):
|
|||
|
||||
```yaml
|
||||
general_settings:
|
||||
master_key: sk-1234
|
||||
master_key: os.environ/LITELLM_MASTER_KEY
|
||||
public_routes: ["LiteLLMRoutes.public_routes", "/spend/calculate", "/api/*"]
|
||||
```
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import atexit
|
||||
import hashlib
|
||||
import sys
|
||||
from collections.abc import Awaitable, Callable, Mapping
|
||||
from dataclasses import dataclass, replace
|
||||
|
|
@ -16,7 +17,9 @@ MASTER_KEY_SETTING: Final = "master_key"
|
|||
MASTER_KEY_ENV_VAR: Final = "LITELLM_MASTER_KEY"
|
||||
SALT_KEY_ENV_VAR: Final = "LITELLM_SALT_KEY"
|
||||
MIGRATE_FROM_MASTER_KEY_ENV_VAR: Final = "LITELLM_MIGRATE_FROM_MASTER_KEY"
|
||||
PUBLICLY_KNOWN_MASTER_KEYS: Final = frozenset({"sk-1234"})
|
||||
PUBLICLY_KNOWN_MASTER_KEY_SHA256_DIGESTS: Final = frozenset(
|
||||
{"88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b"}
|
||||
)
|
||||
ROTATION_DOCS_URL: Final = "https://docs.litellm.ai/docs/proxy/master_key_rotations#proxy-refuses-to-start"
|
||||
_NEW_MASTER_KEY: Final = "sk-$(openssl rand -hex 32)"
|
||||
GENERATE_MASTER_KEY_COMMAND: Final = f'echo "{MASTER_KEY_ENV_VAR}={_NEW_MASTER_KEY}" | tee -a .env'
|
||||
|
|
@ -203,7 +206,7 @@ def _unsafe_reason(master_key: str | None) -> UnsafeMasterKeyReason | None:
|
|||
stripped: Final = master_key.strip()
|
||||
if not stripped:
|
||||
return UnsafeMasterKeyReason.EMPTY
|
||||
if stripped in PUBLICLY_KNOWN_MASTER_KEYS:
|
||||
if hashlib.sha256(stripped.encode()).hexdigest() in PUBLICLY_KNOWN_MASTER_KEY_SHA256_DIGESTS:
|
||||
return UnsafeMasterKeyReason.PUBLICLY_KNOWN
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -506,7 +506,7 @@ def _get_bearer_token_or_received_api_key(api_key: str) -> str:
|
|||
api_key = api_key.replace("bearer ", "")
|
||||
elif api_key.startswith("AWS4-HMAC-SHA256"):
|
||||
# Handle AWS Signature V4 format from LangChain
|
||||
# Format: AWS4-HMAC-SHA256 Credential=Bearer sk-12345/date/region/service/aws4_request, SignedHeaders=..., Signature=...
|
||||
# Format: AWS4-HMAC-SHA256 Credential=Bearer $LITELLM_MASTER_KEY/date/region/service/aws4_request, SignedHeaders=..., Signature=...
|
||||
# Extract the Bearer token from the Credential field
|
||||
match = re.search(r"Credential=Bearer\s+([^/\s,]+)", api_key)
|
||||
if match:
|
||||
|
|
@ -602,7 +602,7 @@ def _get_bearer_token(
|
|||
api_key = api_key.replace("bearer ", "")
|
||||
elif api_key.startswith("AWS4-HMAC-SHA256"):
|
||||
# Handle AWS Signature V4 format from LangChain
|
||||
# Format: AWS4-HMAC-SHA256 Credential=Bearer sk-12345/date/region/service/aws4_request, SignedHeaders=..., Signature=...
|
||||
# Format: AWS4-HMAC-SHA256 Credential=Bearer $LITELLM_MASTER_KEY/date/region/service/aws4_request, SignedHeaders=..., Signature=...
|
||||
# Extract the Bearer token from the Credential field
|
||||
match = re.search(r"Credential=Bearer\s+([^/\s,]+)", api_key)
|
||||
if match:
|
||||
|
|
@ -1572,7 +1572,6 @@ async def _user_api_key_auth_builder(
|
|||
route=route,
|
||||
request=request,
|
||||
)
|
||||
# if user wants to pass LiteLLM_Master_Key as a custom header, example pass litellm keys as X-LiteLLM-Key: Bearer sk-1234
|
||||
custom_litellm_key_header_name: Final = general_settings.get("litellm_key_header_name")
|
||||
if custom_litellm_key_header_name is not None:
|
||||
api_key = get_api_key_from_custom_header(
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ async def create_batch(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/batches \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"input_file_id": "file-abc123",
|
||||
|
|
@ -554,7 +554,7 @@ async def retrieve_batch(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/batches/batch_abc123 \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
|
||||
```
|
||||
|
|
@ -861,7 +861,7 @@ async def list_batches(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/batches?limit=2 \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
|
||||
```
|
||||
|
|
@ -1045,7 +1045,7 @@ async def cancel_batch(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/batches/batch_abc123/cancel \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-X POST
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ async def cache_delete(request: Request):
|
|||
|
||||
```shell
|
||||
curl -X POST "http://0.0.0.0:4000/cache/delete" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{"keys": ["key1", "key2"]}'
|
||||
```
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ async def cache_flushall():
|
|||
|
||||
Usage:
|
||||
```
|
||||
curl -X POST http://0.0.0.0:4000/cache/flushall -H "Authorization: Bearer sk-1234"
|
||||
curl -X POST http://0.0.0.0:4000/cache/flushall -H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ async def get_memory_summary(
|
|||
- garbage_collector: GC status and pending object counts
|
||||
|
||||
Example usage:
|
||||
curl http://localhost:4000/debug/memory/summary -H "Authorization: Bearer sk-1234"
|
||||
curl http://localhost:4000/debug/memory/summary -H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
For detailed analysis, call GET /debug/memory/details
|
||||
For cache management, use the cache management endpoints
|
||||
|
|
@ -692,7 +692,7 @@ async def get_memory_details(
|
|||
- include_process_info: Include process-level memory info using psutil (default: true)
|
||||
|
||||
Example usage:
|
||||
curl "http://localhost:4000/debug/memory/details?top_n=30" -H "Authorization: Bearer sk-1234"
|
||||
curl "http://localhost:4000/debug/memory/details?top_n=30" -H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
All memory sizes are reported in both bytes and MB.
|
||||
"""
|
||||
|
|
@ -754,10 +754,10 @@ async def configure_gc_thresholds_endpoint(
|
|||
- generation_2: Number of gen-1 collections before gen-2 collection (default: 10)
|
||||
|
||||
Example for more aggressive collection:
|
||||
curl -X POST "http://localhost:4000/debug/memory/gc/configure?generation_0=500" -H "Authorization: Bearer sk-1234"
|
||||
curl -X POST "http://localhost:4000/debug/memory/gc/configure?generation_0=500" -H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
Example for less aggressive collection:
|
||||
curl -X POST "http://localhost:4000/debug/memory/gc/configure?generation_0=1000" -H "Authorization: Bearer sk-1234"
|
||||
curl -X POST "http://localhost:4000/debug/memory/gc/configure?generation_0=1000" -H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
Monitor memory usage with GET /debug/memory/summary after changes.
|
||||
"""
|
||||
|
|
@ -796,7 +796,7 @@ async def get_debug_report(
|
|||
Nothing from the operator's config values, request data, or errors
|
||||
|
||||
Example usage:
|
||||
curl http://localhost:4000/debug/report -H "Authorization: Bearer sk-1234"
|
||||
curl http://localhost:4000/debug/report -H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
"""
|
||||
if not is_proxy_admin(user_api_key_dict):
|
||||
raise HTTPException(status_code=403, detail="Only proxy admins can read /debug/report")
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ async def create_container(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/containers" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "My Container",
|
||||
|
|
@ -66,7 +66,7 @@ async def create_container(
|
|||
Or specify provider via header:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/containers" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "custom-llm-provider: azure" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
|
|
@ -187,13 +187,13 @@ async def list_containers(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/containers?limit=20&order=desc" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Or specify provider via header or query param:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/containers?custom_llm_provider=azure" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
@ -290,13 +290,13 @@ async def retrieve_container(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/containers/cntr_123" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Or specify provider via header:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/containers/cntr_123" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "custom-llm-provider: azure"
|
||||
```
|
||||
"""
|
||||
|
|
@ -396,13 +396,13 @@ async def delete_container(
|
|||
Example:
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:4000/v1/containers/cntr_123" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Or specify provider via header:
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:4000/v1/containers/cntr_123" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "custom-llm-provider: azure"
|
||||
```
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ async def create_fine_tuning_job(
|
|||
```
|
||||
curl http://localhost:4000/v1/fine_tuning/jobs \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"training_file": "file-abc123",
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ async def create_interaction(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1beta/interactions" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "gemini/gemini-2.5-flash",
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ async def health_services_endpoint(
|
|||
Example:
|
||||
```
|
||||
curl -L -X GET 'http://0.0.0.0:4000/health/services?service=datadog' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
try:
|
||||
|
|
@ -2086,7 +2086,7 @@ async def test_model_connection(
|
|||
```bash
|
||||
# If model is configured in proxy_config.yaml, you only need to specify the model name:
|
||||
curl -X POST 'http://localhost:4000/health/test_connection' \\
|
||||
-H 'Authorization: Bearer sk-1234' \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"litellm_params": {
|
||||
|
|
@ -2099,7 +2099,7 @@ async def test_model_connection(
|
|||
|
||||
# You can also override specific params or test with custom credentials:
|
||||
curl -X POST 'http://localhost:4000/health/test_connection' \\
|
||||
-H 'Authorization: Bearer sk-1234' \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"litellm_params": {
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ class KeyManagementEventHooks:
|
|||
|
||||
Args:
|
||||
secret_name: Name of the virtual key
|
||||
secret_token: Value of the virtual key (example: sk-1234)
|
||||
secret_token: Value of the virtual key (example: $LITELLM_API_KEY)
|
||||
"""
|
||||
if litellm._key_management_settings is not None:
|
||||
if litellm._key_management_settings.store_virtual_keys is True:
|
||||
|
|
@ -330,7 +330,7 @@ class KeyManagementEventHooks:
|
|||
Args:
|
||||
current_secret_name: Current name of the virtual key
|
||||
new_secret_name: New name of the virtual key
|
||||
new_secret_value: New value of the virtual key (example: sk-1234)
|
||||
new_secret_value: New value of the virtual key (example: $LITELLM_API_KEY)
|
||||
team_id: Optional team ID to get team-specific secret manager settings
|
||||
"""
|
||||
secret_manager: Final = KeyManagementEventHooks._stored_virtual_key_secret_manager()
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ class _PROXY_VirtualKeyModelMaxBudgetLimiter(RouterBudgetLimiting):
|
|||
"""
|
||||
Handles budgets for model + virtual key
|
||||
|
||||
Example: key=sk-1234567890, model=gpt-4o, max_budget=100, time_period=1d
|
||||
Example: key=$LITELLM_API_KEY, model=gpt-4o, max_budget=100, time_period=1d
|
||||
"""
|
||||
|
||||
def __init__(self, dual_cache: DualCache):
|
||||
|
|
@ -497,7 +497,7 @@ class _PROXY_VirtualKeyModelMaxBudgetLimiter(RouterBudgetLimiting):
|
|||
"""
|
||||
Track spend for virtual key + model in DualCache
|
||||
|
||||
Example: key=sk-1234567890, model=gpt-4o, max_budget=100, time_period=1d
|
||||
Example: key=$LITELLM_API_KEY, model=gpt-4o, max_budget=100, time_period=1d
|
||||
"""
|
||||
verbose_proxy_logger.debug("in RouterBudgetLimiting.async_log_success_event")
|
||||
standard_logging_payload: Final[StandardLoggingPayload | None] = kwargs.get("standard_logging_object", None)
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ async def image_edit_api(
|
|||
curl -s -D >(grep -i x-request-id >&2) \
|
||||
-o >(jq -r '.data[0].b64_json' | base64 --decode > gift-basket.png) \
|
||||
-X POST "http://localhost:4000/v1/images/edits" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-F "model=gpt-image-1" \
|
||||
-F "image[]=@soap.png" \
|
||||
-F 'prompt=Create a studio ghibli image of this'
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ async def block_user(data: BlockUsers):
|
|||
|
||||
```
|
||||
curl -X POST "http://0.0.0.0:8000/user/block"
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
-d '{
|
||||
"user_ids": [<user_id>, ...]
|
||||
}'
|
||||
|
|
@ -222,7 +222,7 @@ async def unblock_user(data: BlockUsers):
|
|||
Example
|
||||
```
|
||||
curl -X POST "http://0.0.0.0:8000/user/unblock"
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
-d '{
|
||||
"user_ids": [<user_id>, ...]
|
||||
}'
|
||||
|
|
@ -375,7 +375,7 @@ async def new_end_user(
|
|||
Example curl:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/customer/new' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"user_id" : "ishaan-jaff-3",
|
||||
|
|
@ -387,7 +387,7 @@ async def new_end_user(
|
|||
|
||||
# With object permissions
|
||||
curl -L -X POST 'http://localhost:4000/customer/new' \
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"user_id": "user_1",
|
||||
|
|
@ -558,7 +558,7 @@ async def end_user_info(
|
|||
Example curl:
|
||||
```
|
||||
curl -X GET 'http://localhost:4000/customer/info?end_user_id=test-litellm-user-4' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
try:
|
||||
|
|
@ -638,7 +638,7 @@ async def update_end_user(
|
|||
Example curl:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/customer/update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"user_id": "test-litellm-user-4",
|
||||
|
|
@ -648,7 +648,7 @@ async def update_end_user(
|
|||
|
||||
# Updating object permissions
|
||||
curl -L -X POST 'http://localhost:4000/customer/update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"user_id": "user_1",
|
||||
|
|
@ -797,7 +797,7 @@ async def delete_end_user(
|
|||
Example curl:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/customer/delete' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"user_ids" :["ishaan-jaff-5"]
|
||||
|
|
@ -872,7 +872,7 @@ async def list_end_user(
|
|||
Example curl:
|
||||
```
|
||||
curl --location --request GET 'http://0.0.0.0:4000/customer/list' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -543,7 +543,7 @@ async def new_user(
|
|||
```shell
|
||||
curl -X POST "http://localhost:4000/user/new" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"username": "new_user",
|
||||
"email": "new_user@example.com"
|
||||
|
|
@ -952,7 +952,7 @@ async def user_info(
|
|||
Example request
|
||||
```
|
||||
curl -X GET 'http://localhost:4000/user/info?user_id=krrish7%40berri.ai' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import model_max_budget_limiter, prisma_client
|
||||
|
|
@ -1105,7 +1105,7 @@ async def user_info_v2(
|
|||
Example request:
|
||||
```
|
||||
curl -X GET 'http://localhost:4000/v2/user/info?user_id=user123' \\
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import model_max_budget_limiter, prisma_client
|
||||
|
|
@ -1685,7 +1685,7 @@ async def user_update(
|
|||
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/user/update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"user_id": "test-litellm-user-4",
|
||||
|
|
@ -1873,7 +1873,7 @@ async def bulk_user_update(
|
|||
Example request for specific users:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/user/bulk_update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"users": [
|
||||
|
|
@ -1894,7 +1894,7 @@ async def bulk_user_update(
|
|||
Example request for all users:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/user/bulk_update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"all_users": true,
|
||||
|
|
@ -2415,7 +2415,7 @@ async def delete_user(
|
|||
```
|
||||
curl --location 'http://0.0.0.0:4000/user/delete' \
|
||||
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
|
||||
--header 'Content-Type: application/json' \
|
||||
|
||||
|
|
|
|||
|
|
@ -2028,7 +2028,7 @@ async def generate_key_fn(
|
|||
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/key/generate' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"permissions": {"allow_pii_controls": true}
|
||||
|
|
@ -2226,7 +2226,7 @@ async def generate_service_account_key_fn(
|
|||
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/key/generate' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"permissions": {"allow_pii_controls": true}
|
||||
|
|
@ -3440,10 +3440,10 @@ async def update_key_fn(
|
|||
Example:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/key/update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"key": "sk-1234",
|
||||
"key": "sk-<your-virtual-key>",
|
||||
"key_alias": "my-key",
|
||||
"user_id": "user-1234",
|
||||
"team_id": "team-1234",
|
||||
|
|
@ -3666,12 +3666,12 @@ async def bulk_update_keys(
|
|||
Example request:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/key/bulk_update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"keys": [
|
||||
{
|
||||
"key": "sk-1234",
|
||||
"key": "sk-<your-virtual-key>",
|
||||
"max_budget": 100.0,
|
||||
"team_id": "team-123",
|
||||
"tags": ["production", "api"]
|
||||
|
|
@ -4097,7 +4097,7 @@ async def delete_key_fn(
|
|||
Example:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/key/delete' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"keys": ["sk-QWrxEynunsNpV1zT48HIrw"]
|
||||
|
|
@ -4276,7 +4276,7 @@ async def info_key_fn_v2(
|
|||
Example Curl:
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:4000/key/info" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d {"keys": ["sk-1", "sk-2", "sk-3"]}
|
||||
```
|
||||
"""
|
||||
|
|
@ -4405,7 +4405,7 @@ async def info_key_fn(
|
|||
Example Curl:
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:4000/key/info?key=d5345c0ecc68ae6295c69f91926b2bd379e25481a40c34b5884d157a9f65d8fa" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Curl - if no key is passed, it will use the Key Passed in Authorization Header
|
||||
|
|
@ -5795,8 +5795,8 @@ async def regenerate_key_fn(
|
|||
|
||||
Example:
|
||||
```bash
|
||||
curl --location --request POST 'http://localhost:4000/key/sk-1234/regenerate' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
curl --location --request POST "http://localhost:4000/key/$LITELLM_API_KEY/regenerate" \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"max_budget": 100,
|
||||
|
|
@ -7329,7 +7329,7 @@ async def block_key(
|
|||
Example:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/key/block' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"key": "sk-Fn8Ej39NxjAXrvpUGKghGw"
|
||||
|
|
@ -7443,7 +7443,7 @@ async def unblock_key(
|
|||
Example:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/key/unblock' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"key": "sk-Fn8Ej39NxjAXrvpUGKghGw"
|
||||
|
|
@ -7560,7 +7560,7 @@ async def key_health(
|
|||
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/key/health" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ async def list_budgets(
|
|||
Example curl:
|
||||
```
|
||||
curl --location --globoff 'http://0.0.0.0:4000/management/v1/budgets?sort=-max_budget&filter[budget_duration][in]=7d,30d&page_size=25' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ async def list_spend_log_end_users(
|
|||
Example curl:
|
||||
```
|
||||
curl --location --globoff 'http://0.0.0.0:4000/management/v1/spend_logs/end_users?filter[startTime][gte]=2026-07-23T00:00:00Z&filter[startTime][lte]=2026-07-24T00:00:00Z&page_size=50&q=acme' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
return await _list_spend_log_facet(
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ async def bulk_delete_team_members_action(
|
|||
Example curl:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/management/v1/teams/team-1/members/bulk_delete' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{"members": [{"user_id": "user-1"}, {"user_email": "user-2@example.com"}]}'
|
||||
```
|
||||
|
|
@ -135,7 +135,7 @@ async def bulk_update_team_member_budgets_action(
|
|||
Example curl:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/management/v1/teams/team-1/members/bulk_update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{"members": [{"user_id": "user-1", "max_budget_in_team": 10}, {"user_email": "user-2@example.com", "max_budget_in_team": 10, "budget_duration": "30d"}]}'
|
||||
```
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ async def bulk_create_users_route(
|
|||
```
|
||||
curl -X POST "http://localhost:4000/management/v1/users/bulk" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-H "Authorization: Bearer sk-1234" \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-d '{
|
||||
"users": [
|
||||
{"user_email": "a@example.com", "user_role": "internal_user", "teams": ["team-1"]},
|
||||
|
|
@ -136,7 +136,7 @@ async def bulk_delete_users_action(
|
|||
Example curl:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/management/v1/users/bulk_delete' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{"user_ids": ["user-1", "user-2"]}'
|
||||
```
|
||||
|
|
|
|||
|
|
@ -584,7 +584,7 @@ async def create_model_group(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST 'http://localhost:4000/access_group/new' \\
|
||||
-H 'Authorization: Bearer sk-1234' \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"access_group": "production-models",
|
||||
|
|
@ -729,7 +729,7 @@ async def list_access_groups(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET 'http://localhost:4000/access_group/list' \\
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
|
@ -777,7 +777,7 @@ async def get_access_group_info(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET 'http://localhost:4000/access_group/production-models/info' \\
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
|
@ -841,7 +841,7 @@ async def update_access_group(
|
|||
Example:
|
||||
```bash
|
||||
curl -X PUT 'http://localhost:4000/access_group/production-models/update' \\
|
||||
-H 'Authorization: Bearer sk-1234' \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"model_names": ["gpt-4", "claude-3-sonnet"]
|
||||
|
|
@ -993,7 +993,7 @@ async def delete_access_group(
|
|||
Example:
|
||||
```bash
|
||||
curl -X DELETE 'http://localhost:4000/access_group/production-models/delete' \\
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
|
@ -1099,7 +1099,7 @@ async def get_access_group_budget(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET 'http://localhost:4000/access_group/production-models/budget' \\
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
|
@ -1139,7 +1139,7 @@ async def set_access_group_budget(
|
|||
Example:
|
||||
```bash
|
||||
curl -X PUT 'http://localhost:4000/access_group/production-models/budget' \\
|
||||
-H 'Authorization: Bearer sk-1234' \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"max_budget": 100.0,
|
||||
|
|
@ -1213,7 +1213,7 @@ async def delete_access_group_budget(
|
|||
Example:
|
||||
```bash
|
||||
curl -X DELETE 'http://localhost:4000/access_group/production-models/budget' \\
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ async def new_organization(
|
|||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/organization/new' \
|
||||
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
|
||||
--header 'Content-Type: application/json' \
|
||||
|
||||
|
|
@ -422,7 +422,7 @@ async def new_organization(
|
|||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/organization/new' \
|
||||
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
|
||||
--header 'Content-Type: application/json' \
|
||||
|
||||
|
|
@ -1111,13 +1111,13 @@ async def list_organization(
|
|||
Example:
|
||||
```
|
||||
curl --location --request GET 'http://0.0.0.0:4000/organization/list?org_alias=my-org' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example with org_id:
|
||||
```
|
||||
curl --location --request GET 'http://0.0.0.0:4000/organization/list?org_id=123e4567-e89b-12d3-a456-426614174000' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
|
@ -1311,7 +1311,7 @@ async def organization_member_add(
|
|||
Example:
|
||||
```
|
||||
curl -X POST 'http://0.0.0.0:4000/organization/member_add' \
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"organization_id": "45e3e396-ee08-4a61-a88e-16b3ce7e0849",
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ async def add_team_callbacks(
|
|||
```
|
||||
curl -X POST 'http:/localhost:4000/team/dbe2f686-a686-4896-864a-4c3924458709/callback' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"callback_name": "langfuse",
|
||||
"callback_type": "success",
|
||||
|
|
@ -468,7 +468,7 @@ async def delete_team_callback(
|
|||
Example curl:
|
||||
```
|
||||
curl -X DELETE 'http://localhost:4000/team/dbe2f686-a686-4896-864a-4c3924458709/callback/langsmith' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Covers callbacks registered through POST /team/{team_id}/callback and the Admin UI. Teams still
|
||||
|
|
@ -604,7 +604,7 @@ async def disable_team_logging(
|
|||
Example curl:
|
||||
```
|
||||
curl -X POST 'http://localhost:4000/team/dbe2f686-a686-4896-864a-4c3924458709/disable_logging' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -736,7 +736,7 @@ async def get_team_callbacks(
|
|||
Example curl:
|
||||
```
|
||||
curl -X GET 'http://localhost:4000/team/dbe2f686-a686-4896-864a-4c3924458709/callback' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
This will return the callback settings for the team with id dbe2f686-a686-4896-864a-4c3924458709
|
||||
|
|
|
|||
|
|
@ -1407,7 +1407,7 @@ async def new_team(
|
|||
Example Request:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/new' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"team_alias": "my-new-team_2",
|
||||
|
|
@ -1419,7 +1419,7 @@ async def new_team(
|
|||
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/new' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"team_alias": "QA Prod Bot",
|
||||
|
|
@ -2167,7 +2167,7 @@ async def update_team(
|
|||
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"team_id": "8d916b1c-510d-4894-a334-1c16a93344f5",
|
||||
|
|
@ -2178,7 +2178,7 @@ async def update_team(
|
|||
Example - Update Team `max_budget` budget
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/update' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"team_id": "8d916b1c-510d-4894-a334-1c16a93344f5",
|
||||
|
|
@ -2597,7 +2597,7 @@ async def patch_team(
|
|||
|
||||
```
|
||||
curl --location --request PATCH 'http://0.0.0.0:4000/team/8d916b1c-510d-4894-a334-1c16a93344f5' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"metadata": {"cost_center": "1234", "deprecated_key": null}
|
||||
|
|
@ -3368,7 +3368,7 @@ async def team_member_add(
|
|||
```
|
||||
|
||||
curl -X POST 'http://0.0.0.0:4000/team/member_add' \
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"team_id": "45e3e396-ee08-4a61-a88e-16b3ce7e0849", "member": {"role": "user", "user_id": "krrish247652@berri.ai"}}'
|
||||
|
||||
|
|
@ -3549,7 +3549,7 @@ async def team_member_delete(
|
|||
```
|
||||
curl -X POST 'http://0.0.0.0:8000/team/member_delete' \
|
||||
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
|
||||
-H 'Content-Type: application/json' \
|
||||
|
||||
|
|
@ -4196,7 +4196,7 @@ async def bulk_team_member_add(
|
|||
Example request:
|
||||
```bash
|
||||
curl --location 'http://0.0.0.0:4000/team/bulk_member_add' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"team_id": "team-1234",
|
||||
|
|
@ -4329,7 +4329,7 @@ async def delete_team(
|
|||
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/delete' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"team_ids": ["8d916b1c-510d-4894-a334-1c16a93344f5"]
|
||||
|
|
@ -5141,7 +5141,7 @@ async def block_team(
|
|||
Example:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/block' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"team_id": "team-1234"
|
||||
|
|
@ -5196,7 +5196,7 @@ async def unblock_team(
|
|||
Example:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/unblock' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"team_id": "team-1234"
|
||||
|
|
@ -5867,7 +5867,7 @@ async def list_team(
|
|||
"""
|
||||
```
|
||||
curl --location --request GET 'http://0.0.0.0:4000/team/list' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
|
@ -6071,7 +6071,7 @@ async def team_model_add(
|
|||
Example Request:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/model/add' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"team_id": "team-1234",
|
||||
|
|
@ -6187,7 +6187,7 @@ async def team_model_delete(
|
|||
Example Request:
|
||||
```
|
||||
curl --location 'http://0.0.0.0:4000/team/model/delete' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"team_id": "team-1234",
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ async def ocr(
|
|||
**1. JSON body** (Mistral OCR API compatible):
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/ocr" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "mistral-ocr",
|
||||
|
|
@ -286,7 +286,7 @@ async def ocr(
|
|||
**2. Multipart form file upload**:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/ocr" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-F "model=mistral-ocr" \
|
||||
-F "file=@document.pdf"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -569,7 +569,7 @@ async def create_file(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/files \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-F purpose="batch" \
|
||||
-F file="@mydata.jsonl"
|
||||
-F expires_after[anchor]="created_at" \
|
||||
|
|
@ -970,7 +970,7 @@ async def get_file_content(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/files/file-abc123/content \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
```
|
||||
"""
|
||||
|
|
@ -1282,7 +1282,7 @@ async def get_file(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/files/file-abc123 \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
```
|
||||
"""
|
||||
|
|
@ -1708,7 +1708,7 @@ async def list_files(
|
|||
Example Curl
|
||||
```
|
||||
curl http://localhost:4000/v1/files\
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
```
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -12065,7 +12065,7 @@ async def chat_completion(
|
|||
|
||||
-H "Content-Type: application/json" \
|
||||
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
|
||||
-d '{
|
||||
"model": "gpt-4o",
|
||||
|
|
@ -12229,7 +12229,7 @@ async def completion(
|
|||
|
||||
-H "Content-Type: application/json" \
|
||||
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
|
||||
-d '{
|
||||
"model": "gpt-3.5-turbo-instruct",
|
||||
|
|
@ -12413,7 +12413,7 @@ async def embeddings(
|
|||
|
||||
-H "Content-Type: application/json" \
|
||||
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
|
||||
-d '{
|
||||
"model": "text-embedding-ada-002",
|
||||
|
|
@ -12521,7 +12521,7 @@ async def moderations(
|
|||
```
|
||||
curl --location 'http://0.0.0.0:4000/moderations' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--data '{"input": "Sample text goes here", "model": "text-moderation-stable"}'
|
||||
```
|
||||
"""
|
||||
|
|
@ -14175,7 +14175,7 @@ async def supported_openai_params(model: str):
|
|||
Example curl:
|
||||
```
|
||||
curl -X GET --location 'http://localhost:4000/utils/supported_openai_params?model=gpt-3.5-turbo-16k' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import declared_authenticating_provider
|
||||
|
|
@ -14220,7 +14220,7 @@ async def model_info_lookup(model: str, custom_llm_provider: str | None = None):
|
|||
Example curl:
|
||||
```
|
||||
curl -X GET --location 'http://localhost:4000/utils/model_info?model=gpt-4o&custom_llm_provider=openai' \
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
detail: Final = {"error": f"model={model}, custom_llm_provider={custom_llm_provider} is not in the model cost map"}
|
||||
|
|
@ -15464,7 +15464,7 @@ async def model_info_v2(
|
|||
Example request:
|
||||
```
|
||||
curl -X GET 'http://localhost:4000/v2/model/info?include_team_models=true&page=1&size=50' \\
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
|
@ -16414,7 +16414,7 @@ async def model_deprecations(
|
|||
Example:
|
||||
```shell
|
||||
curl -X GET 'http://localhost:4000/model/deprecations' \\
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
return collect_model_deprecations(llm_router=llm_router, warn_within_days=warn_within_days)
|
||||
|
|
@ -16476,7 +16476,7 @@ async def model_group_info(
|
|||
curl -X 'GET' \
|
||||
'http://localhost:4000/model_group/info' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'x-api-key: sk-1234'
|
||||
-H "x-api-key: $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Request (Specific Model Group):
|
||||
|
|
@ -16484,7 +16484,7 @@ async def model_group_info(
|
|||
curl -X 'GET' \
|
||||
'http://localhost:4000/model_group/info?model_group=rerank-english-v3.0' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Request (Specific Wildcard Model Group): (e.g. `model_name: openai/*` on config.yaml)
|
||||
|
|
@ -16492,7 +16492,7 @@ async def model_group_info(
|
|||
curl -X 'GET' \
|
||||
'http://localhost:4000/model_group/info?model_group=openai/tts-1'
|
||||
-H 'accept: application/json' \
|
||||
-H 'Authorization: Bearersk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Learn how to use and set wildcard models [here](https://docs.litellm.ai/docs/wildcard_routing)
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ async def rag_ingest(
|
|||
## Form upload (for files):
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/rag/ingest" \\
|
||||
-H "Authorization: Bearer sk-1234" \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-F file="@document.pdf" \\
|
||||
-F 'ingest_options={"vector_store": {"custom_llm_provider": "openai"}}'
|
||||
```
|
||||
|
|
@ -558,7 +558,7 @@ async def rag_ingest(
|
|||
## JSON body (for URLs):
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/rag/ingest" \\
|
||||
-H "Authorization: Bearer sk-1234" \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"file_url": "https://example.com/document.pdf",
|
||||
|
|
@ -569,7 +569,7 @@ async def rag_ingest(
|
|||
## Bedrock:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/rag/ingest" \\
|
||||
-H "Authorization: Bearer sk-1234" \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-F file="@document.pdf" \\
|
||||
-F 'ingest_options={"vector_store": {"custom_llm_provider": "bedrock"}}'
|
||||
```
|
||||
|
|
@ -725,7 +725,7 @@ async def rag_query(
|
|||
## Example Request:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/rag/query" \\
|
||||
-H "Authorization: Bearer sk-1234" \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"model": "gpt-4o-mini",
|
||||
|
|
@ -741,7 +741,7 @@ async def rag_query(
|
|||
## With Reranking:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/rag/query" \\
|
||||
-H "Authorization: Bearer sk-1234" \\
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"model": "gpt-4o-mini",
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ async def responses_api(
|
|||
# Normal request
|
||||
curl -X POST http://localhost:4000/v1/responses \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"model": "gpt-4o",
|
||||
"input": "Tell me about AI"
|
||||
|
|
@ -235,7 +235,7 @@ async def responses_api(
|
|||
# Background request with polling
|
||||
curl -X POST http://localhost:4000/v1/responses \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"model": "gpt-4o",
|
||||
"input": "Tell me about AI",
|
||||
|
|
@ -518,7 +518,7 @@ async def cursor_chat_completions(
|
|||
```bash
|
||||
curl -X POST http://localhost:4000/cursor/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"model": "gpt-4o",
|
||||
"input": [{"role": "user", "content": "Hello"}]
|
||||
|
|
@ -711,11 +711,11 @@ async def get_response(
|
|||
```bash
|
||||
# Get polling response
|
||||
curl -X GET http://localhost:4000/v1/responses/litellm_poll_abc123 \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
# Get provider response
|
||||
curl -X GET http://localhost:4000/v1/responses/resp_abc123 \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
@ -826,7 +826,7 @@ async def delete_response(
|
|||
|
||||
```bash
|
||||
curl -X DELETE http://localhost:4000/v1/responses/resp_abc123 \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
@ -1001,7 +1001,7 @@ async def compact_response(
|
|||
```bash
|
||||
curl -X POST http://localhost:4000/v1/responses/compact \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"model": "gpt-4o",
|
||||
"input": [{"role": "user", "content": "Hello"}]
|
||||
|
|
@ -1153,7 +1153,7 @@ async def responses_input_tokens(
|
|||
```bash
|
||||
curl -X POST http://localhost:4000/v1/responses/input_tokens \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"model": "gpt-4o",
|
||||
"input": "Hello, how are you?"
|
||||
|
|
@ -1232,11 +1232,11 @@ async def cancel_response(
|
|||
```bash
|
||||
# Cancel polling response
|
||||
curl -X POST http://localhost:4000/v1/responses/litellm_poll_abc123/cancel \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
|
||||
# Cancel provider response
|
||||
curl -X POST http://localhost:4000/v1/responses/resp_abc123/cancel \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ async def search(
|
|||
Example with search_tool_name in URL (recommended - keeps body Perplexity-compatible):
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/search/litellm-search" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"query": "latest AI developments 2024",
|
||||
|
|
@ -71,7 +71,7 @@ async def search(
|
|||
Example with search_tool_name in body:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/search" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"search_tool_name": "litellm-search",
|
||||
|
|
@ -270,7 +270,7 @@ async def list_search_tools(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/search/tools" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Response:
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ async def spend_key_fn(
|
|||
Example Request:
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/keys" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
|
||||
|
|
@ -505,13 +505,13 @@ async def spend_user_fn(
|
|||
Example Request:
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/users" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
View User Table row for user_id
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/users?user_id=1234" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
|
@ -576,13 +576,13 @@ async def view_spend_tags(
|
|||
Example Request:
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/tags" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Spend with Start Date and End Date
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/tags?start_date=2022-01-01&end_date=2022-02-01" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
|
||||
|
|
@ -1238,7 +1238,7 @@ async def get_spend_capture_rate(
|
|||
|
||||
Example:
|
||||
```
|
||||
curl -H "Authorization: Bearer sk-1234" \
|
||||
curl -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
"http://localhost:4000/spend/capture_rate?provider=openai&start_date=2026-09-17&end_date=2026-09-23"
|
||||
```
|
||||
"""
|
||||
|
|
@ -2158,13 +2158,13 @@ async def global_view_spend_tags(
|
|||
Example Request:
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:4000/spend/tags" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Spend with Start Date and End Date
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:4000/spend/tags?start_date=2022-01-01&end_date=2022-02-01" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
import traceback
|
||||
|
|
@ -2308,7 +2308,7 @@ async def calculate_spend(request: SpendCalculateRequest):
|
|||
|
||||
```
|
||||
curl --location 'http://localhost:4000/spend/calculate'
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
--header 'Content-Type: application/json'
|
||||
--data '{
|
||||
"model": "anthropic.claude-v2",
|
||||
|
|
@ -2320,7 +2320,7 @@ async def calculate_spend(request: SpendCalculateRequest):
|
|||
|
||||
```
|
||||
curl --location 'http://localhost:4000/spend/calculate'
|
||||
--header 'Authorization: Bearer sk-1234'
|
||||
--header "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
--header 'Content-Type: application/json'
|
||||
--data '{
|
||||
"completion_response": {
|
||||
|
|
@ -2594,7 +2594,7 @@ async def ui_view_spend_logs(
|
|||
Example:
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/logs/v2?start_date=2025-11-25%2000:00:00&end_date=2025-11-26%2023:59:59&page=1&page_size=50" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
|
@ -3506,31 +3506,31 @@ async def view_spend_logs(
|
|||
Example Request for all logs
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/logs" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Request for specific request_id
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/logs?request_id=chatcmpl-6dcb2540-d3d7-4e49-bb27-291f863f112e" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Request for specific api_key
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/logs?api_key=d5345c0ecc68ae6295c69f91926b2bd379e25481a40c34b5884d157a9f65d8fa" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Request for specific user_id
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/logs?user_id=ishaan@berri.ai" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Request for date range with individual logs (unsummarized)
|
||||
```
|
||||
curl -X GET "http://0.0.0.0:8000/spend/logs?start_date=2024-01-01&end_date=2024-01-02&summarize=false" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
|
@ -4304,7 +4304,7 @@ async def provider_budgets() -> ProviderBudgetResponse:
|
|||
```bash
|
||||
curl -X GET http://localhost:4000/provider/budgets \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
|
||||
Example Response
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ async def index_create(
|
|||
```bash
|
||||
curl -L -X POST 'http://0.0.0.0:4000/v1/indexes' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Authorization: Bearer sk-1234' \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-d '{
|
||||
"index_name": "dall-e-3",
|
||||
"litellm_params": {
|
||||
|
|
@ -622,7 +622,7 @@ async def index_list(
|
|||
|
||||
```bash
|
||||
curl -L -X GET 'http://0.0.0.0:4000/v1/indexes' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import prisma_client
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ async def video_generation(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/videos" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "sora-2",
|
||||
|
|
@ -144,7 +144,7 @@ async def video_list(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/videos" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
@ -232,7 +232,7 @@ async def video_status(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/videos/video_123" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
@ -332,7 +332,7 @@ async def video_content(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/videos/{video_id}/content" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
--output video.mp4
|
||||
```
|
||||
"""
|
||||
|
|
@ -437,7 +437,7 @@ async def video_remix(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/videos/video_123/remix" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"prompt": "A new version with different colors"
|
||||
|
|
@ -541,7 +541,7 @@ async def video_create_character(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/videos/characters" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-F "video=@character_video.mp4" \
|
||||
-F "name=my_character"
|
||||
```
|
||||
|
|
@ -643,7 +643,7 @@ async def video_get_character(
|
|||
Example:
|
||||
```bash
|
||||
curl -X GET "http://localhost:4000/v1/videos/characters/char_123" \
|
||||
-H "Authorization: Bearer sk-1234"
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
|
||||
```
|
||||
"""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
@ -748,7 +748,7 @@ async def video_edit(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/videos/edits" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"prompt": "Make it brighter", "video": {"id": "video_123"}}'
|
||||
```
|
||||
|
|
@ -852,7 +852,7 @@ async def video_extension(
|
|||
Example:
|
||||
```bash
|
||||
curl -X POST "http://localhost:4000/v1/videos/extensions" \
|
||||
-H "Authorization: Bearer sk-1234" \
|
||||
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"prompt": "Continue the scene", "seconds": "5", "video": {"id": "video_123"}}'
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
# QA: code interpreter sandbox stickiness via metadata.session_id
|
||||
# bash qa_sticky_session.sh
|
||||
# LITELLM_BASE_URL=http://localhost:4000 LITELLM_KEY=sk-1234 bash qa_sticky_session.sh
|
||||
# LITELLM_BASE_URL=http://localhost:4000 LITELLM_KEY="$LITELLM_MASTER_KEY" bash qa_sticky_session.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE="${LITELLM_BASE_URL:-http://localhost:4000}"
|
||||
KEY="${LITELLM_KEY:-sk-1234}"
|
||||
KEY="${LITELLM_KEY:-${LITELLM_MASTER_KEY:?set LITELLM_KEY or LITELLM_MASTER_KEY}}"
|
||||
MODEL="${LITELLM_MODEL:-gpt-4o-mini}"
|
||||
# proxy running at http://localhost:4000 (master key: sk-1234)
|
||||
# proxy running at http://localhost:4000
|
||||
SESSION_A="qa-session-$(date +%s)-A"
|
||||
SESSION_B="qa-session-$(date +%s)-B"
|
||||
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@
|
|||
|
||||
<div class="connect">
|
||||
<label>Proxy URL <input id="proxy-url" type="text" value="http://localhost:4000" /></label>
|
||||
<label>API Key <input id="api-key" type="password" placeholder="sk-1234" /></label>
|
||||
<label>API Key <input id="api-key" type="password" placeholder="LITELLM_MASTER_KEY" /></label>
|
||||
<label>Router
|
||||
<input id="router" type="text" value="smart-cheap-router" style="width:160px" />
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@
|
|||
|
||||
<div class="connect">
|
||||
<label>Proxy URL <input id="proxy-url" type="text" value="http://localhost:4000" /></label>
|
||||
<label>Master Key <input id="api-key" type="password" placeholder="sk-1234" /></label>
|
||||
<label>Master Key <input id="api-key" type="password" placeholder="LITELLM_MASTER_KEY" /></label>
|
||||
<label>Avg tokens/req <input id="avg-tokens" type="number" value="500" min="1" /></label>
|
||||
<label>Poll ms <input id="poll-ms" type="number" value="500" min="100" /></label>
|
||||
<button id="connect-btn">Connect</button>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ For each test case:
|
|||
Run:
|
||||
uv run python scripts/adaptive_router_demo/eval.py \
|
||||
--proxy-url http://localhost:4000 \
|
||||
--api-key sk-1234 \
|
||||
--api-key "$LITELLM_MASTER_KEY" \
|
||||
--router smart-cheap-router \
|
||||
--judge-model smart
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Why this shape:
|
|||
Run:
|
||||
uv run python scripts/adaptive_router_demo/traffic.py \\
|
||||
--proxy-url http://localhost:4000 \\
|
||||
--api-key sk-1234 \\
|
||||
--api-key "$LITELLM_MASTER_KEY" \\
|
||||
--router smart-cheap-router \\
|
||||
--rounds 100 \\
|
||||
--rate 0.5
|
||||
|
|
|
|||
|
|
@ -35,13 +35,12 @@ import tempfile
|
|||
import time
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
from typing import Any, Final, Optional
|
||||
|
||||
import aiohttp
|
||||
from aiohttp import web
|
||||
|
||||
DEFAULT_MODEL = "claude-perf-test"
|
||||
DEFAULT_API_KEY = "sk-1234"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -490,7 +489,7 @@ def parse_args() -> argparse.Namespace:
|
|||
parser.add_argument("--proxy-port", type=int, default=4000)
|
||||
parser.add_argument("--provider-host", default="127.0.0.1")
|
||||
parser.add_argument("--provider-port", type=int, default=8098)
|
||||
parser.add_argument("--api-key", default=DEFAULT_API_KEY)
|
||||
parser.add_argument("--api-key", default=os.environ.get("LITELLM_MASTER_KEY"))
|
||||
parser.add_argument("--requests", type=int, default=300)
|
||||
parser.add_argument("--concurrency", type=int, default=20)
|
||||
parser.add_argument("--warmup", type=int, default=30)
|
||||
|
|
@ -524,12 +523,23 @@ def parse_args() -> argparse.Namespace:
|
|||
|
||||
async def async_main() -> None:
|
||||
args = parse_args()
|
||||
if args.no_start_proxy and not args.api_key:
|
||||
raise ValueError("Set LITELLM_MASTER_KEY or pass --api-key when using --no-start-proxy")
|
||||
api_key: Final = args.api_key or (
|
||||
"sk-"
|
||||
+ subprocess.run(
|
||||
["openssl", "rand", "-hex", "16"],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
text=True,
|
||||
).stdout.strip()
|
||||
)
|
||||
litellm_dir = Path(args.litellm_dir).resolve()
|
||||
revision = get_git_revision(litellm_dir)
|
||||
proxy_base_url = f"http://{args.proxy_host}:{args.proxy_port}"
|
||||
proxy_url = f"{proxy_base_url}/v1/messages"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {args.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
stream_payload = {
|
||||
|
|
@ -557,7 +567,7 @@ async def async_main() -> None:
|
|||
provider_base_url = provider.base_url
|
||||
|
||||
config_path = tmp_dir / "config.yaml"
|
||||
write_proxy_config(config_path, provider_base_url, args.api_key)
|
||||
write_proxy_config(config_path, provider_base_url, api_key)
|
||||
|
||||
try:
|
||||
if not args.no_start_proxy:
|
||||
|
|
|
|||
|
|
@ -29,14 +29,13 @@ import tempfile
|
|||
import time
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
from typing import Any, Final, Optional
|
||||
|
||||
import aiohttp
|
||||
from aiohttp import web
|
||||
|
||||
|
||||
DEFAULT_MODEL = "perf-test-model"
|
||||
DEFAULT_API_KEY = "sk-1234"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -646,7 +645,7 @@ def parse_args() -> argparse.Namespace:
|
|||
parser.add_argument("--proxy-port", type=int, default=4000)
|
||||
parser.add_argument("--provider-host", default="127.0.0.1")
|
||||
parser.add_argument("--provider-port", type=int, default=8099)
|
||||
parser.add_argument("--api-key", default=DEFAULT_API_KEY)
|
||||
parser.add_argument("--api-key", default=os.environ.get("LITELLM_MASTER_KEY"))
|
||||
parser.add_argument("--requests", type=int, default=500)
|
||||
parser.add_argument("--concurrency", type=int, default=100)
|
||||
parser.add_argument("--stream-requests", type=int, default=200)
|
||||
|
|
@ -695,12 +694,23 @@ def parse_args() -> argparse.Namespace:
|
|||
|
||||
async def async_main() -> None:
|
||||
args = parse_args()
|
||||
if args.no_start_proxy and not args.api_key:
|
||||
raise ValueError("Set LITELLM_MASTER_KEY or pass --api-key when using --no-start-proxy")
|
||||
api_key: Final = args.api_key or (
|
||||
"sk-"
|
||||
+ subprocess.run(
|
||||
["openssl", "rand", "-hex", "16"],
|
||||
capture_output=True,
|
||||
check=True,
|
||||
text=True,
|
||||
).stdout.strip()
|
||||
)
|
||||
litellm_dir = Path(args.litellm_dir).resolve()
|
||||
revision = get_git_revision(litellm_dir)
|
||||
proxy_base_url = f"http://{args.proxy_host}:{args.proxy_port}"
|
||||
proxy_url = f"{proxy_base_url}/v1/chat/completions"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {args.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
provider_headers = {
|
||||
|
|
@ -732,7 +742,7 @@ async def async_main() -> None:
|
|||
provider_base_url = provider.base_url
|
||||
|
||||
config_path = tmp_dir / "config.yaml"
|
||||
write_proxy_config(config_path, provider_base_url, args.api_key)
|
||||
write_proxy_config(config_path, provider_base_url, api_key)
|
||||
|
||||
try:
|
||||
if not args.no_start_proxy:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import argparse
|
||||
import asyncio
|
||||
import os
|
||||
import time
|
||||
import statistics
|
||||
|
||||
|
|
@ -17,7 +18,7 @@ REQUEST_BODY = {
|
|||
}
|
||||
|
||||
HEADERS = {
|
||||
"Authorization": "Bearer sk-1234",
|
||||
"Authorization": f"Bearer {os.environ['LITELLM_MASTER_KEY']}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ USAGE EXAMPLES:
|
|||
# Set required environment variables
|
||||
export LITELLM_PROXY_URL='http://localhost:4000/chat/completions'
|
||||
export PROVIDER_URL='https://api.openai.com/v1/chat/completions'
|
||||
export LITELLM_PROXY_API_KEY='sk-1234'
|
||||
export LITELLM_PROXY_API_KEY="$LITELLM_MASTER_KEY"
|
||||
export PROVIDER_API_KEY='sk-openai-key'
|
||||
|
||||
# Run from scripts directory
|
||||
|
|
@ -537,7 +537,7 @@ Examples:
|
|||
# 1. Basic usage (recommended - sequential execution)
|
||||
export LITELLM_PROXY_URL='http://localhost:4000/chat/completions'
|
||||
export PROVIDER_URL='https://api.openai.com/v1/chat/completions'
|
||||
export LITELLM_PROXY_API_KEY='sk-1234'
|
||||
export LITELLM_PROXY_API_KEY="$LITELLM_MASTER_KEY"
|
||||
export PROVIDER_API_KEY='sk-openai-key'
|
||||
python scripts/benchmark_proxy_vs_provider.py
|
||||
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ class LiteLLMHealthCheckClient:
|
|||
async def main():
|
||||
"""Main entry point."""
|
||||
base_url = os.environ.get("LITELLM_BASE_URL", "http://localhost:4000")
|
||||
api_key = os.environ.get("LITELLM_API_KEY", "sk-1234")
|
||||
api_key = os.environ["LITELLM_API_KEY"]
|
||||
yaml_path = os.environ.get("LITELLM_MODELS_YAML")
|
||||
custom_auth_header = os.environ.get(
|
||||
"LITELLM_CUSTOM_AUTH_HEADER"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
# Usage:
|
||||
# $env:LITELLM_BASE_URL="https://litellm.example.com"
|
||||
# $env:LITELLM_API_KEY="your-api-key"
|
||||
# $env:LITELLM_API_KEY="<your-virtual-key>"
|
||||
# .\run_parallel_health_checks.ps1 [num_parallel_jobs] [image_name]
|
||||
#
|
||||
# Defaults:
|
||||
|
|
@ -17,15 +17,14 @@ param(
|
|||
[string]$ContainerRuntime = "docker"
|
||||
)
|
||||
|
||||
# Set defaults for environment variables if not provided
|
||||
# Require credentials for the target proxy
|
||||
if (-not $env:LITELLM_BASE_URL) {
|
||||
$env:LITELLM_BASE_URL = "https://litellm-perf-cache-and-router.onrender.com"
|
||||
Write-Warning "LITELLM_BASE_URL not set, using default: $env:LITELLM_BASE_URL"
|
||||
}
|
||||
|
||||
if (-not $env:LITELLM_API_KEY) {
|
||||
$env:LITELLM_API_KEY = "sk-1234"
|
||||
Write-Warning "LITELLM_API_KEY not set, using default: $env:LITELLM_API_KEY"
|
||||
throw "LITELLM_API_KEY must be set"
|
||||
}
|
||||
|
||||
# Check if container runtime is available
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# Usage:
|
||||
# export LITELLM_BASE_URL="https://litellm.example.com"
|
||||
# export LITELLM_API_KEY="your-api-key"
|
||||
# export LITELLM_API_KEY="<your-virtual-key>"
|
||||
# ./run_parallel_health_checks.sh [num_parallel_jobs] [image_name] [container_runtime]
|
||||
#
|
||||
# Defaults:
|
||||
|
|
@ -20,16 +20,13 @@ NUM_PARALLEL_JOBS="${1:-16}"
|
|||
IMAGE_NAME="${2:-litellm/litellm-health-check:latest}"
|
||||
CONTAINER_RUNTIME="${3:-docker}"
|
||||
|
||||
# Set defaults for environment variables if not provided
|
||||
# Require credentials for the target proxy
|
||||
if [ -z "$LITELLM_BASE_URL" ]; then
|
||||
export LITELLM_BASE_URL="https://litellm-perf-cache-and-router.onrender.com"
|
||||
echo "Warning: LITELLM_BASE_URL not set, using default: $LITELLM_BASE_URL" >&2
|
||||
fi
|
||||
|
||||
if [ -z "$LITELLM_API_KEY" ]; then
|
||||
export LITELLM_API_KEY="sk-1234"
|
||||
echo "Warning: LITELLM_API_KEY not set, using default: $LITELLM_API_KEY" >&2
|
||||
fi
|
||||
: "${LITELLM_API_KEY:?set LITELLM_API_KEY}"
|
||||
|
||||
# Check if container runtime is available
|
||||
if ! command -v "$CONTAINER_RUNTIME" &> /dev/null; then
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ proxy_env() {
|
|||
export LENS_WORKER_IMAGE=litellm-lens-worker:local
|
||||
export LITELLM_MODE=PRODUCTION
|
||||
export LITELLM_MASTER_KEY="$master_key"
|
||||
if [ "$master_key" = sk-1234 ]; then export LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY=true; fi
|
||||
export LITELLM_SALT_KEY=sk-local-tracing-salt-key
|
||||
export DATABASE_URL="$database_url"
|
||||
export STORE_MODEL_IN_DB=True
|
||||
|
|
|
|||
11
tests/_master_key.py
Normal file
11
tests/_master_key.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import hashlib
|
||||
import os
|
||||
import secrets
|
||||
from typing import Final
|
||||
|
||||
_xdist_test_run_uid: Final = os.environ.get("PYTEST_XDIST_TESTRUNUID")
|
||||
MASTER_KEY: Final = (
|
||||
f"sk-{hashlib.sha256(_xdist_test_run_uid.encode()).hexdigest()[:32]}"
|
||||
if _xdist_test_run_uid is not None
|
||||
else f"sk-{secrets.token_hex(16)}"
|
||||
)
|
||||
|
|
@ -5,6 +5,7 @@ This test ensures that the proxy starts and serves requests even with a bad lice
|
|||
in ci/cd config.yml, we set the license to "bad-license"
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
import aiohttp
|
||||
from typing import Optional
|
||||
|
|
@ -36,7 +37,7 @@ async def test_health_and_chat_completion():
|
|||
# Make a chat completion call
|
||||
url = "http://0.0.0.0:4000/chat/completions"
|
||||
headers = {
|
||||
"Authorization": "Bearer sk-1234",
|
||||
"Authorization": f"Bearer {os.environ['LITELLM_MASTER_KEY']}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
data = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from collections.abc import Iterator
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
REPO_ROOT: Final = Path(__file__).resolve().parents[2]
|
||||
PUBLICLY_KNOWN_MASTER_KEY_PREFIX: Final = "sk-" + "1234"
|
||||
|
||||
|
||||
def _file_violations(relative_path: str) -> tuple[str, ...]:
|
||||
path: Final = REPO_ROOT / relative_path
|
||||
if path.is_dir():
|
||||
return ()
|
||||
try:
|
||||
contents: Final = path.read_bytes()
|
||||
except FileNotFoundError:
|
||||
return ()
|
||||
if b"\0" in contents:
|
||||
return ()
|
||||
try:
|
||||
text: Final = contents.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
return ()
|
||||
return tuple(
|
||||
f"{relative_path}:{line_number}"
|
||||
for line_number, line in enumerate(text.splitlines(), start=1)
|
||||
if PUBLICLY_KNOWN_MASTER_KEY_PREFIX in line
|
||||
)
|
||||
|
||||
|
||||
def _violations(tracked_paths: tuple[str, ...]) -> Iterator[str]:
|
||||
for path in tracked_paths:
|
||||
yield from _file_violations(path)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
result: Final = subprocess.run(
|
||||
["git", "-C", os.fspath(REPO_ROOT), "ls-files", "-z"],
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
tracked_paths: Final = tuple(
|
||||
os.fsdecode(path) for path in result.stdout.split(b"\0") if path
|
||||
)
|
||||
violations: Final = tuple(_violations(tracked_paths))
|
||||
for violation in violations:
|
||||
print(violation)
|
||||
if violations:
|
||||
print(f"\n{len(violations)} tracked line(s) contain the publicly known master key prefix")
|
||||
return 1
|
||||
print("No tracked files contain the publicly known master key prefix")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -533,7 +533,7 @@ class TestSecretMasking:
|
|||
environ: Final = {
|
||||
"OPENAI_API_KEY": "sk-proj-0123456789",
|
||||
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG",
|
||||
"LITELLM_MASTER_KEY": "sk-1234",
|
||||
"LITELLM_MASTER_KEY": "sk-test",
|
||||
"GOOGLE_APPLICATION_CREDENTIALS": "/secrets/vertex.json",
|
||||
"KEYCLOAK_URL": "http://localhost:8080",
|
||||
"E2E_MODEL": "claude-haiku-4-5",
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ The suites run against a live proxy, so bring one up first by running the litell
|
|||
|
||||
## Running the tests locally
|
||||
|
||||
1. Create a `.env` file in this directory with the provider keys the example models use, plus the master key and the Postgres/Redis coordinates your config reads back:
|
||||
1. Generate a master key with `export LITELLM_MASTER_KEY="sk-$(openssl rand -hex 32)"`. Create a `.env` file in this directory with the provider keys the example models use and the Postgres/Redis coordinates your config reads back:
|
||||
|
||||
```bash
|
||||
LITELLM_MASTER_KEY="sk-1234"
|
||||
LITELLM_MASTER_KEY="sk-<your-master-key>"
|
||||
DATABASE_URL="postgresql://llmproxy:dbpassword9090@localhost:5432/litellm"
|
||||
REDIS_HOST="localhost"
|
||||
REDIS_PORT="6379"
|
||||
|
|
@ -110,7 +110,7 @@ A couple of logging destinations are configured on the proxy rather than by the
|
|||
```bash
|
||||
bash tests/e2e/secret_manager/backend.sh up cyberark
|
||||
(set -a; . ~/.cache/litellm-e2e-secret-manager/cyberark/proxy.env; set +a; env -u OPENAI_API_KEY LITELLM_LICENSE=... \
|
||||
LITELLM_MASTER_KEY=sk-1234 DATABASE_URL=... uv run litellm --config tests/e2e/gateway/secret_manager_cyberark_ci_config.yml --port 4000)
|
||||
LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" DATABASE_URL=... uv run litellm --config tests/e2e/gateway/secret_manager_cyberark_ci_config.yml --port 4000)
|
||||
(set -a; . ~/.cache/litellm-e2e-secret-manager/cyberark/tests.env; set +a; OPENAI_API_KEY=... \
|
||||
uv run --group e2e-dev pytest tests/e2e/secret_manager/ -v)
|
||||
bash tests/e2e/secret_manager/backend.sh down cyberark
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ set -Eeuo pipefail
|
|||
LITELLM_REPO="${LITELLM_REPO:-${HOME}/litellm/litellm}"
|
||||
WORKTREE="${LITELLM_WORKTREE:-${HOME}/litellm-cron-worktree}"
|
||||
PROXY_PORT="${PROXY_PORT:-4100}"
|
||||
PROXY_API_KEY="${PROXY_API_KEY:-sk-cron-matrix}"
|
||||
PROXY_API_KEY="${PROXY_API_KEY:-sk-$(openssl rand -hex 16)}"
|
||||
DOCS_REPO="${DOCS_REPO:-BerriAI/litellm-docs}"
|
||||
DOCS_BRANCH="${DOCS_BRANCH:-main}"
|
||||
DOCS_TARGET_PATH="${DOCS_TARGET_PATH:-src/data/compatibility-matrix.json}"
|
||||
|
|
@ -347,9 +347,8 @@ log "starting proxy on 127.0.0.1:${PROXY_PORT}"
|
|||
# exclusively by the pytest run on the same host (the health check and
|
||||
# the test env set `LITELLM_PROXY_URL=http://127.0.0.1:...`),
|
||||
# so there's no reason to expose it on the container's external interfaces.
|
||||
# Without `--host`, `litellm` defaults to 0.0.0.0, which combined with
|
||||
# the predictable default `LITELLM_MASTER_KEY=sk-cron-matrix` would
|
||||
# allow anything that can reach :${PROXY_PORT} on the host to authenticate
|
||||
# Without `--host`, `litellm` defaults to 0.0.0.0, so a predictable proxy key
|
||||
# would allow anything that can reach :${PROXY_PORT} on the host to authenticate
|
||||
# and burn upstream provider credentials.
|
||||
#
|
||||
# `setsid` puts the proxy in its own session+pgroup so cleanup() can
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#
|
||||
# Required env (proxy connection), same names as the rest of tests/e2e:
|
||||
# LITELLM_PROXY_URL e.g. http://localhost:4000
|
||||
# LITELLM_MASTER_KEY e.g. sk-1234
|
||||
# LITELLM_MASTER_KEY e.g. sk-<your-master-key>
|
||||
#
|
||||
# Optional env (rate limits, all default to 5 req/s; 0 disables a column):
|
||||
# LITELLM_COMPAT_RATE_ANTHROPIC
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ from pydantic import TypeAdapter
|
|||
load_dotenv(Path(__file__).resolve().parent / ".env", override=False)
|
||||
|
||||
PROXY_BASE_URL = os.environ.get("LITELLM_PROXY_URL", "http://localhost:4000").rstrip("/")
|
||||
MASTER_KEY = os.environ.get("LITELLM_MASTER_KEY", "sk-1234")
|
||||
MASTER_KEY = os.environ["LITELLM_MASTER_KEY"]
|
||||
|
||||
# Control-plane (management/admin) base URL. Defaults to PROXY_BASE_URL so a
|
||||
# single path-routing host (stage ALB, compose monolith) works for both planes.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ if worker_image > /dev/null 2>&1; then
|
|||
fi
|
||||
|
||||
qa_dir=$(mktemp -d)
|
||||
master_key="sk-$(openssl rand -hex 32)"
|
||||
master_key="sk-$(openssl rand -hex 16)"
|
||||
compose=(docker compose -p lens-compose-ci --env-file "$qa_dir/env" -f deploy/lens/stack.yaml)
|
||||
cleanup() {
|
||||
"${compose[@]}" --profile lens down -v --remove-orphans >/dev/null 2>&1 || true
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ def owned_jwt_gateway(
|
|||
"JWT_PUBLIC_KEY_URL": idp.jwks_url,
|
||||
"JWT_ISSUER": idp.issuer,
|
||||
"JWT_AUDIENCE": "litellm-e2e",
|
||||
"LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY": "true",
|
||||
"DISABLE_SCHEMA_UPDATE": "true",
|
||||
"STORE_MODEL_IN_DB": "True",
|
||||
"PYTHONPATH": str(Path(__file__).resolve().parents[3]),
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class TestPlaceholders:
|
|||
("file-XyZ12345abc", "<id>"),
|
||||
("gpt-4o-mini", "gpt-4o-mini"),
|
||||
("max_tokens", "max_tokens"),
|
||||
("sk-1234", "sk-1234"),
|
||||
("sk-9876", "sk-9876"),
|
||||
],
|
||||
)
|
||||
def test_rewrites_exactly_the_volatile_shapes(self, raw: str, expected: str) -> None:
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {
|
|||
INTERNAL_VIEWER_STORAGE_PATH,
|
||||
TEAM_ADMIN_STORAGE_PATH,
|
||||
} from "../constants";
|
||||
import { masterKey } from "../helpers/traffic";
|
||||
|
||||
export enum Role {
|
||||
ProxyAdmin = "proxy_admin",
|
||||
|
|
@ -20,7 +21,7 @@ export type SeedApiRole = "proxy_admin_viewer" | "internal_user" | "internal_use
|
|||
export const users: Record<Role, { email: string; password: string; seedApiRole?: SeedApiRole }> = {
|
||||
[Role.ProxyAdmin]: {
|
||||
email: "admin",
|
||||
password: process.env.LITELLM_MASTER_KEY || "sk-1234",
|
||||
password: masterKey(),
|
||||
},
|
||||
[Role.ProxyAdminViewer]: {
|
||||
email: "adminviewer@test.local",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { users, Role, STORAGE_PATHS } from "./fixtures/users";
|
|||
import { ARTIFACT_DIR, UI_BASE_URL } from "./constants";
|
||||
import { expectUnrestrictedDashboard, setInvitedUserPassword } from "./helpers/userOnboarding";
|
||||
import { hideLiteAdmin } from "./helpers/navigation";
|
||||
import { masterKey as getMasterKey } from "./helpers/traffic";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
|
|
@ -22,7 +23,7 @@ async function globalSetup() {
|
|||
// enable_projects_ui setting is on, and the seeded DB starts with it off.
|
||||
// The proxy runs with LITELLM_LICENSE in CI, so enable it the same way
|
||||
// the admin UI toggle does; the projects migration smoke needs the link.
|
||||
const masterKey = process.env.LITELLM_MASTER_KEY || "sk-1234";
|
||||
const masterKey = getMasterKey();
|
||||
const api = await request.newContext();
|
||||
const settingsRes = await api.patch(`${UI_BASE_URL}${rootPath}/update/ui_settings`, {
|
||||
headers: { Authorization: `Bearer ${masterKey}` },
|
||||
|
|
|
|||
|
|
@ -11,7 +11,13 @@ export const DEPLOYMENT_MODEL_B = "openai/fake-claude";
|
|||
/** The only completion text fixtures/mock_llm_server/server.py ever returns. */
|
||||
export const MOCK_RESPONSE_TEXT = "This is a mock response.";
|
||||
|
||||
export const masterKey = (): string => process.env.LITELLM_MASTER_KEY || "sk-1234";
|
||||
export const masterKey = (): string => {
|
||||
const key = process.env.LITELLM_MASTER_KEY;
|
||||
if (!key) {
|
||||
throw new Error("LITELLM_MASTER_KEY must be set");
|
||||
}
|
||||
return key;
|
||||
};
|
||||
|
||||
export const rootPath = (): string => process.env.SERVER_ROOT_PATH ?? "";
|
||||
|
||||
|
|
|
|||
|
|
@ -144,8 +144,7 @@ else
|
|||
fi
|
||||
|
||||
# --- Credentials ---
|
||||
export LITELLM_MASTER_KEY="sk-1234"
|
||||
export LITELLM_DANGEROUSLY_PERMIT_WEAK_OR_UNSET_MASTER_KEY="true"
|
||||
export LITELLM_MASTER_KEY="${LITELLM_MASTER_KEY:-sk-$(openssl rand -hex 16)}"
|
||||
export MOCK_LLM_URL="http://127.0.0.1:${MOCK_LLM_PORT}/v1"
|
||||
export E2E_MOCK_PRESIDIO_URL="http://127.0.0.1:${MOCK_PRESIDIO_PORT}"
|
||||
export DISABLE_SCHEMA_UPDATE="true"
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ import { execFileSync } from "node:child_process";
|
|||
import * as path from "node:path";
|
||||
import { Page } from "../../fixtures/pages";
|
||||
import { navigateToPage } from "../../helpers/navigation";
|
||||
import { masterKey } from "../../helpers/traffic";
|
||||
|
||||
test("cache leakage by model merges a deployment's resolved and requested model names into its model group", async ({
|
||||
page,
|
||||
}) => {
|
||||
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
|
||||
const master = masterKey();
|
||||
const marker = `integration-browser-${randomUUID()}`;
|
||||
const group = `${marker}-public`;
|
||||
const deployment = `${marker}-backend`;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { test, expect, type APIRequestContext } from "@playwright/test";
|
|||
import { randomUUID } from "node:crypto";
|
||||
import { Page } from "../../fixtures/pages";
|
||||
import { dismissFeedbackPopup, navigateToPage } from "../../helpers/navigation";
|
||||
import { masterKey } from "../../helpers/traffic";
|
||||
|
||||
/**
|
||||
* Credential canary S8: what the Logs page renders for a request, including any client-side
|
||||
|
|
@ -55,7 +56,7 @@ test("the Logs drawer renders the stored request without the deployment api_key"
|
|||
page,
|
||||
request,
|
||||
}) => {
|
||||
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
|
||||
const master = masterKey();
|
||||
const upstream = (
|
||||
process.env.INTEGRATION_UPSTREAM_URL ?? "http://127.0.0.1:8190"
|
||||
).replace(/\/+$/, "");
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ import { randomUUID } from "node:crypto";
|
|||
import { Page } from "../../fixtures/pages";
|
||||
import { navigateToPage } from "../../helpers/navigation";
|
||||
import { captureRequestBody } from "../../helpers/roundTrip";
|
||||
import { masterKey } from "../../helpers/traffic";
|
||||
|
||||
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
|
||||
const master = masterKey();
|
||||
const headers = { Authorization: `Bearer ${master}` };
|
||||
const TOKEN = "USER_TOKEN";
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ import * as path from "node:path";
|
|||
import { Page } from "../../fixtures/pages";
|
||||
import { navigateToPage, openKeyDetail } from "../../helpers/navigation";
|
||||
import { captureRequestBody, readBack } from "../../helpers/roundTrip";
|
||||
import { masterKey } from "../../helpers/traffic";
|
||||
|
||||
test("project creation and explicit detachment preserve saved scope and restore serving", async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
|
||||
const master = masterKey();
|
||||
const headers = { Authorization: `Bearer ${master}` };
|
||||
const prefix = `integration-browser-${randomUUID()}`;
|
||||
// rebind-ok: Register cleanup after each acquisition so partial setup always unwinds in reverse order.
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ import {
|
|||
Page as PlaywrightPage,
|
||||
} from "@playwright/test";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { masterKey } from "../../helpers/traffic";
|
||||
|
||||
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
|
||||
const master = masterKey();
|
||||
const headers = { Authorization: `Bearer ${master}` };
|
||||
|
||||
async function createTeam(request: APIRequestContext): Promise<string> {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ import {
|
|||
Page as PlaywrightPage,
|
||||
} from "@playwright/test";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { masterKey } from "../../helpers/traffic";
|
||||
|
||||
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
|
||||
const master = masterKey();
|
||||
const headers = { Authorization: `Bearer ${master}` };
|
||||
|
||||
async function createTeamCarryingAnEmptyMetadataKey(
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { execFileSync } from "node:child_process";
|
|||
import * as path from "node:path";
|
||||
import { Page } from "../../fixtures/pages";
|
||||
import { dismissFeedbackPopup, navigateToPage } from "../../helpers/navigation";
|
||||
import { masterKey } from "../../helpers/traffic";
|
||||
|
||||
/**
|
||||
* The Tool Policies table gets a User column: the owner of the key that discovered the tool, shown
|
||||
|
|
@ -32,7 +33,7 @@ test("the Tool Policies page names the user behind the key that discovered a too
|
|||
page,
|
||||
request,
|
||||
}) => {
|
||||
const master = process.env.LITELLM_MASTER_KEY ?? "sk-integration-master";
|
||||
const master = masterKey();
|
||||
const upstream = (
|
||||
process.env.INTEGRATION_UPSTREAM_URL ?? "http://127.0.0.1:8190"
|
||||
).replace(/\/+$/, "");
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ test.describe("Public model hub (/ui/model_hub_table)", () => {
|
|||
// The page expects the proxy key as the `key` query param. Use the master
|
||||
// key the e2e runner already exports — this matches what the AI Hub copy
|
||||
// button hands out.
|
||||
const masterKey = process.env.LITELLM_MASTER_KEY || "sk-1234";
|
||||
await page.goto(`/ui/model_hub_table?key=${masterKey}`);
|
||||
await page.goto(`/ui/model_hub_table?key=${masterKey()}`);
|
||||
|
||||
// Dismiss the feedback popup before asserting on the tab, so a popup
|
||||
// race can't briefly mask the tab while we're evaluating visibility.
|
||||
|
|
|
|||
|
|
@ -177,11 +177,11 @@ test.describe("Proxy Admin - Teams", () => {
|
|||
// Restore the seeded models via API in case a prior run (or a CI retry)
|
||||
// left this team mutated — the assertion below requires fake-anthropic-claude
|
||||
// to be present.
|
||||
const masterKey = process.env.LITELLM_MASTER_KEY || "sk-1234";
|
||||
const key = masterKey();
|
||||
const seededModels = ["fake-openai-gpt-4", "fake-anthropic-claude"];
|
||||
const restore = async () => {
|
||||
const res = await request.post("/team/update", {
|
||||
headers: { Authorization: `Bearer ${masterKey}` },
|
||||
headers: { Authorization: `Bearer ${key}` },
|
||||
data: { team_id: E2E_TEAM_CRUD_ID, models: seededModels },
|
||||
});
|
||||
expect(res.ok(), `restore failed: ${res.status()} ${await res.text()}`).toBeTruthy();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue