dify
This commit is contained in:
161
dify/api/services/workflow_run_service.py
Normal file
161
dify/api/services/workflow_run_service.py
Normal file
@@ -0,0 +1,161 @@
|
||||
import threading
|
||||
from collections.abc import Sequence
|
||||
|
||||
from sqlalchemy import Engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
import contexts
|
||||
from extensions.ext_database import db
|
||||
from libs.infinite_scroll_pagination import InfiniteScrollPagination
|
||||
from models import (
|
||||
Account,
|
||||
App,
|
||||
EndUser,
|
||||
WorkflowNodeExecutionModel,
|
||||
WorkflowRun,
|
||||
WorkflowRunTriggeredFrom,
|
||||
)
|
||||
from repositories.api_workflow_run_repository import APIWorkflowRunRepository
|
||||
from repositories.factory import DifyAPIRepositoryFactory
|
||||
|
||||
|
||||
class WorkflowRunService:
|
||||
_session_factory: sessionmaker
|
||||
_workflow_run_repo: APIWorkflowRunRepository
|
||||
|
||||
def __init__(self, session_factory: Engine | sessionmaker | None = None):
|
||||
"""Initialize WorkflowRunService with repository dependencies."""
|
||||
if session_factory is None:
|
||||
session_factory = sessionmaker(bind=db.engine, expire_on_commit=False)
|
||||
elif isinstance(session_factory, Engine):
|
||||
session_factory = sessionmaker(bind=session_factory, expire_on_commit=False)
|
||||
|
||||
self._session_factory = session_factory
|
||||
self._node_execution_service_repo = DifyAPIRepositoryFactory.create_api_workflow_node_execution_repository(
|
||||
self._session_factory
|
||||
)
|
||||
self._workflow_run_repo = DifyAPIRepositoryFactory.create_api_workflow_run_repository(self._session_factory)
|
||||
|
||||
def get_paginate_advanced_chat_workflow_runs(
|
||||
self, app_model: App, args: dict, triggered_from: WorkflowRunTriggeredFrom = WorkflowRunTriggeredFrom.DEBUGGING
|
||||
) -> InfiniteScrollPagination:
|
||||
"""
|
||||
Get advanced chat app workflow run list
|
||||
|
||||
:param app_model: app model
|
||||
:param args: request args
|
||||
:param triggered_from: workflow run triggered from (default: DEBUGGING for preview runs)
|
||||
"""
|
||||
|
||||
class WorkflowWithMessage:
|
||||
message_id: str
|
||||
conversation_id: str
|
||||
|
||||
def __init__(self, workflow_run: WorkflowRun):
|
||||
self._workflow_run = workflow_run
|
||||
|
||||
def __getattr__(self, item):
|
||||
return getattr(self._workflow_run, item)
|
||||
|
||||
pagination = self.get_paginate_workflow_runs(app_model, args, triggered_from)
|
||||
|
||||
with_message_workflow_runs = []
|
||||
for workflow_run in pagination.data:
|
||||
message = workflow_run.message
|
||||
with_message_workflow_run = WorkflowWithMessage(workflow_run=workflow_run)
|
||||
if message:
|
||||
with_message_workflow_run.message_id = message.id
|
||||
with_message_workflow_run.conversation_id = message.conversation_id
|
||||
|
||||
with_message_workflow_runs.append(with_message_workflow_run)
|
||||
|
||||
pagination.data = with_message_workflow_runs
|
||||
return pagination
|
||||
|
||||
def get_paginate_workflow_runs(
|
||||
self, app_model: App, args: dict, triggered_from: WorkflowRunTriggeredFrom = WorkflowRunTriggeredFrom.DEBUGGING
|
||||
) -> InfiniteScrollPagination:
|
||||
"""
|
||||
Get workflow run list
|
||||
|
||||
:param app_model: app model
|
||||
:param args: request args
|
||||
:param triggered_from: workflow run triggered from (default: DEBUGGING)
|
||||
"""
|
||||
limit = int(args.get("limit", 20))
|
||||
last_id = args.get("last_id")
|
||||
status = args.get("status")
|
||||
|
||||
return self._workflow_run_repo.get_paginated_workflow_runs(
|
||||
tenant_id=app_model.tenant_id,
|
||||
app_id=app_model.id,
|
||||
triggered_from=triggered_from,
|
||||
limit=limit,
|
||||
last_id=last_id,
|
||||
status=status,
|
||||
)
|
||||
|
||||
def get_workflow_run(self, app_model: App, run_id: str) -> WorkflowRun | None:
|
||||
"""
|
||||
Get workflow run detail
|
||||
|
||||
:param app_model: app model
|
||||
:param run_id: workflow run id
|
||||
"""
|
||||
return self._workflow_run_repo.get_workflow_run_by_id(
|
||||
tenant_id=app_model.tenant_id,
|
||||
app_id=app_model.id,
|
||||
run_id=run_id,
|
||||
)
|
||||
|
||||
def get_workflow_runs_count(
|
||||
self,
|
||||
app_model: App,
|
||||
status: str | None = None,
|
||||
time_range: str | None = None,
|
||||
triggered_from: WorkflowRunTriggeredFrom = WorkflowRunTriggeredFrom.DEBUGGING,
|
||||
) -> dict[str, int]:
|
||||
"""
|
||||
Get workflow runs count statistics
|
||||
|
||||
:param app_model: app model
|
||||
:param status: optional status filter
|
||||
:param time_range: optional time range filter (e.g., "7d", "4h", "30m", "30s")
|
||||
:param triggered_from: workflow run triggered from (default: DEBUGGING)
|
||||
:return: dict with total and status counts
|
||||
"""
|
||||
return self._workflow_run_repo.get_workflow_runs_count(
|
||||
tenant_id=app_model.tenant_id,
|
||||
app_id=app_model.id,
|
||||
triggered_from=triggered_from,
|
||||
status=status,
|
||||
time_range=time_range,
|
||||
)
|
||||
|
||||
def get_workflow_run_node_executions(
|
||||
self,
|
||||
app_model: App,
|
||||
run_id: str,
|
||||
user: Account | EndUser,
|
||||
) -> Sequence[WorkflowNodeExecutionModel]:
|
||||
"""
|
||||
Get workflow run node execution list
|
||||
"""
|
||||
workflow_run = self.get_workflow_run(app_model, run_id)
|
||||
|
||||
contexts.plugin_tool_providers.set({})
|
||||
contexts.plugin_tool_providers_lock.set(threading.Lock())
|
||||
|
||||
if not workflow_run:
|
||||
return []
|
||||
|
||||
# Get tenant_id from user
|
||||
tenant_id = user.tenant_id if isinstance(user, EndUser) else user.current_tenant_id
|
||||
if tenant_id is None:
|
||||
raise ValueError("User tenant_id cannot be None")
|
||||
|
||||
return self._node_execution_service_repo.get_executions_by_workflow_run(
|
||||
tenant_id=tenant_id,
|
||||
app_id=app_model.id,
|
||||
workflow_run_id=run_id,
|
||||
)
|
||||
Reference in New Issue
Block a user