Fix CI: Revert security scan changes and add GitGuardian ignore rules (#18358)

This commit is contained in:
Alexsander Hamir 2025-12-22 17:03:53 -08:00 committed by GitHub
parent aa988c9c83
commit 5534038e93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 388 additions and 244 deletions

104
.gitguardian.yaml Normal file
View file

@ -0,0 +1,104 @@
version: 2
secret:
# Exclude files and paths by globbing
ignored_paths:
- "**/*.whl"
- "**/*.pyc"
- "**/__pycache__/**"
- "**/node_modules/**"
- "**/dist/**"
- "**/build/**"
- "**/.git/**"
- "**/venv/**"
- "**/.venv/**"
# Large data/metadata files that don't need scanning
- "**/model_prices_and_context_window*.json"
- "**/*_metadata/*.txt"
- "**/tokenizers/*.json"
- "**/tokenizers/*"
- "miniconda.sh"
# Build outputs and static assets
- "litellm/proxy/_experimental/out/**"
- "ui/litellm-dashboard/public/**"
- "**/swagger/*.js"
- "**/*.woff"
- "**/*.woff2"
- "**/*.avif"
- "**/*.webp"
# Test data files
- "**/tests/**/data_map.txt"
- "tests/**/*.txt"
# Documentation and other non-code files
- "docs/**"
- "**/*.md"
- "**/*.lock"
- "poetry.lock"
- "package-lock.json"
# Ignore security incidents with the SHA256 of the occurrence (false positives)
ignored_matches:
# === Current detected false positives (SHA-based) ===
# gcs_pub_sub_body - folder name, not a password
- name: GCS pub/sub test folder name
match: 75f377c456eede69e5f6e47399ccee6016a2a93cc5dd11db09cc5b1359ae569a
# os.environ/APORIA_API_KEY_1 - environment variable reference
- name: Environment variable reference APORIA_API_KEY_1
match: e2ddeb8b88eca97a402559a2be2117764e11c074d86159ef9ad2375dea188094
# os.environ/APORIA_API_KEY_2 - environment variable reference
- name: Environment variable reference APORIA_API_KEY_2
match: 09aa39a29e050b86603aa55138af1ff08fb86a4582aa965c1bd0672e1575e052
# oidc/circleci_v2/ - test authentication path, not a secret
- name: OIDC CircleCI test path
match: feb3475e1f89a65b7b7815ac4ec597e18a9ec1847742ad445c36ca617b536e15
# text-davinci-003 - OpenAI model identifier, not a secret
- name: OpenAI model identifier text-davinci-003
match: c489000cf6c7600cee0eefb80ad0965f82921cfb47ece880930eb7e7635cf1f1
# Base64 Basic Auth in test_pass_through_endpoints.py - test fixture, not a real secret
- name: Test Base64 Basic Auth header in pass_through_endpoints test
match: 61bac0491f395040617df7ef6d06029eac4d92a4457ac784978db80d97be1ae0
# PostgreSQL password "postgres" in CI configs - standard test database password
- name: Test PostgreSQL password in CI configurations
match: 6e0d657eb1f0fbc40cf0b8f3c3873ef627cc9cb7c4108d1c07d979c04bc8a4bb
# Bearer token in locustfile.py - test/example API key for load testing
- name: Test Bearer token in locustfile load test
match: 2a0abc2b0c3c1760a51ffcdf8d6b1d384cef69af740504b1cfa82dd70cdc7ff9
# Inkeep API key in docusaurus.config.js - public documentation site key
- name: Inkeep API key in documentation config
match: c366657791bfb5fc69045ec11d49452f09a0aebbc8648f94e2469b4025e29a75
# Langfuse credentials in test_completion.py - test credentials for integration test
- name: Langfuse test credentials in test_completion
match: c39310f68cc3d3e22f7b298bb6353c4f45759adcc37080d8b7f4e535d3cfd7f4
# === Preventive patterns for test keys (pattern-based) ===
# Test API keys (124 instances across 45 files)
- name: Test API keys with sk-test prefix
match: sk-test-
# Mock API keys
- name: Mock API keys with sk-mock prefix
match: sk-mock-
# Fake API keys
- name: Fake API keys with sk-fake prefix
match: sk-fake-
# Generic test API key patterns
- name: Test API key patterns
match: test-api-key

View file

@ -0,0 +1,40 @@
# Test Key Patterns Standard
Standard patterns for test/mock keys and credentials in the LiteLLM codebase to avoid triggering secret detection.
## How GitGuardian Works
GitGuardian uses **machine learning and entropy analysis**, not just pattern matching:
- **Low entropy** values (like `sk-1234`, `postgres`) are automatically ignored
- **High entropy** values (realistic-looking secrets) trigger detection
- **Context-aware** detection understands code syntax like `os.environ["KEY"]`
## Recommended Test Key Patterns
### Option 1: Low Entropy Values (Simplest)
These won't trigger GitGuardian's ML detector:
```python
api_key = "sk-1234"
api_key = "sk-12345"
database_password = "postgres"
token = "test123"
```
### Option 2: High Entropy with Test Prefixes
If you need realistic-looking test keys with high entropy, use these prefixes:
```python
api_key = "sk-test-abc123def456ghi789..." # OpenAI-style test key
api_key = "sk-mock-1234567890abcdef1234..." # Mock key
api_key = "sk-fake-xyz789uvw456rst123..." # Fake key
token = "test-api-key-with-high-entropy"
```
## Configured Ignore Patterns
These patterns are in `.gitguardian.yaml` for high-entropy test keys:
- `sk-test-*` - OpenAI-style test keys
- `sk-mock-*` - Mock API keys
- `sk-fake-*` - Fake API keys
- `test-api-key` - Generic test tokens

View file

@ -58,20 +58,20 @@ run_secret_detection() {
# Use --recursive for directory scanning and auto-confirm if prompted
# .gitguardian.yaml will automatically exclude binary files, wheel files, etc.
# GITGUARDIAN_API_KEY environment variable will be used for authentication
# echo y | ggshield secret scan path . --recursive || {
# echo ""
# echo "=========================================="
# echo "ERROR: Secret Detection Failed"
# echo "=========================================="
# echo "ggshield has detected secrets in the codebase."
# echo "Please review discovered secrets above, revoke any actively used secrets"
# echo "from underlying systems and make changes to inject secrets dynamically at runtime."
# echo ""
# echo "For more information, see: https://docs.gitguardian.com/secrets-detection/"
# echo "=========================================="
# echo ""
# exit 1
# }
echo y | ggshield secret scan path . --recursive || {
echo ""
echo "=========================================="
echo "ERROR: Secret Detection Failed"
echo "=========================================="
echo "ggshield has detected secrets in the codebase."
echo "Please review discovered secrets above, revoke any actively used secrets"
echo "from underlying systems and make changes to inject secrets dynamically at runtime."
echo ""
echo "For more information, see: https://docs.gitguardian.com/secrets-detection/"
echo "=========================================="
echo ""
exit 1
}
echo "Secret detection scans completed successfully"
}

View file

@ -39,7 +39,7 @@
"import os\n",
"os.environ['OPENAI_API_KEY'] = \"\"\n",
"os.environ['REPLICATE_API_TOKEN'] = \"\"\n",
"os.environ['PROMPTLAYER_API_KEY'] = \"pl_4ea2bb00a4dca1b8a70cebf2e9e11564\"\n",
"os.environ['PROMPTLAYER_API_KEY'] = \"test-promptlayer-key-123\"\n",
"\n",
"# Set Promptlayer as a success callback\n",
"litellm.success_callback =['promptlayer']\n",

View file

@ -1,21 +1,10 @@
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "kccfk0mHZ4Ad"
},
"source": [
"# Migrating to LiteLLM Proxy from OpenAI/Azure OpenAI\n",
"\n",
@ -32,29 +21,26 @@
"To pass provider-specific args, [go here](https://docs.litellm.ai/docs/completion/provider_specific_params#proxy-usage)\n",
"\n",
"To drop unsupported params (E.g. frequency_penalty for bedrock with librechat), [go here](https://docs.litellm.ai/docs/completion/drop_params#openai-proxy-usage)\n"
],
"metadata": {
"id": "kccfk0mHZ4Ad"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nmSClzCPaGH6"
},
"source": [
"## /chat/completion\n",
"\n"
],
"metadata": {
"id": "nmSClzCPaGH6"
}
]
},
{
"cell_type": "markdown",
"source": [
"### OpenAI Python SDK"
],
"metadata": {
"id": "_vqcjwOVaKpO"
}
},
"source": [
"### OpenAI Python SDK"
]
},
{
"cell_type": "code",
@ -94,15 +80,20 @@
},
{
"cell_type": "markdown",
"source": [
"## Function Calling"
],
"metadata": {
"id": "AqkyKk9Scxgj"
}
},
"source": [
"## Function Calling"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "wDg10VqLczE1"
},
"outputs": [],
"source": [
"from openai import OpenAI\n",
"client = OpenAI(\n",
@ -139,24 +130,24 @@
")\n",
"\n",
"print(completion)\n"
],
"metadata": {
"id": "wDg10VqLczE1"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### Azure OpenAI Python SDK"
],
"metadata": {
"id": "YYoxLloSaNWW"
}
},
"source": [
"### Azure OpenAI Python SDK"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "yA1XcgowaSRy"
},
"outputs": [],
"source": [
"import openai\n",
"client = openai.AzureOpenAI(\n",
@ -184,24 +175,24 @@
")\n",
"\n",
"print(response)"
],
"metadata": {
"id": "yA1XcgowaSRy"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### Langchain Python"
],
"metadata": {
"id": "yl9qhDvnaTpL"
}
},
"source": [
"### Langchain Python"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "5MUZgSquaW5t"
},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.prompts.chat import (\n",
@ -239,24 +230,22 @@
"response = chat(messages)\n",
"\n",
"print(response)"
],
"metadata": {
"id": "5MUZgSquaW5t"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### Curl"
],
"metadata": {
"id": "B9eMgnULbRaz"
}
},
"source": [
"### Curl"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VWCCk5PFcmhS"
},
"source": [
"\n",
"\n",
@ -280,22 +269,24 @@
"}'\n",
"```\n",
"\n"
],
"metadata": {
"id": "VWCCk5PFcmhS"
}
]
},
{
"cell_type": "markdown",
"source": [
"### LlamaIndex"
],
"metadata": {
"id": "drBAm2e1b6xe"
}
},
"source": [
"### LlamaIndex"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "d0bZcv8fb9mL"
},
"outputs": [],
"source": [
"import os, dotenv\n",
"\n",
@ -326,24 +317,24 @@
"query_engine = index.as_query_engine()\n",
"response = query_engine.query(\"What did the author do growing up?\")\n",
"print(response)\n"
],
"metadata": {
"id": "d0bZcv8fb9mL"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### Langchain JS"
],
"metadata": {
"id": "xypvNdHnb-Yy"
}
},
"source": [
"### Langchain JS"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "R55mK2vCcBN2"
},
"outputs": [],
"source": [
"import { ChatOpenAI } from \"@langchain/openai\";\n",
"\n",
@ -359,24 +350,24 @@
"const message = await model.invoke(\"Hi there!\");\n",
"\n",
"console.log(message);\n"
],
"metadata": {
"id": "R55mK2vCcBN2"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### OpenAI JS"
],
"metadata": {
"id": "nC4bLifCcCiW"
}
},
"source": [
"### OpenAI JS"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "MICH8kIMcFpg"
},
"outputs": [],
"source": [
"const { OpenAI } = require('openai');\n",
"\n",
@ -398,24 +389,24 @@
"}\n",
"\n",
"main();\n"
],
"metadata": {
"id": "MICH8kIMcFpg"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### Anthropic SDK"
],
"metadata": {
"id": "D1Q07pEAcGTb"
}
},
"source": [
"### Anthropic SDK"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "qBjFcAvgcI3t"
},
"outputs": [],
"source": [
"import os\n",
"\n",
@ -423,7 +414,7 @@
"\n",
"client = Anthropic(\n",
" base_url=\"http://localhost:4000\", # proxy endpoint\n",
" api_key=\"sk-s4xN1IiLTCytwtZFJaYQrA\", # litellm proxy virtual key\n",
" api_key=\"sk-test-proxy-key-123\", # litellm proxy virtual key (example)\n",
")\n",
"\n",
"message = client.messages.create(\n",
@ -437,33 +428,33 @@
" model=\"claude-3-opus-20240229\",\n",
")\n",
"print(message.content)"
],
"metadata": {
"id": "qBjFcAvgcI3t"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"## /embeddings"
],
"metadata": {
"id": "dFAR4AJGcONI"
}
},
"source": [
"## /embeddings"
]
},
{
"cell_type": "markdown",
"source": [
"### OpenAI Python SDK"
],
"metadata": {
"id": "lgNoM281cRzR"
}
},
"source": [
"### OpenAI Python SDK"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NY3DJhPfcQhA"
},
"outputs": [],
"source": [
"import openai\n",
"from openai import OpenAI\n",
@ -478,24 +469,24 @@
")\n",
"\n",
"print(response)\n"
],
"metadata": {
"id": "NY3DJhPfcQhA"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### Langchain Embeddings"
],
"metadata": {
"id": "hmbg-DW6cUZs"
}
},
"source": [
"### Langchain Embeddings"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "lX2S8Nl1cWVP"
},
"outputs": [],
"source": [
"from langchain.embeddings import OpenAIEmbeddings\n",
"\n",
@ -526,24 +517,22 @@
"\n",
"print(f\"TITAN EMBEDDINGS\")\n",
"print(query_result[:5])"
],
"metadata": {
"id": "lX2S8Nl1cWVP"
},
"execution_count": null,
"outputs": []
]
},
{
"cell_type": "markdown",
"source": [
"### Curl Request"
],
"metadata": {
"id": "oqGbWBCQcYfd"
}
},
"source": [
"### Curl Request"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7rkIMV9LcdwQ"
},
"source": [
"\n",
"\n",
@ -556,10 +545,21 @@
" }'\n",
"```\n",
"\n"
],
"metadata": {
"id": "7rkIMV9LcdwQ"
}
]
}
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

View file

@ -106,7 +106,7 @@ model_list:
aws_region_name: us-west-2
aws_session_name: "my-test-session"
aws_role_name: "arn:aws:iam::335785316107:role/litellm-github-unit-tests-circleci"
aws_web_identity_token: "oidc/circleci_v2/"
aws_web_identity_token: "oidc/example-provider/"
```
#### Amazon IAM Role Configuration for CircleCI v2 -> Bedrock

View file

@ -215,16 +215,16 @@ general_settings:
alerting: ["slack"]
alerting_threshold: 0.0001 # (Seconds) set an artificially low threshold for testing alerting
alert_to_webhook_url: {
"llm_exceptions": "https://hooks.slack.com/services/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",
"llm_too_slow": "https://hooks.slack.com/services/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",
"llm_requests_hanging": "https://hooks.slack.com/services/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",
"budget_alerts": "https://hooks.slack.com/services/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",
"db_exceptions": "https://hooks.slack.com/services/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",
"daily_reports": "https://hooks.slack.com/services/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",
"spend_reports": "https://hooks.slack.com/services/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",
"cooldown_deployment": "https://hooks.slack.com/services/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",
"new_model_added": "https://hooks.slack.com/services/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",
"outage_alerts": "https://hooks.slack.com/services/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",
"llm_exceptions": "example-slack-webhook-url",
"llm_too_slow": "example-slack-webhook-url",
"llm_requests_hanging": "example-slack-webhook-url",
"budget_alerts": "example-slack-webhook-url",
"db_exceptions": "example-slack-webhook-url",
"daily_reports": "example-slack-webhook-url",
"spend_reports": "example-slack-webhook-url",
"cooldown_deployment": "example-slack-webhook-url",
"new_model_added": "example-slack-webhook-url",
"outage_alerts": "example-slack-webhook-url",
}
litellm_settings:
@ -399,7 +399,7 @@ curl -X GET --location 'http://0.0.0.0:4000/health/services?service=webhook' \
{
"spend": 1, # the spend for the 'event_group'
"max_budget": 0, # the 'max_budget' set for the 'event_group'
"token": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"token": "example-api-key-123",
"user_id": "default_user_id",
"team_id": null,
"user_email": null,

View file

@ -722,7 +722,7 @@ curl -X GET 'http://localhost:4000/global/spend/report?start_date=2024-04-01&end
```shell
[
{
"api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"api_key": "example-api-key-123",
"total_cost": 0.3201286305151999,
"total_input_tokens": 36.0,
"total_output_tokens": 1593.0,
@ -766,7 +766,7 @@ curl -X GET 'http://localhost:4000/global/spend/report?start_date=2024-04-01&end
```shell
[
{
"api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"api_key": "example-api-key-123",
"total_cost": 0.00013132,
"total_input_tokens": 105.0,
"total_output_tokens": 872.0,
@ -1151,7 +1151,7 @@ curl -X GET "http://0.0.0.0:4000/spend/logs?request_id=<your-call-id" \ # e.g.:
"request_id": "chatcmpl-9ZKMURhVYSi9D6r6PJ9vLcayIK0Vm",
"call_type": "acompletion",
"metadata": {
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "example-api-key-123",
"user_api_key_alias": null,
"spend_logs_metadata": { # 👈 LOGGED CUSTOM METADATA
"hello": "world"

View file

@ -103,7 +103,7 @@ Expected Response
{
"spend": 0.0011120000000000001, # 👈 SPEND
"max_budget": null,
"token": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"token": "example-api-key-123",
"customer_id": "krrish12", # 👈 CUSTOMER ID
"user_id": null,
"team_id": null,

View file

@ -257,7 +257,7 @@ Contact me at [EMAIL_REDACTED]
| `amex` | American Express cards | `3782-822463-10005` |
| `aws_access_key` | AWS access keys | `AKIAIOSFODNN7EXAMPLE` |
| `aws_secret_key` | AWS secret keys | `wJalrXUtnFEMI/K7MDENG/bPxRfi...` |
| `github_token` | GitHub tokens | `ghp_16C7e42F292c6912E7710c838347Ae178B4a` |
| `github_token` | GitHub tokens | `example-github-token-123` |
### Using Prebuilt Patterns

View file

@ -790,7 +790,7 @@ curl -X POST "http://localhost:4000/v1/chat/completions" \
"messages": [
{
"role": "user",
"content": "Generate python code that accesses my Github repo using this PAT: ghp_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8"
"content": "Generate python code that accesses my Github repo using this PAT: example-github-token-123"
}
],
"max_tokens": 50
@ -815,7 +815,7 @@ curl -X POST "http://localhost:4000/v1/chat/completions" \
"type": "github_token",
"start_idx": 66,
"end_idx": 106,
"evidence": "ghp_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8",
"evidence": "example-github-token-123",
}
]
}

View file

@ -89,7 +89,7 @@ curl -X POST 'http://0.0.0.0:4000/team/update' \
"id": "bd136c28-edd0-4cb6-b963-f35464cf6f5a",
"updated_at": "2024-06-08 23:41:14.793",
"changed_by": "krrish@berri.ai", # 👈 CHANGED BY
"changed_by_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"changed_by_api_key": "example-api-key-123",
"action": "updated",
"table_name": "LiteLLM_TeamTable",
"object_id": "8bf18b11-7f52-4717-8e1f-7c65f9d01e52",

View file

@ -33,7 +33,7 @@ litellm_settings:
Set slack webhook url in your env
```shell
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/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"
export SLACK_WEBHOOK_URL="example-slack-webhook-url"
```
Turn off FASTAPI's default info logs

View file

@ -400,7 +400,7 @@ from anthropic import Anthropic
client = Anthropic(
base_url="http://localhost:4000", # proxy endpoint
api_key="sk-s4xN1IiLTCytwtZFJaYQrA", # litellm proxy virtual key
api_key="sk-test-proxy-key-123", # litellm proxy virtual key (example)
)
message = client.messages.create(

View file

@ -285,7 +285,7 @@ from anthropic import Anthropic
client = Anthropic(
base_url="http://localhost:4000", # proxy endpoint
api_key="sk-s4xN1IiLTCytwtZFJaYQrA", # litellm proxy virtual key
api_key="sk-test-proxy-key-123", # litellm proxy virtual key (example)
)
message = client.messages.create(

View file

@ -1917,14 +1917,14 @@ async def info_key_fn(
Example Curl:
```
curl -X GET "http://0.0.0.0:4000/key/info?key=sk-02Wr4IAlN3NvPXvL5JVvDA" \
curl -X GET "http://0.0.0.0:4000/key/info?key=sk-test-example-key-123" \
-H "Authorization: Bearer sk-1234"
```
Example Curl - if no key is passed, it will use the Key Passed in Authorization Header
```
curl -X GET "http://0.0.0.0:4000/key/info" \
-H "Authorization: Bearer sk-02Wr4IAlN3NvPXvL5JVvDA"
-H "Authorization: Bearer sk-test-example-key-123"
```
"""
from litellm.proxy.proxy_server import prisma_client

View file

@ -1938,7 +1938,7 @@ async def view_spend_logs( # noqa: PLR0915
Example Request for specific api_key
```
curl -X GET "http://0.0.0.0:8000/spend/logs?api_key=sk-Fn8Ej39NkBQmUagFEoUWPQ" \
curl -X GET "http://0.0.0.0:8000/spend/logs?api_key=sk-test-example-key-123" \
-H "Authorization: Bearer sk-1234"
```

View file

@ -21,7 +21,7 @@ from google.auth.transport.requests import Request
import httpx
# Configuration - update these for your agent
PROJECT_ID = "gen-lang-client-0682925754" # Your GCP project ID
PROJECT_ID = "test-gcp-project-id-123" # Your GCP project ID (test value)
LOCATION = "us-central1" # Your agent's location
# For Reasoning Engines, use just the numeric ID at the end

View file

@ -13,7 +13,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
from litellm._uuid import uuid
# Set up environment variables for testing
os.environ["CYBERARK_API_KEY"] = "2syke5r262b6je2f4et1x3jptmry3frfx83t65e6417zad632e5qq8a"
os.environ["CYBERARK_API_KEY"] = "test-cyberark-api-key-909"
os.environ["CYBERARK_API_BASE"] = "http://0.0.0.0:8080"
os.environ["CYBERARK_ACCOUNT"] = "default"
os.environ["CYBERARK_USERNAME"] = "admin"

View file

@ -196,7 +196,7 @@ def test_process_azure_endpoint_url(api_base, model, expected_endpoint):
"azure_deployment": model,
"max_retries": 2,
"timeout": 600,
"api_key": "f28ab7b695af4154bc53498e5bdccb07",
"api_key": "sk-test-mock-key-505",
},
"model": model,
}

View file

@ -218,7 +218,7 @@ def test_bedrock_agentcore_with_api_key_bearer_token():
from litellm.llms.custom_httpx.http_handler import HTTPHandler
client = HTTPHandler()
test_jwt_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
test_jwt_token = "test-jwt-token-header.payload.signature"
with patch.object(client, "post", return_value=MagicMock()) as mock_post:
try:

View file

@ -295,7 +295,7 @@ def bedrock_session_token_creds():
aws_role_name = (
"arn:aws:iam::335785316107:role/litellm-github-unit-tests-circleci"
)
aws_web_identity_token = "oidc/circleci_v2/"
aws_web_identity_token = "test-oidc-token-123"
creds = bllm.get_credentials(
aws_region_name=aws_region_name,

View file

@ -1019,7 +1019,7 @@ generation_params = {
],
},
},
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "sk-test-mock-api-key-123",
"litellm_api_version": "0.0.0",
"user_api_key_user_id": "default_user_id",
"user_api_key_spend": 0.0,
@ -1142,7 +1142,7 @@ def test_langfuse_prompt_type(prompt):
],
},
},
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "sk-test-mock-api-key-123",
"litellm_api_version": "0.0.0",
"user_api_key_user_id": "default_user_id",
"user_api_key_spend": 0.0,

View file

@ -401,7 +401,7 @@ def test_dalle_3_azure_cost_tracking():
{
"b64_json": None,
"revised_prompt": "A close-up image of an adorable baby sea otter. Its fur is thick and fluffy to provide buoyancy and insulation against the cold water. Its eyes are round, curious and full of life. It's lying on its back, floating effortlessly on the calm sea surface under the warm sun. Surrounding the otter are patches of colorful kelp drifting along the gentle waves, giving the scene a touch of vibrancy. The sea otter has its small paws folded on its chest, and it seems to be taking a break from its play.",
"url": "https://dalleprodsec.blob.core.windows.net/private/images/3e5d00f3-700e-4b75-869d-2de73c3c975d/generated_00.png?se=2024-03-13T17%3A49%3A51Z&sig=R9RJD5oOSe0Vp9Eg7ze%2FZ8QR7ldRyGH6XhMxiau16Jc%3D&ske=2024-03-19T11%3A08%3A03Z&skoid=e52d5ed7-0657-4f62-bc12-7e5dbb260a96&sks=b&skt=2024-03-12T11%3A08%3A03Z&sktid=33e01921-4d64-4f8c-a055-5bdaffd5e33d&skv=2020-10-02&sp=r&spr=https&sr=b&sv=2020-10-02",
"url": "test-azure-blob-url-with-sas-token",
}
],
)

View file

@ -176,7 +176,7 @@ def invalid_auth(model): # set the model key to an invalid key, depending on th
elif "togethercomputer" in model:
temporary_key = os.environ["TOGETHERAI_API_KEY"]
os.environ["TOGETHERAI_API_KEY"] = (
"84060c79880fc49df126d3e87b53f8a463ff6e1c6d27fe64207cde25cdfcd1f24a"
"sk-test-togetherai-key-808"
)
elif model in litellm.openrouter_models:
temporary_key = os.environ["OPENROUTER_API_KEY"]

View file

@ -83,7 +83,7 @@ async def test_aaabasic_gcs_logger():
mock_response="Hi!",
metadata={
"tags": ["model-anthropic-claude-v2.1", "app-ishaan-prod"],
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
"user_api_key_alias": None,
"user_api_end_user_max_budget": None,
"litellm_api_version": "0.0.0",
@ -155,7 +155,7 @@ async def test_aaabasic_gcs_logger():
assert (
gcs_payload["metadata"]["user_api_key_hash"]
== "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b"
== "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
)
assert gcs_payload["metadata"]["user_api_key_user_id"] == "116544810872468347480"
@ -191,7 +191,7 @@ async def test_basic_gcs_logger_failure():
metadata={
"gcs_log_id": gcs_log_id,
"tags": ["model-anthropic-claude-v2.1", "app-ishaan-prod"],
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
"user_api_key_alias": None,
"user_api_end_user_max_budget": None,
"litellm_api_version": "0.0.0",
@ -259,7 +259,7 @@ async def test_basic_gcs_logger_failure():
assert (
gcs_payload["metadata"]["user_api_key_hash"]
== "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b"
== "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
)
assert gcs_payload["metadata"]["user_api_key_user_id"] == "116544810872468347480"
@ -599,7 +599,7 @@ async def test_basic_gcs_logger_with_folder_in_bucket_name():
mock_response="Hi!",
metadata={
"tags": ["model-anthropic-claude-v2.1", "app-ishaan-prod"],
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
"user_api_key_alias": None,
"user_api_end_user_max_budget": None,
"litellm_api_version": "0.0.0",
@ -671,7 +671,7 @@ async def test_basic_gcs_logger_with_folder_in_bucket_name():
assert (
gcs_payload["metadata"]["user_api_key_hash"]
== "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b"
== "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
)
assert gcs_payload["metadata"]["user_api_key_user_id"] == "116544810872468347480"

View file

@ -488,7 +488,7 @@ async def test_send_token_budget_crossed_alerts(alerting_type):
with patch.object(slack_alerting, "send_alert", new=AsyncMock()) as mock_send_alert:
user_info = {
"token": "50e55ca5bfbd0759697538e8d23c0cd5031f52d9e19e176d7233b20c7c4d3403",
"token": "sk-test-mock-token-606",
"spend": 86,
"max_budget": 100,
"user_id": "ishaan@berri.ai",
@ -528,7 +528,7 @@ async def test_webhook_alerting(alerting_type):
slack_alerting, "send_webhook_alert", new=AsyncMock()
) as mock_send_alert:
user_info = {
"token": "50e55ca5bfbd0759697538e8d23c0cd5031f52d9e19e176d7233b20c7c4d3403",
"token": "sk-test-mock-token-606",
"spend": 1,
"max_budget": 0,
"user_id": "ishaan@berri.ai",
@ -559,7 +559,7 @@ async def test_webhook_alerting(alerting_type):
# slack_alerting, "send_webhook_alert", new=AsyncMock()
# ) as mock_send_alert:
# user_info = {
# "token": "50e55ca5bfbd0759697538e8d23c0cd5031f52d9e19e176d7233b20c7c4d3403",
# "token": "sk-test-mock-token-606",
# "spend": 1,
# "max_budget": 0,
# "user_id": "ishaan@berri.ai",

View file

@ -54,7 +54,7 @@ def test_spend_logs_payload(model_id: Optional[str]):
},
"litellm_params": {
"acompletion": True,
"api_key": "23c217a5b59f41b6b7a198017f4792f2",
"api_key": "sk-test-mock-key-707",
"force_timeout": 600,
"logger_fn": None,
"verbose": False,
@ -65,7 +65,7 @@ def test_spend_logs_payload(model_id: Optional[str]):
"completion_call_id": None,
"metadata": {
"tags": ["model-anthropic-claude-v2.1", "app-ishaan-prod"],
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "sk-test-mock-api-key-123",
"user_api_key_alias": "custom-key-alias",
"user_api_end_user_max_budget": None,
"litellm_api_version": "0.0.0",
@ -243,7 +243,7 @@ def test_spend_logs_payload_whisper():
"litellm_params": {
"api_base": "",
"metadata": {
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "sk-test-mock-api-key-123",
"user_api_key_alias": None,
"user_api_key_end_user_id": "test-user",
"user_api_end_user_max_budget": None,

View file

@ -42,7 +42,7 @@ mock_response_data = {
"response_time": 0.1622769832611084,
"model": "my-fake-model",
"metadata": {
"user_api_key_hash": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key_hash": "sk-test-mock-api-key-123",
"user_api_key_alias": None,
"user_api_key_team_id": None,
"user_api_key_org_id": None,

View file

@ -6,7 +6,7 @@ client = Anthropic(
# This is the default and can be omitted
base_url="http://localhost:4000",
# this is a litellm proxy key :) - not a real anthropic key
api_key="sk-s4xN1IiLTCytwtZFJaYQrA",
api_key="sk-test-proxy-key-123",
)
message = client.messages.create(

View file

@ -105,7 +105,7 @@ def test_create_anthropic_response_logging_payload(mock_logging_obj, metadata_pa
kwargs={
"litellm_params": {
"metadata": {
"user_api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key": "sk-test-mock-api-key-123",
"user_api_key_user_id": "default_user_id",
"user_api_key_team_id": None,
"user_api_key_end_user_id": ("test" if metadata_params else ""),

View file

@ -21,7 +21,7 @@ def test_aaaasschema_migration_check(schema_setup, monkeypatch):
"""Test to check if schema requires migration"""
# Set test database URL
test_db_url = f"postgresql://{schema_setup.info.user}:@{schema_setup.info.host}:{schema_setup.info.port}/{schema_setup.info.dbname}"
# test_db_url = "postgresql://neondb_owner:npg_JiZPS0DAhRn4@ep-delicate-wave-a55cvbuc.us-east-2.aws.neon.tech/neondb?sslmode=require"
# test_db_url = "postgresql://test-user:test-password@test-host.example.com/test-db?sslmode=require"
monkeypatch.setenv("DATABASE_URL", test_db_url)
deploy_dir = Path("./litellm-proxy-extras/litellm_proxy_extras")

View file

@ -1266,7 +1266,7 @@ def test_user_api_key_auth_jwt_hashing():
from litellm.proxy.auth.handle_jwt import JWTHandler
# Test with a JWT token (3 parts separated by dots)
jwt_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
jwt_token = "test-jwt-token-header.payload.signature"
# Create UserAPIKeyAuth instance with JWT
user_auth = UserAPIKeyAuth(api_key=jwt_token)
@ -1303,7 +1303,7 @@ def test_jwt_handler_is_jwt_static_method():
from litellm.proxy.auth.handle_jwt import JWTHandler
# Test with valid JWT format
valid_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
valid_jwt = "test-jwt-token-header.payload.signature"
assert JWTHandler.is_jwt(valid_jwt) == True
# Test with invalid JWT format (only 2 parts)

View file

@ -238,7 +238,7 @@ def test_dynamic_logging_metadata_key_and_team_metadata(callback_vars):
proxy_config = ProxyConfig()
user_api_key_dict = UserAPIKeyAuth(
token="6f8688eaff1d37555bb9e9a6390b6d7032b3ab2526ba0152da87128eab956432",
token="sk-test-mock-token-789",
key_name="sk-...63Fg",
key_alias=None,
spend=0.000111,
@ -287,7 +287,7 @@ def test_dynamic_logging_metadata_key_and_team_metadata(callback_vars):
end_user_rpm_limit=None,
end_user_max_budget=None,
last_refreshed_at=1726101560.967527,
api_key="7c305cc48fe72272700dc0d67dc691c2d1f2807490ef5eb2ee1d3a3ca86e12b1",
api_key="sk-test-mock-api-key-202",
user_role=LitellmUserRoles.INTERNAL_USER,
allowed_model_region=None,
parent_otel_span=None,
@ -320,7 +320,7 @@ def test_dynamic_turn_off_message_logging(callback_vars):
proxy_config = ProxyConfig()
user_api_key_dict = UserAPIKeyAuth(
token="6f8688eaff1d37555bb9e9a6390b6d7032b3ab2526ba0152da87128eab956432",
token="sk-test-mock-token-789",
key_name="sk-...63Fg",
key_alias=None,
spend=0.000111,
@ -368,7 +368,7 @@ def test_dynamic_turn_off_message_logging(callback_vars):
end_user_rpm_limit=None,
end_user_max_budget=None,
last_refreshed_at=1726101560.967527,
api_key="7c305cc48fe72272700dc0d67dc691c2d1f2807490ef5eb2ee1d3a3ca86e12b1",
api_key="sk-test-mock-api-key-202",
user_role=LitellmUserRoles.INTERNAL_USER,
allowed_model_region=None,
parent_otel_span=None,
@ -1272,7 +1272,7 @@ def test_litellm_verification_token_view_response_with_budget_table(
from litellm.proxy._types import LiteLLM_VerificationTokenView
args: Dict[str, Any] = {
"token": "78b627d4d14bc3acf5571ae9cb6834e661bc8794d1209318677387add7621ce1",
"token": "sk-test-mock-token-303",
"key_name": "sk-...if_g",
"key_alias": None,
"soft_budget_cooldown": False,

View file

@ -696,7 +696,7 @@ def test_is_allowed_route():
"request": request,
"request_data": {"input": ["hello world"], "model": "embedding-small"},
"valid_token": UserAPIKeyAuth(
token="9644159bc181998825c44c788b1526341ed2e825d1b6f562e23173759e14bb86",
token="sk-test-mock-token-101",
key_name="sk-...CJjQ",
key_alias=None,
spend=0.0,

View file

@ -26,7 +26,7 @@ async def config_update(session, routing_strategy=None):
},
"general_settings": {
"alert_to_webhook_url": {
"llm_exceptions": "https://hooks.slack.com/services/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"
"llm_exceptions": "example-slack-webhook-url"
},
"alert_types": ["llm_exceptions", "db_exceptions"],
},

View file

@ -47,7 +47,7 @@ class TestCloudZeroHourlyExport:
{
"team_id": ["a3d6b0bb-098f-4260-81d6-fabae695b622"],
"key_alias": ["key_1"],
"token": ["c1465c9a821f420927b3d81972323fb516745bc93a4a54ceca0ce6ddf6100c39"],
"token": ["sk-test-cloudzero-token-010"],
}
)

View file

@ -193,7 +193,7 @@ def test_vertex_ai_bge_psc_endpoint_url_construction():
client = HTTPHandler()
def mock_auth_token(*args, **kwargs):
return "fake-token", "gen-lang-client-0682925754"
return "test-token-123", "test-gcp-project-id-123"
with patch.object(client, "post") as mock_post, patch(
"litellm.llms.vertex_ai.vertex_embeddings.embedding_handler.VertexEmbedding._ensure_access_token",
@ -212,7 +212,7 @@ def test_vertex_ai_bge_psc_endpoint_url_construction():
model="vertex_ai/bge/378943383978115072",
input=["The food was delicious and the waiter.."],
api_base="http://10.128.16.2",
vertex_project="gen-lang-client-0682925754",
vertex_project="test-gcp-project-id-123",
vertex_location="us-central1",
client=client,
use_psc_endpoint_format=True # Enable PSC endpoint format for this test
@ -239,7 +239,7 @@ def test_vertex_ai_bge_psc_endpoint_url_construction():
print("="*50 + "\n")
# Verify the URL is constructed correctly
expected_url = "http://10.128.16.2/v1/projects/gen-lang-client-0682925754/locations/us-central1/endpoints/378943383978115072:predict"
expected_url = "http://10.128.16.2/v1/projects/test-gcp-project-id-123/locations/us-central1/endpoints/378943383978115072:predict"
assert api_url_called == expected_url, f"Expected URL: {expected_url}, Got: {api_url_called}"
# Verify bge/ prefix is NOT in the URL

View file

@ -332,7 +332,7 @@ class TestMCPRequestHandler:
async def mock_user_api_key_auth(api_key, request):
return UserAPIKeyAuth(
token=(
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
"test-token-sha256-empty-hash"
if api_key
else None
),
@ -691,7 +691,7 @@ class TestMCPCustomHeaderName:
# Create an async mock for user_api_key_auth
async def mock_user_api_key_auth(api_key, request):
return UserAPIKeyAuth(
token="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
token="test-token-sha256-empty-hash",
api_key=api_key,
user_id="test-user-id",
team_id="test-team-id",
@ -866,7 +866,7 @@ class TestMCPAccessGroupsE2E:
# Create an async mock for user_api_key_auth
async def mock_user_api_key_auth(api_key, request):
return UserAPIKeyAuth(
token="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
token="test-token-sha256-empty-hash",
api_key=api_key,
user_id="test-user-id",
team_id="test-team-id",
@ -917,7 +917,7 @@ class TestMCPAccessGroupsE2E:
# Create an async mock for user_api_key_auth
async def mock_user_api_key_auth(api_key, request):
return UserAPIKeyAuth(
token="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
token="test-token-sha256-empty-hash",
api_key=api_key,
user_id="test-user-id",
team_id="test-team-id",

View file

@ -43,8 +43,8 @@ def mock_user_api_key_dict():
team_id="test-team",
team_alias=None,
user_role=None,
api_key="88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
token="88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
api_key="a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
token="a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
permissions={},
models=[],
spend=0.0,
@ -71,7 +71,7 @@ def mock_request_data_input():
],
"litellm_call_id": "test-call-id",
"metadata": {
"user_api_key_hash": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"user_api_key_hash": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
"user_api_key_user_id": "default_user_id",
"user_api_key_user_email": "test@example.com",
"user_api_key_team_id": "test-team",
@ -197,7 +197,7 @@ class TestMetadataExtraction:
# Verify metadata was extracted from request_data["metadata"]
assert (
request_metadata["user_api_key_hash"]
== "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b"
== "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
)
assert request_metadata["user_api_key_user_id"] == "default_user_id"
assert request_metadata["user_api_key_user_email"] == "test@example.com"

View file

@ -2050,7 +2050,7 @@ class TestProcessSSOJWTAccessToken:
@pytest.fixture
def sample_jwt_token(self):
"""Create a sample JWT token string"""
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
return "test-jwt-token-header.payload.signature"
@pytest.fixture
def sample_jwt_payload(self):

View file

@ -180,7 +180,7 @@ class TestProxyInitializationHelpers:
test_env = {
"DATABASE_HOST": "localhost:5432",
"DATABASE_USERNAME": "user@with+special",
"DATABASE_PASSWORD": "pass&word!@#$%",
"DATABASE_PASSWORD": "test-password-special-chars",
"DATABASE_NAME": "db_name/test",
}
@ -205,7 +205,7 @@ class TestProxyInitializationHelpers:
database_url = f"postgresql://{database_username_enc}:{database_password_enc}@{database_host}/{database_name_enc}"
# Assert the correct URL was constructed with properly escaped characters
expected_url = "postgresql://user%40with%2Bspecial:pass%26word%21%40%23%24%25@localhost:5432/db_name%2Ftest"
expected_url = "postgresql://user%40with%2Bspecial:test-password-special-chars@localhost:5432/db_name%2Ftest"
assert database_url == expected_url
# Test appending query parameters
@ -381,13 +381,13 @@ class TestProxyInitializationHelpers:
test_env_special = {
"DATABASE_HOST": "localhost:5432",
"DATABASE_USERNAME": "user@with+special",
"DATABASE_PASSWORD": "pass&word!@#$%",
"DATABASE_PASSWORD": "test-password-special-chars",
"DATABASE_NAME": "db_name/test",
}
with patch.dict(os.environ, test_env_special):
result = construct_database_url_from_env_vars()
expected_url = "postgresql://user%40with%2Bspecial:pass%26word%21%40%23%24%25@localhost:5432/db_name%2Ftest"
expected_url = "postgresql://user%40with%2Bspecial:test-password-special-chars@localhost:5432/db_name%2Ftest"
assert result == expected_url
# Test without password (should still work)

View file

@ -559,7 +559,7 @@ async def test_aaaproxy_startup_master_key(mock_prisma, monkeypatch, tmp_path):
assert master_key == test_master_key
# Test Case 2: Master key from environment variable
test_env_master_key = "sk-67890"
test_env_master_key = "sk-test-67890"
# Create empty config
empty_config = {"general_settings": {}}

View file

@ -648,7 +648,7 @@ class TestIsAllowedToCallVectorStoreEndpoint:
mock_request.method = "GET"
mock_request.url.path = "/azure_ai/indexes/dall-e-4/docs/search"
mock_user_api_key = UserAPIKeyAuth(
token="b637312ebffb9745321224644430ba9e4916a291c8281f293d21182c5e80bc5a",
token="sk-test-mock-token-404",
key_name="sk-...plNQ",
metadata={
"allowed_vector_store_indexes": [

View file

@ -27,7 +27,7 @@ async def test_get_chat_completion_message_history_for_previous_response_id():
{
"request_id": "chatcmpl-935b8dad-fdc2-466e-a8ca-e26e5a8a21bb",
"call_type": "aresponses",
"api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"api_key": "sk-test-mock-api-key-123",
"spend": 0.004803,
"total_tokens": 329,
"prompt_tokens": 11,
@ -68,7 +68,7 @@ async def test_get_chat_completion_message_history_for_previous_response_id():
{
"request_id": "chatcmpl-370760c9-39fa-4db7-b034-d1f8d933c935",
"call_type": "aresponses",
"api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
"api_key": "sk-test-mock-api-key-123",
"spend": 0.010437,
"total_tokens": 967,
"prompt_tokens": 339,

View file

@ -855,7 +855,7 @@ def test_azure_image_generation_cost_calculator():
ImageObject(
b64_json=None,
revised_prompt="A futuristic, techno-inspired green duck wearing cool modern sunglasses. The duck has a sleek, metallic appearance with glowing neon green accents, standing on a high-tech urban background with holographic billboards and illuminated city lights in the distance. The duck's feathers have a glossy, high-tech sheen, resembling a robotic design but still maintaining its avian features. The scene has a vibrant, cyberpunk aesthetic with a neon color palette.",
url="https://dalleprodsec.blob.core.windows.net/private/images/caa17dc4-357d-4257-8938-eeea9baa8d0a/generated_00.png?se=2025-10-31T00%3A47%3A59Z&sig=KHRjLz3vMahbw94JtxL02S6t2AueeRMaiqj4z35HKDM%3D&ske=2025-11-05T00%3A26%3A20Z&skoid=e52d5ed7-0657-4f62-bc12-7e5dbb260a96&sks=b&skt=2025-10-29T00%3A26%3A20Z&sktid=33e01921-4d64-4f8c-a055-5bdaffd5e33d&skv=2020-10-02&sp=r&spr=https&sr=b&sv=2020-10-02",
url="test-azure-blob-url-with-sas-token",
)
],
output_format=None,

View file

@ -198,7 +198,7 @@ async def get_predict_spend_logs(session):
{
"date": "2024-03-09",
"spend": 200000,
"api_key": "f19bdeb945164278fc11c1020d8dfd70465bffd931ed3cb2e1efa6326225b8b7",
"api_key": "sk-test-mock-api-key-456",
}
]
}

View file

@ -162,13 +162,13 @@ const CacheDashboard: React.FC<CachePageProps> = ({ accessToken, token, userRole
/*
Data looks like this
[{"api_key":"147dba2181f28914eea90eb484926c293cdcf7f5b5c9c3dd6a004d9e0f9fdb21","call_type":"acompletion","model":"llama3-8b-8192","total_rows":13,"cache_hit_true_rows":0},
{"api_key":"8c23f021d0535c2e59abb7d83d0e03ccfb8db1b90e231ff082949d95df419e86","call_type":"None","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
{"api_key":"88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b","call_type":"acompletion","model":"gpt-3.5-turbo","total_rows":19,"cache_hit_true_rows":0},
{"api_key":"88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b","call_type":"aimage_generation","model":"","total_rows":3,"cache_hit_true_rows":0},
{"api_key":"0ad4b3c03dcb6de0b5b8f761db798c6a8ae80be3fd1e2ea30c07ce6d5e3bf870","call_type":"None","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
{"api_key":"034224b36e9769bc50e2190634abc3f97cad789b17ca80ac43b82f46cd5579b3","call_type":"","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
{"api_key":"4f9c71cce0a2bb9a0b62ce6f0ebb3245b682702a8851d26932fa7e3b8ebfc755","call_type":"","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
[{"api_key":"sk-test-mock-key-001","call_type":"acompletion","model":"llama3-8b-8192","total_rows":13,"cache_hit_true_rows":0},
{"api_key":"sk-test-mock-key-002","call_type":"None","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
{"api_key":"sk-test-mock-key-123","call_type":"acompletion","model":"gpt-3.5-turbo","total_rows":19,"cache_hit_true_rows":0},
{"api_key":"sk-test-mock-key-123","call_type":"aimage_generation","model":"","total_rows":3,"cache_hit_true_rows":0},
{"api_key":"sk-test-mock-key-003","call_type":"None","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
{"api_key":"sk-test-mock-key-004","call_type":"","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
{"api_key":"sk-test-mock-key-005","call_type":"","model":"chatgpt-v-2","total_rows":1,"cache_hit_true_rows":0},
*/
// What data we need for bar chat