prefect-client 3.2.1__py3-none-any.whl → 3.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prefect/__init__.py +15 -8
- prefect/_build_info.py +5 -0
- prefect/_internal/schemas/bases.py +4 -7
- prefect/_internal/schemas/validators.py +5 -6
- prefect/_result_records.py +6 -1
- prefect/client/orchestration/__init__.py +18 -6
- prefect/client/schemas/schedules.py +2 -2
- prefect/concurrency/asyncio.py +4 -3
- prefect/concurrency/sync.py +3 -3
- prefect/concurrency/v1/asyncio.py +3 -3
- prefect/concurrency/v1/sync.py +3 -3
- prefect/deployments/flow_runs.py +2 -2
- prefect/docker/docker_image.py +2 -3
- prefect/engine.py +1 -1
- prefect/events/clients.py +4 -3
- prefect/events/related.py +3 -5
- prefect/flows.py +11 -5
- prefect/locking/filesystem.py +8 -8
- prefect/logging/handlers.py +7 -11
- prefect/main.py +0 -2
- prefect/runtime/flow_run.py +10 -17
- prefect/server/api/__init__.py +34 -0
- prefect/server/api/admin.py +85 -0
- prefect/server/api/artifacts.py +224 -0
- prefect/server/api/automations.py +239 -0
- prefect/server/api/block_capabilities.py +25 -0
- prefect/server/api/block_documents.py +164 -0
- prefect/server/api/block_schemas.py +153 -0
- prefect/server/api/block_types.py +211 -0
- prefect/server/api/clients.py +246 -0
- prefect/server/api/collections.py +75 -0
- prefect/server/api/concurrency_limits.py +286 -0
- prefect/server/api/concurrency_limits_v2.py +269 -0
- prefect/server/api/csrf_token.py +38 -0
- prefect/server/api/dependencies.py +196 -0
- prefect/server/api/deployments.py +941 -0
- prefect/server/api/events.py +300 -0
- prefect/server/api/flow_run_notification_policies.py +120 -0
- prefect/server/api/flow_run_states.py +52 -0
- prefect/server/api/flow_runs.py +867 -0
- prefect/server/api/flows.py +210 -0
- prefect/server/api/logs.py +43 -0
- prefect/server/api/middleware.py +73 -0
- prefect/server/api/root.py +35 -0
- prefect/server/api/run_history.py +170 -0
- prefect/server/api/saved_searches.py +99 -0
- prefect/server/api/server.py +891 -0
- prefect/server/api/task_run_states.py +52 -0
- prefect/server/api/task_runs.py +342 -0
- prefect/server/api/task_workers.py +31 -0
- prefect/server/api/templates.py +35 -0
- prefect/server/api/ui/__init__.py +3 -0
- prefect/server/api/ui/flow_runs.py +128 -0
- prefect/server/api/ui/flows.py +173 -0
- prefect/server/api/ui/schemas.py +63 -0
- prefect/server/api/ui/task_runs.py +175 -0
- prefect/server/api/validation.py +382 -0
- prefect/server/api/variables.py +181 -0
- prefect/server/api/work_queues.py +230 -0
- prefect/server/api/workers.py +656 -0
- prefect/settings/sources.py +18 -5
- prefect/states.py +3 -3
- prefect/task_engine.py +3 -3
- prefect/types/_datetime.py +82 -3
- prefect/utilities/dockerutils.py +2 -2
- prefect/workers/base.py +5 -5
- {prefect_client-3.2.1.dist-info → prefect_client-3.2.3.dist-info}/METADATA +10 -15
- {prefect_client-3.2.1.dist-info → prefect_client-3.2.3.dist-info}/RECORD +70 -32
- {prefect_client-3.2.1.dist-info → prefect_client-3.2.3.dist-info}/WHEEL +1 -2
- prefect/_version.py +0 -21
- prefect_client-3.2.1.dist-info/top_level.txt +0 -1
- {prefect_client-3.2.1.dist-info → prefect_client-3.2.3.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,230 @@
|
|
1
|
+
"""
|
2
|
+
Routes for interacting with work queue objects.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional
|
6
|
+
from uuid import UUID
|
7
|
+
|
8
|
+
import sqlalchemy as sa
|
9
|
+
from fastapi import (
|
10
|
+
BackgroundTasks,
|
11
|
+
Body,
|
12
|
+
Depends,
|
13
|
+
Header,
|
14
|
+
HTTPException,
|
15
|
+
Path,
|
16
|
+
status,
|
17
|
+
)
|
18
|
+
|
19
|
+
import prefect.server.api.dependencies as dependencies
|
20
|
+
import prefect.server.models as models
|
21
|
+
import prefect.server.schemas as schemas
|
22
|
+
from prefect.server.database import (
|
23
|
+
PrefectDBInterface,
|
24
|
+
provide_database_interface,
|
25
|
+
)
|
26
|
+
from prefect.server.models.deployments import mark_deployments_ready
|
27
|
+
from prefect.server.models.work_queues import (
|
28
|
+
emit_work_queue_status_event,
|
29
|
+
mark_work_queues_ready,
|
30
|
+
)
|
31
|
+
from prefect.server.schemas.statuses import WorkQueueStatus
|
32
|
+
from prefect.server.utilities.server import PrefectRouter
|
33
|
+
from prefect.types import DateTime
|
34
|
+
|
35
|
+
router: PrefectRouter = PrefectRouter(prefix="/work_queues", tags=["Work Queues"])
|
36
|
+
|
37
|
+
|
38
|
+
@router.post("/", status_code=status.HTTP_201_CREATED)
|
39
|
+
async def create_work_queue(
|
40
|
+
work_queue: schemas.actions.WorkQueueCreate,
|
41
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
42
|
+
) -> schemas.responses.WorkQueueResponse:
|
43
|
+
"""
|
44
|
+
Creates a new work queue.
|
45
|
+
|
46
|
+
If a work queue with the same name already exists, an error
|
47
|
+
will be raised.
|
48
|
+
"""
|
49
|
+
|
50
|
+
try:
|
51
|
+
async with db.session_context(begin_transaction=True) as session:
|
52
|
+
model = await models.work_queues.create_work_queue(
|
53
|
+
session=session, work_queue=work_queue
|
54
|
+
)
|
55
|
+
except sa.exc.IntegrityError:
|
56
|
+
raise HTTPException(
|
57
|
+
status_code=status.HTTP_409_CONFLICT,
|
58
|
+
detail="A work queue with this name already exists.",
|
59
|
+
)
|
60
|
+
|
61
|
+
return schemas.responses.WorkQueueResponse.model_validate(
|
62
|
+
model, from_attributes=True
|
63
|
+
)
|
64
|
+
|
65
|
+
|
66
|
+
@router.patch("/{id}", status_code=status.HTTP_204_NO_CONTENT)
|
67
|
+
async def update_work_queue(
|
68
|
+
work_queue: schemas.actions.WorkQueueUpdate,
|
69
|
+
work_queue_id: UUID = Path(..., description="The work queue id", alias="id"),
|
70
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
71
|
+
) -> None:
|
72
|
+
"""
|
73
|
+
Updates an existing work queue.
|
74
|
+
"""
|
75
|
+
async with db.session_context(begin_transaction=True) as session:
|
76
|
+
result = await models.work_queues.update_work_queue(
|
77
|
+
session=session,
|
78
|
+
work_queue_id=work_queue_id,
|
79
|
+
work_queue=work_queue,
|
80
|
+
emit_status_change=emit_work_queue_status_event,
|
81
|
+
)
|
82
|
+
if not result:
|
83
|
+
raise HTTPException(
|
84
|
+
status_code=status.HTTP_404_NOT_FOUND, detail=f"Work Queue {id} not found"
|
85
|
+
)
|
86
|
+
|
87
|
+
|
88
|
+
@router.get("/name/{name}")
|
89
|
+
async def read_work_queue_by_name(
|
90
|
+
name: str = Path(..., description="The work queue name"),
|
91
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
92
|
+
) -> schemas.responses.WorkQueueResponse:
|
93
|
+
"""
|
94
|
+
Get a work queue by id.
|
95
|
+
"""
|
96
|
+
async with db.session_context() as session:
|
97
|
+
work_queue = await models.work_queues.read_work_queue_by_name(
|
98
|
+
session=session, name=name
|
99
|
+
)
|
100
|
+
if not work_queue:
|
101
|
+
raise HTTPException(
|
102
|
+
status_code=status.HTTP_404_NOT_FOUND, detail="work queue not found"
|
103
|
+
)
|
104
|
+
return schemas.responses.WorkQueueResponse.model_validate(
|
105
|
+
work_queue, from_attributes=True
|
106
|
+
)
|
107
|
+
|
108
|
+
|
109
|
+
@router.get("/{id}")
|
110
|
+
async def read_work_queue(
|
111
|
+
work_queue_id: UUID = Path(..., description="The work queue id", alias="id"),
|
112
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
113
|
+
) -> schemas.responses.WorkQueueResponse:
|
114
|
+
"""
|
115
|
+
Get a work queue by id.
|
116
|
+
"""
|
117
|
+
async with db.session_context() as session:
|
118
|
+
work_queue = await models.work_queues.read_work_queue(
|
119
|
+
session=session, work_queue_id=work_queue_id
|
120
|
+
)
|
121
|
+
if not work_queue:
|
122
|
+
raise HTTPException(
|
123
|
+
status_code=status.HTTP_404_NOT_FOUND, detail="work queue not found"
|
124
|
+
)
|
125
|
+
return schemas.responses.WorkQueueResponse.model_validate(
|
126
|
+
work_queue, from_attributes=True
|
127
|
+
)
|
128
|
+
|
129
|
+
|
130
|
+
@router.post("/{id}/get_runs")
|
131
|
+
async def read_work_queue_runs(
|
132
|
+
background_tasks: BackgroundTasks,
|
133
|
+
work_queue_id: UUID = Path(..., description="The work queue id", alias="id"),
|
134
|
+
limit: int = dependencies.LimitBody(),
|
135
|
+
scheduled_before: DateTime = Body(
|
136
|
+
None,
|
137
|
+
description=(
|
138
|
+
"Only flow runs scheduled to start before this time will be returned."
|
139
|
+
),
|
140
|
+
),
|
141
|
+
x_prefect_ui: Optional[bool] = Header(
|
142
|
+
default=False,
|
143
|
+
description="A header to indicate this request came from the Prefect UI.",
|
144
|
+
),
|
145
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
146
|
+
) -> List[schemas.responses.FlowRunResponse]:
|
147
|
+
"""
|
148
|
+
Get flow runs from the work queue.
|
149
|
+
"""
|
150
|
+
async with db.session_context(begin_transaction=True) as session:
|
151
|
+
work_queue, flow_runs = await models.work_queues.get_runs_in_work_queue(
|
152
|
+
session=session,
|
153
|
+
work_queue_id=work_queue_id,
|
154
|
+
scheduled_before=scheduled_before,
|
155
|
+
limit=limit,
|
156
|
+
)
|
157
|
+
|
158
|
+
# The Prefect UI often calls this route to see which runs are enqueued.
|
159
|
+
# We do not want to record this as an actual poll event.
|
160
|
+
if x_prefect_ui:
|
161
|
+
return flow_runs
|
162
|
+
|
163
|
+
background_tasks.add_task(
|
164
|
+
mark_work_queues_ready,
|
165
|
+
polled_work_queue_ids=[work_queue_id],
|
166
|
+
ready_work_queue_ids=(
|
167
|
+
[work_queue_id] if work_queue.status == WorkQueueStatus.NOT_READY else []
|
168
|
+
),
|
169
|
+
)
|
170
|
+
|
171
|
+
background_tasks.add_task(
|
172
|
+
mark_deployments_ready,
|
173
|
+
work_queue_ids=[work_queue_id],
|
174
|
+
)
|
175
|
+
|
176
|
+
return flow_runs
|
177
|
+
|
178
|
+
|
179
|
+
@router.post("/filter")
|
180
|
+
async def read_work_queues(
|
181
|
+
limit: int = dependencies.LimitBody(),
|
182
|
+
offset: int = Body(0, ge=0),
|
183
|
+
work_queues: schemas.filters.WorkQueueFilter = None,
|
184
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
185
|
+
) -> List[schemas.responses.WorkQueueResponse]:
|
186
|
+
"""
|
187
|
+
Query for work queues.
|
188
|
+
"""
|
189
|
+
async with db.session_context() as session:
|
190
|
+
wqs = await models.work_queues.read_work_queues(
|
191
|
+
session=session, offset=offset, limit=limit, work_queue_filter=work_queues
|
192
|
+
)
|
193
|
+
|
194
|
+
return [
|
195
|
+
schemas.responses.WorkQueueResponse.model_validate(wq, from_attributes=True)
|
196
|
+
for wq in wqs
|
197
|
+
]
|
198
|
+
|
199
|
+
|
200
|
+
@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
|
201
|
+
async def delete_work_queue(
|
202
|
+
work_queue_id: UUID = Path(..., description="The work queue id", alias="id"),
|
203
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
204
|
+
) -> None:
|
205
|
+
"""
|
206
|
+
Delete a work queue by id.
|
207
|
+
"""
|
208
|
+
async with db.session_context(begin_transaction=True) as session:
|
209
|
+
result = await models.work_queues.delete_work_queue(
|
210
|
+
session=session, work_queue_id=work_queue_id
|
211
|
+
)
|
212
|
+
if not result:
|
213
|
+
raise HTTPException(
|
214
|
+
status_code=status.HTTP_404_NOT_FOUND, detail="work queue not found"
|
215
|
+
)
|
216
|
+
|
217
|
+
|
218
|
+
@router.get("/{id}/status")
|
219
|
+
async def read_work_queue_status(
|
220
|
+
work_queue_id: UUID = Path(..., description="The work queue id", alias="id"),
|
221
|
+
db: PrefectDBInterface = Depends(provide_database_interface),
|
222
|
+
) -> schemas.core.WorkQueueStatusDetail:
|
223
|
+
"""
|
224
|
+
Get the status of a work queue.
|
225
|
+
"""
|
226
|
+
async with db.session_context() as session:
|
227
|
+
work_queue_status = await models.work_queues.read_work_queue_status(
|
228
|
+
session=session, work_queue_id=work_queue_id
|
229
|
+
)
|
230
|
+
return work_queue_status
|