Spaces:
Paused
Paused
| """ | |
| AUDIT LOGGING | |
| All /audit logging endpoints. Attempting to write these as CRUD endpoints. | |
| GET - /audit/{id} - Get audit log by id | |
| GET - /audit - Get all audit logs | |
| """ | |
| from typing import Any, Dict, Optional | |
| #### AUDIT LOGGING #### | |
| from fastapi import APIRouter, Depends, HTTPException, Query | |
| from litellm_enterprise.types.proxy.audit_logging_endpoints import ( | |
| AuditLogResponse, | |
| PaginatedAuditLogResponse, | |
| ) | |
| from litellm.proxy._types import CommonProxyErrors, UserAPIKeyAuth | |
| from litellm.proxy.auth.user_api_key_auth import user_api_key_auth | |
| router = APIRouter() | |
| async def get_audit_logs( | |
| page: int = Query(1, ge=1), | |
| page_size: int = Query(10, ge=1, le=100), | |
| # Filter parameters | |
| changed_by: Optional[str] = Query( | |
| None, description="Filter by user or system that performed the action" | |
| ), | |
| changed_by_api_key: Optional[str] = Query( | |
| None, description="Filter by API key hash that performed the action" | |
| ), | |
| action: Optional[str] = Query( | |
| None, description="Filter by action type (create, update, delete)" | |
| ), | |
| table_name: Optional[str] = Query( | |
| None, description="Filter by table name that was modified" | |
| ), | |
| object_id: Optional[str] = Query( | |
| None, description="Filter by ID of the object that was modified" | |
| ), | |
| start_date: Optional[str] = Query(None, description="Filter logs after this date"), | |
| end_date: Optional[str] = Query(None, description="Filter logs before this date"), | |
| # Sorting parameters | |
| sort_by: Optional[str] = Query( | |
| None, | |
| description="Column to sort by (e.g. 'updated_at', 'action', 'table_name')", | |
| ), | |
| sort_order: str = Query("desc", description="Sort order ('asc' or 'desc')"), | |
| ): | |
| """ | |
| Get all audit logs with filtering and pagination. | |
| Returns a paginated response of audit logs matching the specified filters. | |
| """ | |
| from litellm.proxy.proxy_server import prisma_client | |
| if prisma_client is None: | |
| raise HTTPException( | |
| status_code=500, | |
| detail={"message": CommonProxyErrors.db_not_connected_error.value}, | |
| ) | |
| # Build filter conditions | |
| where_conditions: Dict[str, Any] = {} | |
| if changed_by: | |
| where_conditions["changed_by"] = changed_by | |
| if changed_by_api_key: | |
| where_conditions["changed_by_api_key"] = changed_by_api_key | |
| if action: | |
| where_conditions["action"] = action | |
| if table_name: | |
| where_conditions["table_name"] = table_name | |
| if object_id: | |
| where_conditions["object_id"] = object_id | |
| if start_date or end_date: | |
| date_filter = {} | |
| if start_date: | |
| date_filter["gte"] = start_date | |
| if end_date: | |
| date_filter["lte"] = end_date | |
| where_conditions["updated_at"] = date_filter | |
| # Build sort conditions | |
| order_by = {} | |
| if sort_by and isinstance(sort_by, str): | |
| order_by[sort_by] = sort_order | |
| elif sort_order and isinstance(sort_order, str): | |
| order_by["updated_at"] = sort_order # Default sort by updated_at | |
| # Get paginated results | |
| audit_logs = await prisma_client.db.litellm_auditlog.find_many( | |
| where=where_conditions, | |
| order=order_by, | |
| skip=(page - 1) * page_size, | |
| take=page_size, | |
| ) | |
| # Get total count for pagination | |
| total_count = await prisma_client.db.litellm_auditlog.count(where=where_conditions) | |
| total_pages = -(-total_count // page_size) # Ceiling division | |
| # Return paginated response | |
| return PaginatedAuditLogResponse( | |
| audit_logs=[ | |
| AuditLogResponse(**audit_log.model_dump()) for audit_log in audit_logs | |
| ] | |
| if audit_logs | |
| else [], | |
| total=total_count, | |
| page=page, | |
| page_size=page_size, | |
| total_pages=total_pages, | |
| ) | |
| async def get_audit_log_by_id( | |
| id: str, user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth) | |
| ): | |
| """ | |
| Get detailed information about a specific audit log entry by its ID. | |
| Args: | |
| id (str): The unique identifier of the audit log entry | |
| Returns: | |
| AuditLogResponse: Detailed information about the audit log entry | |
| Raises: | |
| HTTPException: If the audit log is not found or if there's a database connection error | |
| """ | |
| from litellm.proxy.proxy_server import prisma_client | |
| if prisma_client is None: | |
| raise HTTPException( | |
| status_code=500, | |
| detail={"message": CommonProxyErrors.db_not_connected_error.value}, | |
| ) | |
| # Get the audit log by ID | |
| audit_log = await prisma_client.db.litellm_auditlog.find_unique(where={"id": id}) | |
| if audit_log is None: | |
| raise HTTPException( | |
| status_code=404, detail={"message": f"Audit log with ID {id} not found"} | |
| ) | |
| # Convert to response model | |
| return AuditLogResponse(**audit_log.model_dump()) | |