Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Commit a6c9e76

Browse files
feat: filter messages by ID (#1206)
* feat: filter messages by ID * lint fix * fix: use `.bindparams` for `filter_by_ids`
1 parent c41b4ad commit a6c9e76

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

src/codegate/api/v1.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ async def get_workspace_messages(
407407
workspace_name: str,
408408
page: int = Query(1, ge=1),
409409
page_size: int = Query(API_DEFAULT_PAGE_SIZE, ge=1, le=API_MAX_PAGE_SIZE),
410+
filter_by_ids: Optional[List[str]] = Query(None),
410411
) -> v1_models.PaginatedMessagesResponse:
411412
"""Get messages for a workspace."""
412413
try:
@@ -422,7 +423,7 @@ async def get_workspace_messages(
422423

423424
while len(fetched_messages) < page_size:
424425
messages_batch = await dbreader.get_prompts_with_output_alerts_usage_by_workspace_id(
425-
ws.id, AlertSeverity.CRITICAL.value, page_size, offset
426+
ws.id, AlertSeverity.CRITICAL.value, page_size, offset, filter_by_ids
426427
)
427428
if not messages_batch:
428429
break

src/codegate/db/connection.py

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from alembic import command as alembic_command
99
from alembic.config import Config as AlembicConfig
1010
from pydantic import BaseModel
11-
from sqlalchemy import CursorResult, TextClause, event, text
11+
from sqlalchemy import CursorResult, TextClause, bindparam, event, text
1212
from sqlalchemy.engine import Engine
1313
from sqlalchemy.exc import IntegrityError, OperationalError
1414
from sqlalchemy.ext.asyncio import create_async_engine
@@ -600,38 +600,51 @@ async def get_prompts_with_output_alerts_usage_by_workspace_id(
600600
trigger_category: Optional[str] = None,
601601
limit: int = API_DEFAULT_PAGE_SIZE,
602602
offset: int = 0,
603+
filter_by_ids: Optional[List[str]] = None,
603604
) -> List[GetPromptWithOutputsRow]:
604605
"""
605606
Get all prompts with their outputs, alerts and token usage by workspace_id.
606607
"""
607-
sql = text(
608-
"""
608+
609+
base_query = """
609610
SELECT
610-
p.id as prompt_id, p.timestamp as prompt_timestamp, p.provider, p.request, p.type,
611-
o.id as output_id, o.output, o.timestamp as output_timestamp, o.input_tokens, o.output_tokens, o.input_cost, o.output_cost,
612-
a.id as alert_id, a.code_snippet, a.trigger_string, a.trigger_type, a.trigger_category, a.timestamp as alert_timestamp
611+
p.id as prompt_id, p.timestamp as prompt_timestamp, p.provider, p.request, p.type,
612+
o.id as output_id, o.output, o.timestamp as output_timestamp, o.input_tokens, o.output_tokens, o.input_cost, o.output_cost,
613+
a.id as alert_id, a.code_snippet, a.trigger_string, a.trigger_type, a.trigger_category, a.timestamp as alert_timestamp
613614
FROM prompts p
614615
LEFT JOIN outputs o ON p.id = o.prompt_id
615616
LEFT JOIN alerts a ON p.id = a.prompt_id
616617
WHERE p.workspace_id = :workspace_id
617-
""" # noqa: E501
618-
)
619-
conditions = {"workspace_id": workspace_id}
620-
if trigger_category:
621-
sql = text(sql.text + " AND a.trigger_category = :trigger_category")
622-
conditions["trigger_category"] = trigger_category
618+
AND (:trigger_category IS NULL OR a.trigger_category = :trigger_category)
619+
""" # noqa: E501
623620

624-
sql = text(
625-
sql.text + " ORDER BY o.timestamp DESC, a.timestamp DESC LIMIT :limit OFFSET :offset"
626-
)
627-
conditions["limit"] = limit
628-
conditions["offset"] = offset
621+
if filter_by_ids:
622+
base_query += " AND p.id IN :filter_ids"
629623

630-
fetched_rows: List[IntermediatePromptWithOutputUsageAlerts] = (
631-
await self._exec_select_conditions_to_pydantic(
632-
IntermediatePromptWithOutputUsageAlerts, sql, conditions, should_raise=True
633-
)
624+
base_query += """
625+
ORDER BY o.timestamp DESC, a.timestamp DESC
626+
LIMIT :limit OFFSET :offset
627+
"""
628+
629+
sql = text(base_query)
630+
631+
conditions = {
632+
"workspace_id": workspace_id,
633+
"trigger_category": trigger_category,
634+
"limit": limit,
635+
"offset": offset,
636+
}
637+
638+
if filter_by_ids:
639+
sql = sql.bindparams(bindparam("filter_ids", expanding=True))
640+
conditions["filter_ids"] = filter_by_ids
641+
642+
fetched_rows: List[
643+
IntermediatePromptWithOutputUsageAlerts
644+
] = await self._exec_select_conditions_to_pydantic(
645+
IntermediatePromptWithOutputUsageAlerts, sql, conditions, should_raise=True
634646
)
647+
635648
prompts_dict: Dict[str, GetPromptWithOutputsRow] = {}
636649
for row in fetched_rows:
637650
prompt_id = row.prompt_id

0 commit comments

Comments
 (0)