Skip to content

Commit

Permalink
refine apis
Browse files Browse the repository at this point in the history
  • Loading branch information
Mini256 committed Feb 11, 2025
1 parent 136f9fa commit fb0ef2f
Show file tree
Hide file tree
Showing 16 changed files with 177 additions and 126 deletions.
Empty file.
21 changes: 21 additions & 0 deletions backend/app/api/admin_routes/chat/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from fastapi import APIRouter, Depends
from fastapi_pagination import Params

from app.models.chat import ChatOrigin
from app.api.deps import CurrentSuperuserDep, SessionDep
from app.repositories import chat_repo


router = APIRouter(
prefix="/admin/chats",
tags=["admin/chat"],
)


@router.get("/origins")
def list_chat_origins(
session: SessionDep,
user: CurrentSuperuserDep,
params: Params = Depends(),
) -> list[ChatOrigin]:
return chat_repo.list_chat_origins(session, params)
20 changes: 17 additions & 3 deletions backend/app/api/admin_routes/feedback.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
from typing import Annotated
from typing import Annotated, Optional

from fastapi import APIRouter, Depends, Query
from fastapi_pagination import Params, Page

from app.api.deps import SessionDep, CurrentSuperuserDep
from app.models import AdminFeedbackPublic, FeedbackFilters
from app.models.feedback import FeedbackOrigin
from app.repositories import feedback_repo

router = APIRouter()
router = APIRouter(
prefix="/admin/feedbacks",
tags=["admin/feedback"],
)


@router.get("/admin/feedbacks")
@router.get("/")
def list_feedbacks(
session: SessionDep,
user: CurrentSuperuserDep,
Expand All @@ -22,3 +26,13 @@ def list_feedbacks(
filters=filters,
params=params,
)


@router.get("/origins")
def list_feedback_origins(
session: SessionDep,
user: CurrentSuperuserDep,
search: Optional[str] = None,
params: Params = Depends(),
) -> Page[FeedbackOrigin]:
return feedback_repo.list_feedback_origins(session, search, params)
45 changes: 1 addition & 44 deletions backend/app/api/admin_routes/stats.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
from datetime import date
from pydantic import BaseModel
from fastapi import APIRouter, Depends
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.sqlmodel import paginate

from sqlmodel import select

from fastapi import APIRouter
from app.api.deps import CurrentSuperuserDep, SessionDep
from app.repositories import chat_repo
from app.models import Feedback
from app.models.base import UUIDBaseModel

from app.repositories import chat_repo

router = APIRouter()

Expand Down Expand Up @@ -39,38 +31,3 @@ def chat_origin_trend(
) -> ChatStats:
stats = chat_repo.chat_trend_by_origin(session, start_date, end_date)
return ChatStats(start_date=start_date, end_date=end_date, values=stats)


class ChatOrigin(UUIDBaseModel):
origin: str


@router.get("/admin/stats/chats/origins")
def list_chat_origins(
session: SessionDep,
user: CurrentSuperuserDep,
params: Params = Depends(),
) -> list[ChatOrigin]:
chat_origins = []
# chats = session.exec(select(Chat.origin, Chat.id).order_by(Chat.created_at.desc()))
for chat in chat_repo.list_chat_origins(session):
chat_origins.append(
ChatOrigin(
id=chat.id,
origin=chat.origin,
)
)
return chat_origins


@router.get("/admin/stats/feedbacks/origins")
def list_feedback_origins(
session: SessionDep,
user: CurrentSuperuserDep,
params: Params = Depends(),
) -> Page[str]:
return paginate(
session,
select(Feedback.origin).distinct().order_by(Feedback.origin.asc()),
params,
)
28 changes: 8 additions & 20 deletions backend/app/api/admin_routes/user.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,24 @@
from fastapi import APIRouter, Depends
from fastapi_pagination import Params
from sqlmodel import select

from app.api.deps import SessionDep, CurrentSuperuserDep
from app.models import User

from app.repositories.user import user_repo
from app.api.deps import SessionDep, CurrentSuperuserDep
from app.api.admin_routes.models import (
UserDescriptor,
)
from fuzzywuzzy import process

router = APIRouter()
router = APIRouter(
prefix="/admin/users",
tags=["admin/user"],
)


@router.get("/admin/users/search")
@router.get("/search")
def search_users(
session: SessionDep,
user: CurrentSuperuserDep,
search: str | None = None,
params: Params = Depends(),
) -> list[UserDescriptor]:
users = []
for user in session.exec(select(User).order_by(User.id)):
users.append(UserDescriptor(id=user.id, email=user.email))
# when search is empty, return all users
if not search:
return users
# when search is not empty, filter users by email
emails = [user.email for user in users]
matches = process.extract(search, emails, limit=len(emails))

threshold = 70
matched_emails = {match[0] for match in matches if match[1] >= threshold}

return [user for user in users if user.email in matched_emails]
return user_repo.search_users(session, search, params)
10 changes: 5 additions & 5 deletions backend/app/api/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from fastapi import APIRouter


from app.api.routes import (
index,
chat,
Expand Down Expand Up @@ -35,6 +33,7 @@
from app.api.admin_routes.reranker_model.routes import (
router as admin_reranker_model_router,
)
from app.api.admin_routes.chat.routes import router as admin_user_router
from app.api.admin_routes import (
chat_engine as admin_chat_engine,
feedback as admin_feedback,
Expand Down Expand Up @@ -64,9 +63,10 @@
api_router.include_router(api_key.router, tags=["auth"])
api_router.include_router(document.router, tags=["documents"])
api_router.include_router(retrieve_routes.router, tags=["retrieve"])
api_router.include_router(admin_chat_engine.router, tags=["admin/chat_engine"])
api_router.include_router(admin_user_router)
api_router.include_router(admin_chat_engine.router, tags=["admin/chat-engines"])
api_router.include_router(admin_document_router, tags=["admin/documents"])
api_router.include_router(admin_feedback.router, tags=["admin/feedback"])
api_router.include_router(admin_feedback.router)
api_router.include_router(admin_site_settings.router, tags=["admin/site_settings"])
api_router.include_router(admin_upload.router, tags=["admin/upload"])
api_router.include_router(admin_knowledge_base_router, tags=["admin/knowledge_base"])
Expand All @@ -93,7 +93,7 @@
api_router.include_router(
admin_evaluation_dataset.router, tags=["admin/evaluation/dataset"]
)
api_router.include_router(admin_user.router, tags=["admin/user"])
api_router.include_router(admin_user.router)

api_router.include_router(
fastapi_users.get_auth_router(auth_backend), prefix="/auth", tags=["auth"]
Expand Down
32 changes: 2 additions & 30 deletions backend/app/api/routes/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,16 @@
)
from fastapi import APIRouter, Depends, HTTPException, Request, Query
from fastapi.responses import StreamingResponse
from fastapi_pagination import Params, Page, paginate

from sqlmodel import select

from fastapi_pagination import Params, Page
from app.api.deps import SessionDep, OptionalUserDep, CurrentUserDep
from app.models.base import UUIDBaseModel
from app.rag.chat.chat_flow import ChatFlow
from app.rag.retrievers.knowledge_graph.schema import KnowledgeGraphRetrievalResult
from app.repositories import chat_repo
from app.models import Chat, ChatUpdate

from app.rag.chat.chat_service import get_final_chat_result
from app.models import Chat, ChatUpdate, ChatFilters
from app.rag.chat import (
from app.rag.chat.chat_service import (
user_can_view_chat,
user_can_edit_chat,
get_chat_message_subgraph,
Expand Down Expand Up @@ -110,30 +106,6 @@ def list_chats(
return chat_repo.paginate(session, user, browser_id, filters, params)


class ChatOrigin(UUIDBaseModel):
origin: str


@router.get("/chats/origins")
def list_chat_origins(
session: SessionDep,
user: OptionalUserDep,
params: Params = Depends(),
) -> Page[ChatOrigin]:
return paginate(
session,
select(Chat.origin, Chat.id).order_by(Chat.created_at.desc()),
params,
transformer=lambda items: [
ChatOrigin(
id=item.id,
origin=item.origin,
)
for item in items
],
)


@router.get("/chats/{chat_id}")
def get_chat(session: SessionDep, user: OptionalUserDep, chat_id: UUID):
chat = chat_repo.must_get(session, chat_id)
Expand Down
3 changes: 2 additions & 1 deletion backend/app/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
FeedbackType,
AdminFeedbackPublic,
FeedbackFilters,
FeedbackOrigin,
)
from .semantic_cache import SemanticCache
from .staff_action_log import StaffActionLog
from .chat_engine import ChatEngine, ChatEngineUpdate
from .chat import Chat, ChatUpdate, ChatVisibility, ChatFilters
from .chat import Chat, ChatUpdate, ChatVisibility, ChatFilters, ChatOrigin
from .chat_message import ChatMessage
from .document import Document, DocIndexTaskStatus
from .chunk import Chunk, KgIndexStatus
Expand Down
5 changes: 5 additions & 0 deletions backend/app/models/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,8 @@ class ChatFilters(BaseModel):
chat_origin: Optional[str] = None
# user_id: Optional[UUID] = None # no use now
engine_id: Optional[int] = None


class ChatOrigin(BaseModel):
origin: str
chats: int
8 changes: 7 additions & 1 deletion backend/app/models/feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,16 @@ class AdminFeedbackPublic(BaseFeedback):
user_id: Optional[UUID]
user_email: Optional[str]


class FeedbackFilters(BaseModel):
created_at_start: Optional[datetime] = None
created_at_end: Optional[datetime] = None
feedback_origin: Optional[str] = None
chat_id: Optional[UUID] = None
feedback_type: Optional[FeedbackType] = None
user_id: Optional[UUID] = None
user_id: Optional[UUID] = None


class FeedbackOrigin(BaseModel):
origin: str
feedbacks: int
20 changes: 16 additions & 4 deletions backend/app/repositories/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.sqlmodel import paginate

from app.models import Chat, User, ChatMessage, ChatUpdate, ChatFilters
from app.models import Chat, User, ChatMessage, ChatUpdate, ChatFilters, ChatOrigin
from app.repositories.base_repo import BaseRepo
from app.exceptions import ChatNotFound, ChatMessageNotFound

Expand Down Expand Up @@ -242,10 +242,22 @@ def chat_trend_by_origin(
stats.sort(key=lambda x: x["date"])
return stats

def list_chat_origins(self, session: Session):
return session.exec(
select(Chat.origin, Chat.id).order_by(Chat.created_at.desc())
def list_chat_origins(
self,
session: Session,
search: Optional[str] = None,
params: Params | None = Params(),
) -> Page[ChatOrigin]:
query = select(Chat.origin, func.count(Chat.id).label("count")).where(
Chat.deleted_at == None
)

if search:
query = query.where(Chat.origin.ilike(f"%{search}%"))

query = query.group_by(Chat.origin).order_by(desc("count"))

return paginate(session, query, params)


chat_repo = ChatRepo()
36 changes: 32 additions & 4 deletions backend/app/repositories/feedback.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from sqlmodel import select, Session, col
from sqlmodel import select, Session, col, func, desc
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.sqlmodel import paginate
from typing import Optional

from app.models import Feedback, AdminFeedbackPublic, FeedbackFilters
from app.models.feedback import FeedbackOrigin
from app.repositories.base_repo import BaseRepo


class FeedbackRepo(BaseRepo):
model_cls = Feedback

Expand All @@ -28,11 +31,11 @@ def paginate(
stmt = stmt.where(Feedback.feedback_type == filters.feedback_type)
if filters.user_id:
stmt = stmt.where(Feedback.user_id == filters.user_id)

stmt = stmt.order_by(Feedback.created_at.desc())
return paginate(
session,
stmt,
session,
stmt,
params,
transformer=lambda items: [
AdminFeedbackPublic(
Expand All @@ -46,4 +49,29 @@ def paginate(
],
)

def list_feedback_origins(
self,
session: Session,
search: Optional[str] = None,
params: Params | None = Params(),
) -> Page[FeedbackOrigin]:
query = select(
Feedback.origin, func.count(Feedback.id).label("feedbacks")
).group_by(Feedback.origin)

if search:
query = query.where(Feedback.origin.ilike(f"%{search}%"))

query = query.order_by(desc("feedbacks"))

return paginate(
session,
query,
params,
transformer=lambda items: [
FeedbackOrigin(origin=item[0], feedbacks=item[1]) for item in items
],
)


feedback_repo = FeedbackRepo()
Loading

0 comments on commit fb0ef2f

Please sign in to comment.