Spaces:
Configuration error
Configuration error
File size: 5,304 Bytes
447ebeb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
"""
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()
@router.get(
"/audit",
tags=["Audit Logging"],
dependencies=[Depends(user_api_key_auth)],
response_model=PaginatedAuditLogResponse,
)
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,
)
@router.get(
"/audit/{id}",
tags=["Audit Logging"],
dependencies=[Depends(user_api_key_auth)],
response_model=AuditLogResponse,
responses={
404: {"description": "Audit log not found"},
500: {"description": "Database connection error"},
},
)
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())
|