mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-27 17:56:26 -04:00
implement date picker and additional columns for analytics (#25922)
Co-authored-by: Tim Baek <tim@openwebui.com>
This commit is contained in:
co-authored by
Tim Baek
parent
e473ab1231
commit
6cd0ba0b6b
@@ -3,6 +3,8 @@ import time
|
||||
import uuid
|
||||
from typing import Any, Optional
|
||||
|
||||
from sqlalchemy import select, delete, func, cast, Integer, distinct
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from open_webui.internal.db import Base, get_async_db_context
|
||||
from open_webui.utils.response import normalize_usage
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
@@ -440,6 +442,44 @@ class ChatMessageTable:
|
||||
result = await db.execute(stmt)
|
||||
return {row.model_id: row.count for row in result.all()}
|
||||
|
||||
async def get_unique_counts_by_model(
|
||||
self,
|
||||
start_date: Optional[int] = None,
|
||||
end_date: Optional[int] = None,
|
||||
group_id: Optional[str] = None,
|
||||
db: Optional[AsyncSession] = None,
|
||||
) -> dict[str, dict]:
|
||||
"""Count distinct users and chats per model."""
|
||||
async with get_async_db_context(db) as db:
|
||||
from open_webui.models.groups import GroupMember
|
||||
|
||||
stmt = select(
|
||||
ChatMessage.model_id,
|
||||
func.count(distinct(ChatMessage.user_id)).label('unique_users'),
|
||||
func.count(distinct(ChatMessage.chat_id)).label('unique_chats'),
|
||||
).filter(
|
||||
ChatMessage.role == 'assistant',
|
||||
ChatMessage.model_id.isnot(None),
|
||||
)
|
||||
|
||||
if start_date:
|
||||
stmt = stmt.filter(ChatMessage.created_at >= start_date)
|
||||
if end_date:
|
||||
stmt = stmt.filter(ChatMessage.created_at <= end_date)
|
||||
if group_id:
|
||||
group_users = select(GroupMember.user_id).filter(GroupMember.group_id == group_id).scalar_subquery()
|
||||
stmt = stmt.filter(ChatMessage.user_id.in_(group_users))
|
||||
|
||||
stmt = stmt.group_by(ChatMessage.model_id)
|
||||
result = await db.execute(stmt)
|
||||
return {
|
||||
row.model_id: {
|
||||
'unique_users': row.unique_users,
|
||||
'unique_chats': row.unique_chats,
|
||||
}
|
||||
for row in result.all()
|
||||
}
|
||||
|
||||
async def get_token_usage_by_model(
|
||||
self,
|
||||
start_date: Optional[int] = None,
|
||||
|
||||
@@ -28,6 +28,8 @@ router = APIRouter()
|
||||
class ModelAnalyticsEntry(BaseModel):
|
||||
model_id: str
|
||||
count: int
|
||||
unique_users: int = 0
|
||||
unique_chats: int = 0
|
||||
|
||||
|
||||
class ModelAnalyticsResponse(BaseModel):
|
||||
@@ -65,8 +67,16 @@ async def get_model_analytics(
|
||||
counts = await ChatMessages.get_message_count_by_model(
|
||||
start_date=start_date, end_date=end_date, group_id=group_id, db=db
|
||||
)
|
||||
unique_counts = await ChatMessages.get_unique_counts_by_model(
|
||||
start_date=start_date, end_date=end_date, group_id=group_id, db=db
|
||||
)
|
||||
models = [
|
||||
ModelAnalyticsEntry(model_id=model_id, count=count)
|
||||
ModelAnalyticsEntry(
|
||||
model_id=model_id,
|
||||
count=count,
|
||||
unique_users=unique_counts.get(model_id, {}).get('unique_users', 0),
|
||||
unique_chats=unique_counts.get(model_id, {}).get('unique_chats', 0),
|
||||
)
|
||||
for model_id, count in sorted(counts.items(), key=lambda x: -x[1])
|
||||
]
|
||||
return ModelAnalyticsResponse(models=models)
|
||||
|
||||
Reference in New Issue
Block a user