mirror of
https://github.com/tiennm99/litellm.git
synced 2026-06-17 18:48:36 +00:00
a44bc9f613
* refactor(litellm/): wrap enterprise package usage in safe try-excepts prevents missing package error for OSS users Fixes https://github.com/BerriAI/litellm/issues/10795 * ci(config.yml): add script to check for unsafe imports to ci/cd Closes https://github.com/BerriAI/litellm/issues/10795 * fix: add missing docs * test: test_openai_image_edit_litellm_sdk * use n 4 for mapped tests (#11109) * Fix/background health check (#10887) * fix: improve health check logic by deep copying model list on each iteration * test: add async test for background health check reflecting model list changes * fix: validate health check interval before executing background health check * fix: specify type for health check results dictionary * fix(user_api_key_auth.py): handle user custom auth set with no custom settings * bump: version 0.1.21 → 0.2.0 * ci(config.yml): run enterprise and litellm tests separately * fix: fix linting error * docs: add missing docs * [Feat] Add content policy violation error mapping for image editd (#11113) * feat: add image edit mapping for content policy violations * test fix * Expose `/list` and `/info` endpoints for Audit Log events (#11102) * feat(audit_logging_endpoints.py): expose list endpoint to show all audit logs make it easier for user to retrieve individual endpoints * feat(enterprise/): add audit logging endpoint * feat(audit_logging_endpoints.py): expose new GET `/audit/{id}` endpoint make it easier to retrieve view individual audit logs * feat(key_management_event_hooks.py): correctly show the key of the user who initiated the change * fix(key_management_event_hooks.py): add key rotations as an audit log event ' * test(test_audit_logging_endpoints.py): add simple unit testing for audit log endpoint * fix: testing fixes * fix: fix ruff check * [Feat] Use aiohttp transport by default - 97% lower median latency (#11097) * fix: add flag for disabling use_aiohttp_transport * feat: add _create_async_transport * feat: fixes for transport * add httpx-aiohttp * feat: fixes for transport * refactor: fixes for transport * build: fix deps * fixes: test fixes * fix: ensure aiohttp does not auto set content type * test: test fixes * feat: add LiteLLMAiohttpTransport * fix: fixes for responses API handling * test: fixes for responses API handling * test: fixes for responses API handling * feat: fixes for transport * fix: base embedding handler * test: test_async_http_handler_force_ipv4 * test: fix failing deepeval test * fix: add YARL for bedrock urls * fix: issues with transport * fix: comment out linting issues * test fix * test: XAI is unstable * test: fixes for using respx * test: XAI fixes * test: XAI fixes * test: infinity testing fixes * docs(config_settings.md): document param * test: test_openai_image_edit_litellm_sdk * test: remove deprecated test * bump respx==0.22.0 * test: test_xai_message_name_filtering * test: fix anthropic test after bumping httpx * use n 4 for mapped tests (#11109) * fix: use 1 session per event loop * test: test_client_session_helper * fix: linting error * fix: resolving GET requests on httpx 0.28.1 * test fixes proxy unit tests * fix: add ssl verify settings * fix: proxy unit tests * fix: refactor * tests: basic unit tests for aiohttp transports * tests: fixes xai --------- Co-authored-by: Krrish Dholakia <krrishdholakia@gmail.com> * test: cleanup redundant test * fix: fix import * fix: fix linting errors --------- Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com> Co-authored-by: JuHyun Bae <jhyun0408@nate.com>
96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
import ast
|
|
import os
|
|
|
|
class EnterpriseImportFinder(ast.NodeVisitor):
|
|
def __init__(self):
|
|
self.unsafe_imports = []
|
|
self.current_file = None
|
|
self.in_try_block = False
|
|
self.try_blocks = []
|
|
|
|
def visit_Try(self, node):
|
|
# Track that we're entering a try block
|
|
self.in_try_block = True
|
|
self.try_blocks.append(node)
|
|
# Visit all nodes in the try block
|
|
for item in node.body:
|
|
self.visit(item)
|
|
# Visit except blocks
|
|
for handler in node.handlers:
|
|
for item in handler.body:
|
|
self.visit(item)
|
|
# Visit else block if it exists
|
|
for item in node.orelse:
|
|
self.visit(item)
|
|
# Visit finally block if it exists
|
|
for item in node.finalbody:
|
|
self.visit(item)
|
|
# We're leaving the try block
|
|
self.try_blocks.pop()
|
|
self.in_try_block = len(self.try_blocks) > 0
|
|
|
|
def visit_Import(self, node):
|
|
# Check for direct imports of litellm_enterprise
|
|
for name in node.names:
|
|
if "litellm_enterprise" in name.name or "enterprise" in name.name:
|
|
if not self.in_try_block:
|
|
self.unsafe_imports.append({
|
|
"file": self.current_file,
|
|
"line": node.lineno,
|
|
"import": name.name,
|
|
"context": "direct import"
|
|
})
|
|
self.generic_visit(node)
|
|
|
|
def visit_ImportFrom(self, node):
|
|
# Check for from litellm_enterprise imports
|
|
if node.module and ("litellm_enterprise" in node.module or "enterprise" in node.module):
|
|
if not self.in_try_block:
|
|
self.unsafe_imports.append({
|
|
"file": self.current_file,
|
|
"line": node.lineno,
|
|
"import": f"from {node.module}",
|
|
"context": "from import"
|
|
})
|
|
self.generic_visit(node)
|
|
|
|
def find_unsafe_enterprise_imports_in_file(file_path):
|
|
with open(file_path, "r") as file:
|
|
tree = ast.parse(file.read(), filename=file_path)
|
|
finder = EnterpriseImportFinder()
|
|
finder.current_file = file_path
|
|
finder.visit(tree)
|
|
return finder.unsafe_imports
|
|
|
|
def find_unsafe_enterprise_imports_in_directory(directory):
|
|
unsafe_imports = []
|
|
for root, _, files in os.walk(directory):
|
|
for file in files:
|
|
if file.endswith(".py"):
|
|
file_path = os.path.join(root, file)
|
|
imports = find_unsafe_enterprise_imports_in_file(file_path)
|
|
if imports:
|
|
unsafe_imports.extend(imports)
|
|
return unsafe_imports
|
|
|
|
if __name__ == "__main__":
|
|
# Check for unsafe enterprise imports in the litellm directory
|
|
directory_path = "./litellm"
|
|
unsafe_imports = find_unsafe_enterprise_imports_in_directory(directory_path)
|
|
|
|
if unsafe_imports:
|
|
print("🚨 UNSAFE ENTERPRISE IMPORTS FOUND (not in try-except blocks):")
|
|
for imp in unsafe_imports:
|
|
print(f"File: {imp['file']}")
|
|
print(f"Line: {imp['line']}")
|
|
print(f"Import: {imp['import']}")
|
|
print(f"Context: {imp['context']}")
|
|
print("---")
|
|
|
|
# Raise exception to fail CI/CD
|
|
raise Exception(
|
|
"🚨 Unsafe enterprise imports found. All enterprise imports must be wrapped in try-except blocks."
|
|
)
|
|
else:
|
|
print("✅ No unsafe enterprise imports found.")
|