mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-23 14:04:49 -06:00
perf(prompts): make /tags fetch only the tags column with SQL access filter (#24287)
Non-admin GET /api/v1/prompts/tags went through get_prompts_by_user_id, which loaded every active prompt with its full content/data/meta plus owner records and all access grants, then ran one has_access query per prompt that wasn't owned by the caller - all so the endpoint could collapse the result to a sorted tag list. With 600 prompts this took several seconds while the admin path (a single SELECT) returned in <1s. Add Prompts.get_tags_by_user_id which selects only the tags column and applies the same EXISTS-based access filter used by /list. Also tighten the admin get_tags to project just the tags column instead of full rows. The endpoint is now one DB query (plus one for groups), no row hydration, no N+1. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -663,12 +663,38 @@ class PromptsTable:
|
||||
async def get_tags(self, db: Optional[AsyncSession] = None) -> list[str]:
|
||||
try:
|
||||
async with get_async_db_context(db) as db:
|
||||
result = await db.execute(select(Prompt).filter_by(is_active=True))
|
||||
prompts = result.scalars().all()
|
||||
result = await db.execute(select(Prompt.tags).filter(Prompt.is_active == True))
|
||||
tags = set()
|
||||
for prompt in prompts:
|
||||
if prompt.tags:
|
||||
for tag in prompt.tags:
|
||||
for (tag_list,) in result.all():
|
||||
if tag_list:
|
||||
for tag in tag_list:
|
||||
if tag:
|
||||
tags.add(tag)
|
||||
return sorted(list(tags))
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
async def get_tags_by_user_id(self, user_id: str, db: Optional[AsyncSession] = None) -> list[str]:
|
||||
try:
|
||||
async with get_async_db_context(db) as db:
|
||||
user_groups = await Groups.get_groups_by_member_id(user_id, db=db)
|
||||
user_group_ids = [group.id for group in user_groups]
|
||||
|
||||
query = select(Prompt.tags).filter(Prompt.is_active == True)
|
||||
query = AccessGrants.has_permission_filter(
|
||||
db=db,
|
||||
query=query,
|
||||
DocumentModel=Prompt,
|
||||
filter={'user_id': user_id, 'group_ids': user_group_ids},
|
||||
resource_type='prompt',
|
||||
permission='read',
|
||||
)
|
||||
|
||||
result = await db.execute(query)
|
||||
tags = set()
|
||||
for (tag_list,) in result.all():
|
||||
if tag_list:
|
||||
for tag in tag_list:
|
||||
if tag:
|
||||
tags.add(tag)
|
||||
return sorted(list(tags))
|
||||
|
||||
@@ -61,13 +61,7 @@ async def get_prompts(user=Depends(get_verified_user), db: AsyncSession = Depend
|
||||
async def get_prompt_tags(user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session)):
|
||||
if user.role == 'admin' and BYPASS_ADMIN_ACCESS_CONTROL:
|
||||
return await Prompts.get_tags(db=db)
|
||||
else:
|
||||
prompts = await Prompts.get_prompts_by_user_id(user.id, 'read', db=db)
|
||||
tags = set()
|
||||
for prompt in prompts:
|
||||
if prompt.tags:
|
||||
tags.update(prompt.tags)
|
||||
return sorted(list(tags))
|
||||
return await Prompts.get_tags_by_user_id(user.id, db=db)
|
||||
|
||||
|
||||
@router.get('/list', response_model=PromptAccessListResponse)
|
||||
|
||||
Reference in New Issue
Block a user