feat: implement pagination for transaction log queries (#5281)

* Add pagination support for transaction logs.

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* Replace 'TransactionData' with 'data' variable.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
dhlidongming 2024-12-17 05:04:30 +08:00 • committed by GitHub
commit 1ec63800b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 105 additions and 47 deletions

View file

@ -12,7 +12,7 @@ import orjson
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
from fastapi.encoders import jsonable_encoder
from fastapi.responses import StreamingResponse
from fastapi_pagination import Page, Params, add_pagination
from fastapi_pagination import Page, Params
from fastapi_pagination.ext.sqlalchemy import paginate
from sqlmodel import and_, col, select
from sqlmodel.ext.asyncio.session import AsyncSession
@ -521,6 +521,3 @@ async def read_basic_examples(
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
add_pagination(router)

View file

@ -2,15 +2,17 @@ from typing import Annotated
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi_pagination import Page, Params
from fastapi_pagination.ext.sqlmodel import paginate
from sqlalchemy import delete
from sqlmodel import col, select
from langflow.api.utils import DbSession
from langflow.api.utils import DbSession, custom_params
from langflow.schema.message import MessageResponse
from langflow.services.auth.utils import get_current_active_user
from langflow.services.database.models.message.model import MessageRead, MessageTable, MessageUpdate
from langflow.services.database.models.transactions.crud import get_transactions_by_flow_id
from langflow.services.database.models.transactions.model import TransactionReadResponse
from langflow.services.database.models.transactions.crud import transform_transaction_table
from langflow.services.database.models.transactions.model import TransactionTable
from langflow.services.database.models.vertex_builds.crud import (
delete_vertex_builds_by_flow_id,
get_vertex_builds_by_flow_id,
@ -160,22 +162,14 @@ async def delete_messages_session(
async def get_transactions(
flow_id: Annotated[UUID, Query()],
session: DbSession,
) -> list[TransactionReadResponse]:
params: Annotated[Params | None, Depends(custom_params)],
) -> Page[TransactionTable]:
try:
transactions = await get_transactions_by_flow_id(session, flow_id)
return [
TransactionReadResponse(
transaction_id=t.id,
timestamp=t.timestamp,
vertex_id=t.vertex_id,
target_id=t.target_id,
inputs=t.inputs,
outputs=t.outputs,
status=t.status,
error=t.error,
flow_id=t.flow_id,
)
for t in transactions
]
stmt = (
select(TransactionTable)
.where(TransactionTable.flow_id == flow_id)
.order_by(col(TransactionTable.timestamp))
)
return await paginate(session, stmt, params=params, transformer=transform_transaction_table)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e

View file

@ -13,6 +13,7 @@ from fastapi import FastAPI, HTTPException, Request, Response, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi_pagination import add_pagination
from loguru import logger
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from pydantic import PydanticDeprecatedSince20
@ -229,6 +230,7 @@ def create_app():
FastAPIInstrumentor.instrument_app(app)
add_pagination(app)
return app

View file

@ -4,7 +4,11 @@ from sqlalchemy.exc import IntegrityError
from sqlmodel import col, select
from sqlmodel.ext.asyncio.session import AsyncSession
from langflow.services.database.models.transactions.model import TransactionBase, TransactionTable
from langflow.services.database.models.transactions.model import (
TransactionBase,
TransactionReadResponse,
TransactionTable,
)
async def get_transactions_by_flow_id(
@ -31,3 +35,11 @@ async def log_transaction(db: AsyncSession, transaction: TransactionBase) -> Tra
await db.rollback()
raise
return table
def transform_transaction_table(
transaction: list[TransactionTable] | TransactionTable,
) -> list[TransactionReadResponse]:
if isinstance(transaction, list):
return [TransactionReadResponse.model_validate(t, from_attributes=True) for t in transaction]
return TransactionReadResponse.model_validate(transaction, from_attributes=True)

View file

@ -46,5 +46,5 @@ class TransactionTable(TransactionBase, table=True): # type: ignore[call-arg]
class TransactionReadResponse(TransactionBase):
transaction_id: UUID
id: UUID = Field(alias="transaction_id")
flow_id: UUID