mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-07-12 00:40:07 +08:00
#47- Create API endpoints that return leaderboards (#250)
* Leaderboard endpoints proof of concept - New leaderboards router - Two endpoints /api/v1/leaderboards/assistant & /api/v1/leaderboards/prompter - Function in prompt_repository to calculate user scores * Separating create vs 'eventual' evaluate routes * Adding display_name to result * Missing / in routes * Updating route to be experimental * Fixing format for pre-commit
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
from fastapi import APIRouter
|
||||
from oasst_backend.api.v1 import frontend_messages, frontend_users, messages, stats, tasks, text_labels, users
|
||||
from oasst_backend.api.v1 import (
|
||||
frontend_messages,
|
||||
frontend_users,
|
||||
leaderboards,
|
||||
messages,
|
||||
stats,
|
||||
tasks,
|
||||
text_labels,
|
||||
users,
|
||||
)
|
||||
|
||||
api_router = APIRouter()
|
||||
api_router.include_router(tasks.router, prefix="/tasks", tags=["tasks"])
|
||||
@@ -9,3 +18,4 @@ api_router.include_router(frontend_messages.router, prefix="/frontend_messages",
|
||||
api_router.include_router(users.router, prefix="/users", tags=["users"])
|
||||
api_router.include_router(frontend_users.router, prefix="/frontend_users", tags=["frontend_users"])
|
||||
api_router.include_router(stats.router, prefix="/stats", tags=["stats"])
|
||||
api_router.include_router(leaderboards.router, prefix="/experimental/leaderboards", tags=["leaderboards"])
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from oasst_backend.api import deps
|
||||
from oasst_backend.models import ApiClient
|
||||
from oasst_backend.prompt_repository import PromptRepository
|
||||
from sqlmodel import Session
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/create/assistant")
|
||||
def get_assistant_leaderboard(
|
||||
db: Session = Depends(deps.get_db),
|
||||
api_client: ApiClient = Depends(deps.get_trusted_api_client),
|
||||
):
|
||||
pr = PromptRepository(db, api_client, None)
|
||||
return pr.get_user_leaderboard(role="assistant")
|
||||
|
||||
|
||||
@router.get("/create/prompter")
|
||||
def get_prompter_leaderboard(
|
||||
db: Session = Depends(deps.get_db),
|
||||
api_client: ApiClient = Depends(deps.get_trusted_api_client),
|
||||
):
|
||||
pr = PromptRepository(db, api_client, None)
|
||||
return pr.get_user_leaderboard(role="prompter")
|
||||
@@ -12,7 +12,7 @@ from oasst_backend.models import ApiClient, Message, MessageReaction, Task, Text
|
||||
from oasst_backend.models.payload_column_type import PayloadContainer
|
||||
from oasst_shared.exceptions import OasstError, OasstErrorCode
|
||||
from oasst_shared.schemas import protocol as protocol_schema
|
||||
from oasst_shared.schemas.protocol import SystemStats
|
||||
from oasst_shared.schemas.protocol import LeaderboardStats, SystemStats
|
||||
from sqlalchemy import update
|
||||
from sqlmodel import Session, func
|
||||
from starlette.status import HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND
|
||||
@@ -705,3 +705,24 @@ class PromptRepository:
|
||||
deleted=result.get(True, 0),
|
||||
message_trees=result.get(None, 0),
|
||||
)
|
||||
|
||||
def get_user_leaderboard(self, role: str) -> LeaderboardStats:
|
||||
"""
|
||||
Get leaderboard stats for Messages created,
|
||||
separate leaderboard for prompts & assistants
|
||||
|
||||
"""
|
||||
query = (
|
||||
self.db.query(Message.user_id, User.username, User.display_name, func.count(Message.user_id))
|
||||
.join(User, User.id == Message.user_id, isouter=True)
|
||||
.filter(Message.deleted is not True, Message.role == role)
|
||||
.group_by(Message.user_id, User.username, User.display_name)
|
||||
.order_by(func.count(Message.user_id).desc())
|
||||
)
|
||||
|
||||
result = [
|
||||
{"ranking": i, "user_id": j[0], "username": j[1], "display_name": j[2], "score": j[3]}
|
||||
for i, j in enumerate(query.all(), start=1)
|
||||
]
|
||||
|
||||
return LeaderboardStats(leaderboard=result)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import enum
|
||||
from datetime import datetime
|
||||
from typing import Literal, Optional, Union
|
||||
from typing import List, Literal, Optional, Union
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import pydantic
|
||||
@@ -281,3 +281,15 @@ class SystemStats(BaseModel):
|
||||
active: int = 0
|
||||
deleted: int = 0
|
||||
message_trees: int = 0
|
||||
|
||||
|
||||
class UserScore(BaseModel):
|
||||
ranking: int
|
||||
user_id: UUID
|
||||
username: str
|
||||
display_name: str
|
||||
score: int
|
||||
|
||||
|
||||
class LeaderboardStats(BaseModel):
|
||||
leaderboard: List[UserScore]
|
||||
|
||||
Reference in New Issue
Block a user