routes.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. from core_domain import ServiceHealth
  2. from core_dsl import EdgeDefinition, NodeDefinition, WorkflowDefinition
  3. from fastapi import APIRouter, Depends, HTTPException, Query
  4. from sqlalchemy import text
  5. from sqlalchemy.orm import Session
  6. from app.application.services import WorkflowApplicationService
  7. from app.db.session import get_db
  8. from app.domain.repositories import (
  9. AppDefinitionRepository,
  10. AppVersionRepository,
  11. WorkflowDefinitionRepository,
  12. WorkflowVersionRepository,
  13. )
  14. from app.schemas.app import (
  15. AppCreateRequest,
  16. AppResponse,
  17. AppVersionCreateRequest,
  18. AppVersionResponse,
  19. )
  20. from app.schemas.workflow import (
  21. WorkflowCreateRequest,
  22. WorkflowDebuggerPlanRequest,
  23. WorkflowDebuggerPlanResponse,
  24. WorkflowDefinitionResponse,
  25. WorkflowDesignerValidateRequest,
  26. WorkflowDesignerValidateResponse,
  27. WorkflowVersionCreateRequest,
  28. WorkflowVersionResponse,
  29. )
  30. router = APIRouter()
  31. def get_workflow_application_service(db: Session = Depends(get_db)) -> WorkflowApplicationService:
  32. return WorkflowApplicationService(
  33. app_repository=AppDefinitionRepository(db),
  34. workflow_repository=WorkflowDefinitionRepository(db),
  35. app_version_repository=AppVersionRepository(db),
  36. workflow_version_repository=WorkflowVersionRepository(db))
  37. @router.get("/health", response_model=ServiceHealth)
  38. def health_check(db: Session = Depends(get_db)) -> ServiceHealth:
  39. db.execute(text("SELECT 1"))
  40. return ServiceHealth(service="workflow-service", status="ok", database="ok")
  41. @router.get("/sample", response_model=WorkflowDefinition)
  42. def get_sample_workflow() -> WorkflowDefinition:
  43. return WorkflowDefinition(
  44. code="sample_workflow",
  45. name="Sample Workflow",
  46. nodes=[
  47. NodeDefinition(id="start", type="llm"),
  48. NodeDefinition(id="end", type="answer"),
  49. ],
  50. edges=[EdgeDefinition(source="start", target="end")])
  51. @router.post("/designer/validate", response_model=WorkflowDesignerValidateResponse)
  52. def validate_workflow_designer_dsl(
  53. payload: WorkflowDesignerValidateRequest,
  54. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDesignerValidateResponse:
  55. inspection = service.validate_designer_workflow(payload)
  56. return WorkflowDesignerValidateResponse.from_inspection(inspection)
  57. @router.post("/designer/debug", response_model=WorkflowDebuggerPlanResponse)
  58. def debug_workflow_designer_dsl(
  59. payload: WorkflowDebuggerPlanRequest,
  60. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDebuggerPlanResponse:
  61. plan = service.build_designer_debug_plan(payload)
  62. return WorkflowDebuggerPlanResponse.from_plan(plan)
  63. @router.post("/apps", response_model=AppResponse)
  64. def create_app(
  65. payload: AppCreateRequest,
  66. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> AppResponse:
  67. entity = service.create_app(payload)
  68. return AppResponse.from_entity(entity)
  69. @router.get("/apps", response_model=list[AppResponse])
  70. def list_apps(
  71. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[AppResponse]:
  72. return [AppResponse.from_entity(item) for item in service.list_apps()]
  73. @router.post("/apps/versions", response_model=AppVersionResponse)
  74. def create_app_version(
  75. payload: AppVersionCreateRequest,
  76. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> AppVersionResponse:
  77. entity = service.create_app_version(payload)
  78. return AppVersionResponse.from_entity(entity)
  79. @router.get("/apps/versions", response_model=list[AppVersionResponse])
  80. def list_app_versions(
  81. app_id: str = Query(...),
  82. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[AppVersionResponse]:
  83. return [AppVersionResponse.from_entity(item) for item in service.list_app_versions(app_id)]
  84. @router.post("", response_model=WorkflowDefinitionResponse)
  85. def create_workflow(
  86. payload: WorkflowCreateRequest,
  87. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDefinitionResponse:
  88. entity = service.create_workflow(payload)
  89. return WorkflowDefinitionResponse.from_entity(entity)
  90. @router.get("", response_model=list[WorkflowDefinitionResponse])
  91. def list_workflows(
  92. app_id: str | None = Query(default=None),
  93. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[WorkflowDefinitionResponse]:
  94. items = service.list_workflows(app_id=app_id)
  95. return [WorkflowDefinitionResponse.from_entity(item) for item in items]
  96. @router.post("/versions", response_model=WorkflowVersionResponse)
  97. def create_workflow_version(
  98. payload: WorkflowVersionCreateRequest,
  99. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowVersionResponse:
  100. try:
  101. entity = service.create_workflow_version(payload)
  102. except ValueError as exc:
  103. raise HTTPException(status_code=422, detail=str(exc)) from exc
  104. return WorkflowVersionResponse.from_entity(entity)
  105. @router.get("/versions", response_model=list[WorkflowVersionResponse])
  106. def list_workflow_versions(
  107. workflow_id: str = Query(...),
  108. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[WorkflowVersionResponse]:
  109. items = service.list_workflow_versions(workflow_id=workflow_id)
  110. return [WorkflowVersionResponse.from_entity(item) for item in items]
  111. @router.get("/versions/{workflow_version_id}", response_model=WorkflowVersionResponse)
  112. def get_workflow_version(
  113. workflow_version_id: str,
  114. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowVersionResponse:
  115. entity = service.get_workflow_version(workflow_version_id=workflow_version_id)
  116. if entity is None:
  117. raise HTTPException(status_code=404, detail=f"workflow_version not found: {workflow_version_id}")
  118. return WorkflowVersionResponse.from_entity(entity)
  119. @router.get("/versions/{workflow_version_id}/debug", response_model=WorkflowDebuggerPlanResponse)
  120. def debug_workflow_version(
  121. workflow_version_id: str,
  122. max_preview_steps: int = Query(default=50, ge=1, le=500),
  123. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDebuggerPlanResponse:
  124. plan = service.build_version_debug_plan(
  125. workflow_version_id=workflow_version_id,
  126. max_preview_steps=max_preview_steps)
  127. if plan is None:
  128. raise HTTPException(status_code=404, detail=f"workflow_version not found: {workflow_version_id}")
  129. return WorkflowDebuggerPlanResponse.from_plan(plan)