prefect-client 3.2.2__py3-none-any.whl → 3.2.4__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.
Files changed (50) hide show
  1. prefect/__init__.py +15 -8
  2. prefect/_build_info.py +5 -0
  3. prefect/client/orchestration/__init__.py +16 -5
  4. prefect/main.py +0 -2
  5. prefect/server/api/__init__.py +34 -0
  6. prefect/server/api/admin.py +85 -0
  7. prefect/server/api/artifacts.py +224 -0
  8. prefect/server/api/automations.py +239 -0
  9. prefect/server/api/block_capabilities.py +25 -0
  10. prefect/server/api/block_documents.py +164 -0
  11. prefect/server/api/block_schemas.py +153 -0
  12. prefect/server/api/block_types.py +211 -0
  13. prefect/server/api/clients.py +246 -0
  14. prefect/server/api/collections.py +75 -0
  15. prefect/server/api/concurrency_limits.py +286 -0
  16. prefect/server/api/concurrency_limits_v2.py +269 -0
  17. prefect/server/api/csrf_token.py +38 -0
  18. prefect/server/api/dependencies.py +196 -0
  19. prefect/server/api/deployments.py +941 -0
  20. prefect/server/api/events.py +300 -0
  21. prefect/server/api/flow_run_notification_policies.py +120 -0
  22. prefect/server/api/flow_run_states.py +52 -0
  23. prefect/server/api/flow_runs.py +867 -0
  24. prefect/server/api/flows.py +210 -0
  25. prefect/server/api/logs.py +43 -0
  26. prefect/server/api/middleware.py +73 -0
  27. prefect/server/api/root.py +35 -0
  28. prefect/server/api/run_history.py +170 -0
  29. prefect/server/api/saved_searches.py +99 -0
  30. prefect/server/api/server.py +891 -0
  31. prefect/server/api/task_run_states.py +52 -0
  32. prefect/server/api/task_runs.py +342 -0
  33. prefect/server/api/task_workers.py +31 -0
  34. prefect/server/api/templates.py +35 -0
  35. prefect/server/api/ui/__init__.py +3 -0
  36. prefect/server/api/ui/flow_runs.py +128 -0
  37. prefect/server/api/ui/flows.py +173 -0
  38. prefect/server/api/ui/schemas.py +63 -0
  39. prefect/server/api/ui/task_runs.py +175 -0
  40. prefect/server/api/validation.py +382 -0
  41. prefect/server/api/variables.py +181 -0
  42. prefect/server/api/work_queues.py +230 -0
  43. prefect/server/api/workers.py +656 -0
  44. prefect/settings/sources.py +18 -5
  45. {prefect_client-3.2.2.dist-info → prefect_client-3.2.4.dist-info}/METADATA +10 -15
  46. {prefect_client-3.2.2.dist-info → prefect_client-3.2.4.dist-info}/RECORD +48 -10
  47. {prefect_client-3.2.2.dist-info → prefect_client-3.2.4.dist-info}/WHEEL +1 -2
  48. prefect/_version.py +0 -21
  49. prefect_client-3.2.2.dist-info/top_level.txt +0 -1
  50. {prefect_client-3.2.2.dist-info → prefect_client-3.2.4.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