mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-10-23 03:42:59 -05:00
118 lines
3.5 KiB
Python
118 lines
3.5 KiB
Python
import datetime
|
|
from collections import defaultdict
|
|
|
|
from fastapi import APIRouter
|
|
from fastapi import Depends
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.orm import Session
|
|
|
|
from danswer.auth.users import current_admin_user
|
|
from danswer.db.engine import get_session
|
|
from danswer.db.models import User
|
|
from ee.danswer.db.analytics import fetch_danswerbot_analytics
|
|
from ee.danswer.db.analytics import fetch_per_user_query_analytics
|
|
from ee.danswer.db.analytics import fetch_query_analytics
|
|
|
|
router = APIRouter(prefix="/analytics")
|
|
|
|
|
|
class QueryAnalyticsResponse(BaseModel):
|
|
total_queries: int
|
|
total_likes: int
|
|
total_dislikes: int
|
|
date: datetime.date
|
|
|
|
|
|
@router.get("/admin/query")
|
|
def get_query_analytics(
|
|
start: datetime.datetime | None = None,
|
|
end: datetime.datetime | None = None,
|
|
_: User | None = Depends(current_admin_user),
|
|
db_session: Session = Depends(get_session),
|
|
) -> list[QueryAnalyticsResponse]:
|
|
daily_query_usage_info = fetch_query_analytics(
|
|
start=start
|
|
or (
|
|
datetime.datetime.utcnow() - datetime.timedelta(days=30)
|
|
), # default is 30d lookback
|
|
end=end or datetime.datetime.utcnow(),
|
|
db_session=db_session,
|
|
)
|
|
return [
|
|
QueryAnalyticsResponse(
|
|
total_queries=total_queries,
|
|
total_likes=total_likes,
|
|
total_dislikes=total_dislikes,
|
|
date=date,
|
|
)
|
|
for total_queries, total_likes, total_dislikes, date in daily_query_usage_info
|
|
]
|
|
|
|
|
|
class UserAnalyticsResponse(BaseModel):
|
|
total_active_users: int
|
|
date: datetime.date
|
|
|
|
|
|
@router.get("/admin/user")
|
|
def get_user_analytics(
|
|
start: datetime.datetime | None = None,
|
|
end: datetime.datetime | None = None,
|
|
_: User | None = Depends(current_admin_user),
|
|
db_session: Session = Depends(get_session),
|
|
) -> list[UserAnalyticsResponse]:
|
|
daily_query_usage_info_per_user = fetch_per_user_query_analytics(
|
|
start=start
|
|
or (
|
|
datetime.datetime.utcnow() - datetime.timedelta(days=30)
|
|
), # default is 30d lookback
|
|
end=end or datetime.datetime.utcnow(),
|
|
db_session=db_session,
|
|
)
|
|
|
|
user_analytics: dict[datetime.date, int] = defaultdict(int)
|
|
for __, ___, ____, date, _____ in daily_query_usage_info_per_user:
|
|
user_analytics[date] += 1
|
|
return [
|
|
UserAnalyticsResponse(
|
|
total_active_users=cnt,
|
|
date=date,
|
|
)
|
|
for date, cnt in user_analytics.items()
|
|
]
|
|
|
|
|
|
class DanswerbotAnalyticsResponse(BaseModel):
|
|
total_queries: int
|
|
auto_resolved: int
|
|
date: datetime.date
|
|
|
|
|
|
@router.get("/admin/danswerbot")
|
|
def get_danswerbot_analytics(
|
|
start: datetime.datetime | None = None,
|
|
end: datetime.datetime | None = None,
|
|
_: User | None = Depends(current_admin_user),
|
|
db_session: Session = Depends(get_session),
|
|
) -> list[DanswerbotAnalyticsResponse]:
|
|
daily_danswerbot_info = fetch_danswerbot_analytics(
|
|
start=start
|
|
or (
|
|
datetime.datetime.utcnow() - datetime.timedelta(days=30)
|
|
), # default is 30d lookback
|
|
end=end or datetime.datetime.utcnow(),
|
|
db_session=db_session,
|
|
)
|
|
|
|
resolution_results = [
|
|
DanswerbotAnalyticsResponse(
|
|
total_queries=total_queries,
|
|
# If it hits negatives, something has gone wrong...
|
|
auto_resolved=max(0, total_queries - total_negatives),
|
|
date=date,
|
|
)
|
|
for total_queries, total_negatives, date in daily_danswerbot_info
|
|
]
|
|
|
|
return resolution_results
|