10000 Add UI-specific route for task run details (#17708) · CodersSampling/prefect@6a4bc14 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6a4bc14

Browse files
authored
Add UI-specific route for task run details (PrefectHQ#17708)
1 parent 385b8bd commit 6a4bc14

File tree

14 files changed

+722
-25
lines changed

14 files changed

+722
-25
lines changed

docs/docs.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@
291291
"v3/api-ref/rest-api/server/task-runs/paginate-task-runs",
292292
"v3/api-ref/rest-api/server/task-runs/set-task-run-state",
293293
"v3/api-ref/rest-api/server/task-runs/read-dashboard-task-run-counts",
294-
"v3/api-ref/rest-api/server/task-runs/read-task-run-counts-by-state"
294+
"v3/api-ref/rest-api/server/task-runs/read-task-run-counts-by-state",
295+
"v3/api-ref/rest-api/server/task-runs/read-task-run-with-flow-run-name"
295296
]
296297
},
297298
{

docs/v3/api-ref/rest-api/server/schema.json

Lines changed: 378 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
openapi: get /api/ui/task_runs/{id}
3+
---
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
openapi: get /api/ui/task_runs/{id}
3+
---

src/prefect/server/api/ui/task_runs.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from datetime import datetime
22
from typing import TYPE_CHECKING, List, Optional
3+
from uuid import UUID
34

45
import sqlalchemy as sa
5-
from fastapi import Depends, HTTPException, status
6+
from fastapi import Depends, HTTPException, Path, status
67
from pydantic import Field, model_serializer
78

89
import prefect.server.schemas as schemas
@@ -173,3 +174,22 @@ async def read_task_run_counts_by_state(
173174
task_run_filter=task_runs,
174175
deployment_filter=deployments,
175176
)
177+
178+
179+
@router.get("/{id}")
180+
async def read_task_run_with_flow_run_name(
181+
task_run_id: UUID = Path(..., description="The task run id", alias="id"),
182+
db: PrefectDBInterface = Depends(provide_database_interface),
183+
) -> schemas.ui.UITaskRun:
184+
"""
185+
Get a task run by id.
186+
"""
187+
async with db.session_context() as session:
188+
task_run = await models.task_runs.read_task_run_with_flow_run_name(
189+
session=session, task_run_id=task_run_id
190+
)
191+
192+
if not task_run:
193+
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Task not found")
194+
195+
return schemas.ui.UITaskRun.model_validate(task_run)

src/prefect/server/models/task_runs.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,39 @@ async def read_task_run(
195195
return model
196196

197197

198+
@db_injector
199+
async def read_task_run_with_flow_run_name(
200+
db: PrefectDBInterface, session: AsyncSession, task_run_id: UUID
201+
) -> Union[orm_models.TaskRun, None]:
202+
"""
203+
Read a task run by id.
204+
205+
Args:
206+
session: a database session
207+
task_run_id: the task run id
208+
209+
Returns:
210+
orm_models.TaskRun: the task run with the flow run name
211+
"""
212+
213+
result = await session.execute(
214+
select(orm_models.TaskRun, orm_models.FlowRun.name.label("flow_run_name"))
215+
.outerjoin(
216+
orm_models.FlowRun, orm_models.TaskRun.flow_run_id == orm_models.FlowRun.id
217+
)
218+
.where(orm_models.TaskRun.id == task_run_id)
219+
)
220+
row = result.first()
221+
if not row:
222+
return None
223+
224+
task_run = row[0]
225+
flow_run_name = row[1]
226+
if flow_run_name:
227+
setattr(task_run, "flow_run_name", flow_run_name)
228+
return task_run
229+
230+
198231
async def _apply_task_run_filters(
199232
db: PrefectDBInterface,
200233
query: Select[T],

src/prefect/server/schemas/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
responses,
99
actions,
1010
internal,
11+
ui,
1112
) # noqa
1213

1314
__all__ = [
@@ -20,4 +21,5 @@
2021
"states",
2122
"statuses",
2223
"internal",
24+
"ui",
2325
]

src/prefect/server/schemas/ui.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""Schemas for UI endpoints."""
2+
3+
from typing import Optional
4+
5+
from prefect.server.schemas.core import TaskRun as CoreTaskRun
6+
7+
8+
class UITaskRun(CoreTaskRun):
9+
"""A task run with additional details for display in the UI."""
10+
11+
flow_run_name: Optional[str] = None

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ def pytest_addoption(parser: pytest.Parser) -> None:
140140
"tests/_internal",
141141
"tests/server/orchestration/test_rules.py",
142142
"tests/test_flows.py",
143+
"tests/server/orchestration/api/ui/test_task_runs.py",
143144
]
144145

145146

tests/fixtures/database.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,19 @@ async def register_block_types(session):
154154

155155

156156
@pytest.fixture
157-
async def flow(session):
157+
async def flow(session: AsyncSession):
158158
model = await models.flows.create_flow(
159-
session=session, flow=schemas.actions.FlowCreate(name="my-flow")
159+
session=session, flow=schemas.core.Flow(name=f"my-flow-{uuid.uuid4()}")
160160
)
161161
await session.commit()
162162
return model
163163

164164

165165
@pytest.fixture
166-
async def flow_run(session, flow):
166+
async def flow_run(session: AsyncSession, flow: orm_models.Flow):
167167
model = await models.flow_runs.create_flow_run(
168168
session=session,
169-
flow_run=schemas.actions.FlowRunCreate(flow_id=flow.id, flow_version="0.1"),
169+
flow_run=schemas.core.FlowRun(flow_id=flow.id, flow_version="0.1"),
170170
)
171171
await session.commit()
172172
return model
@@ -327,6 +327,16 @@ async def task_run(session, flow_run):
327327
return model
328328

329329

330+
@pytest.fixture
331+
async def task_run_without_flow_run(session: AsyncSession):
332+
model = await models.task_runs.create_task_run(
333+
session=session,
334+
task_run=schemas.core.TaskRun(task_key="my-key", dynamic_key="0"),
335+
)
336+
await session.commit()
337+
return model
338+
339+
330340
@pytest.fixture
331341
async def task_run_state(session, task_run, db):
332342
task_run.set_state(db.TaskRunState(**schemas.states.Pending().orm_dict()))

0 commit comments

Comments
 (0)
0