prefect-client 3.1.13__py3-none-any.whl → 3.1.14__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/_experimental/lineage.py +63 -0
- prefect/_version.py +3 -3
- prefect/cache_policies.py +50 -2
- prefect/client/orchestration/_automations/client.py +4 -0
- prefect/client/orchestration/_deployments/client.py +3 -3
- prefect/context.py +16 -6
- prefect/events/filters.py +34 -34
- prefect/flow_engine.py +155 -114
- prefect/flows.py +1 -1
- prefect/logging/configuration.py +2 -5
- prefect/logging/loggers.py +1 -2
- prefect/runner/runner.py +79 -58
- prefect/tasks.py +37 -1
- prefect/types/__init__.py +6 -5
- prefect/types/_datetime.py +19 -0
- {prefect_client-3.1.13.dist-info → prefect_client-3.1.14.dist-info}/METADATA +1 -1
- {prefect_client-3.1.13.dist-info → prefect_client-3.1.14.dist-info}/RECORD +20 -19
- {prefect_client-3.1.13.dist-info → prefect_client-3.1.14.dist-info}/LICENSE +0 -0
- {prefect_client-3.1.13.dist-info → prefect_client-3.1.14.dist-info}/WHEEL +0 -0
- {prefect_client-3.1.13.dist-info → prefect_client-3.1.14.dist-info}/top_level.txt +0 -0
prefect/flow_engine.py
CHANGED
@@ -39,6 +39,7 @@ from prefect.context import (
|
|
39
39
|
FlowRunContext,
|
40
40
|
SyncClientContext,
|
41
41
|
TagsContext,
|
42
|
+
hydrated_context,
|
42
43
|
)
|
43
44
|
from prefect.exceptions import (
|
44
45
|
Abort,
|
@@ -137,6 +138,7 @@ class BaseFlowRunEngine(Generic[P, R]):
|
|
137
138
|
flow_run_id: Optional[UUID] = None
|
138
139
|
logger: logging.Logger = field(default_factory=lambda: get_logger("engine"))
|
139
140
|
wait_for: Optional[Iterable[PrefectFuture[Any]]] = None
|
141
|
+
context: Optional[dict[str, Any]] = None
|
140
142
|
# holds the return value from the user code
|
141
143
|
_return_value: Union[R, Type[NotSet]] = NotSet
|
142
144
|
# holds the exception raised by the user code, if any
|
@@ -647,65 +649,68 @@ class FlowRunEngine(BaseFlowRunEngine[P, R]):
|
|
647
649
|
"""
|
648
650
|
Enters a client context and creates a flow run if needed.
|
649
651
|
"""
|
650
|
-
with
|
651
|
-
|
652
|
-
|
652
|
+
with hydrated_context(self.context):
|
653
|
+
with SyncClientContext.get_or_create() as client_ctx:
|
654
|
+
self._client = client_ctx.client
|
655
|
+
self._is_started = True
|
653
656
|
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
657
|
+
if not self.flow_run:
|
658
|
+
self.flow_run = self.create_flow_run(self.client)
|
659
|
+
else:
|
660
|
+
# Update the empirical policy to match the flow if it is not set
|
661
|
+
if self.flow_run.empirical_policy.retry_delay is None:
|
662
|
+
self.flow_run.empirical_policy.retry_delay = (
|
663
|
+
self.flow.retry_delay_seconds
|
664
|
+
)
|
662
665
|
|
663
|
-
|
664
|
-
|
666
|
+
if self.flow_run.empirical_policy.retries is None:
|
667
|
+
self.flow_run.empirical_policy.retries = self.flow.retries
|
665
668
|
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
669
|
+
self.client.update_flow_run(
|
670
|
+
flow_run_id=self.flow_run.id,
|
671
|
+
flow_version=self.flow.version,
|
672
|
+
empirical_policy=self.flow_run.empirical_policy,
|
673
|
+
)
|
671
674
|
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
675
|
+
self._telemetry.start_span(
|
676
|
+
run=self.flow_run,
|
677
|
+
client=self.client,
|
678
|
+
parameters=self.parameters,
|
679
|
+
)
|
677
680
|
|
678
|
-
|
679
|
-
|
681
|
+
try:
|
682
|
+
yield self
|
680
683
|
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
684
|
+
except TerminationSignal as exc:
|
685
|
+
self.cancel_all_tasks()
|
686
|
+
self.handle_crash(exc)
|
687
|
+
raise
|
688
|
+
except Exception:
|
689
|
+
# regular exceptions are caught and re-raised to the user
|
690
|
+
raise
|
691
|
+
except (Abort, Pause):
|
692
|
+
raise
|
693
|
+
except GeneratorExit:
|
694
|
+
# Do not capture generator exits as crashes
|
695
|
+
raise
|
696
|
+
except BaseException as exc:
|
697
|
+
# BaseExceptions are caught and handled as crashes
|
698
|
+
self.handle_crash(exc)
|
699
|
+
raise
|
700
|
+
finally:
|
701
|
+
# If debugging, use the more complete `repr` than the usual `str` description
|
702
|
+
display_state = (
|
703
|
+
repr(self.state) if PREFECT_DEBUG_MODE else str(self.state)
|
704
|
+
)
|
705
|
+
self.logger.log(
|
706
|
+
level=logging.INFO
|
707
|
+
if self.state.is_completed()
|
708
|
+
else logging.ERROR,
|
709
|
+
msg=f"Finished in state {display_state}",
|
710
|
+
)
|
706
711
|
|
707
|
-
|
708
|
-
|
712
|
+
self._is_started = False
|
713
|
+
self._client = None
|
709
714
|
|
710
715
|
# --------------------------
|
711
716
|
#
|
@@ -1208,71 +1213,74 @@ class AsyncFlowRunEngine(BaseFlowRunEngine[P, R]):
|
|
1208
1213
|
"""
|
1209
1214
|
Enters a client context and creates a flow run if needed.
|
1210
1215
|
"""
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1216
|
+
with hydrated_context(self.context):
|
1217
|
+
async with AsyncClientContext.get_or_create() as client_ctx:
|
1218
|
+
self._client = client_ctx.client
|
1219
|
+
self._is_started = True
|
1220
|
+
|
1221
|
+
if not self.flow_run:
|
1222
|
+
self.flow_run = await self.create_flow_run(self.client)
|
1223
|
+
flow_run_url = url_for(self.flow_run)
|
1224
|
+
|
1225
|
+
if flow_run_url:
|
1226
|
+
self.logger.info(
|
1227
|
+
f"View at {flow_run_url}", extra={"send_to_api": False}
|
1228
|
+
)
|
1229
|
+
else:
|
1230
|
+
# Update the empirical policy to match the flow if it is not set
|
1231
|
+
if self.flow_run.empirical_policy.retry_delay is None:
|
1232
|
+
self.flow_run.empirical_policy.retry_delay = (
|
1233
|
+
self.flow.retry_delay_seconds
|
1234
|
+
)
|
1214
1235
|
|
1215
|
-
|
1216
|
-
|
1217
|
-
flow_run_url = url_for(self.flow_run)
|
1236
|
+
if self.flow_run.empirical_policy.retries is None:
|
1237
|
+
self.flow_run.empirical_policy.retries = self.flow.retries
|
1218
1238
|
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
else:
|
1224
|
-
# Update the empirical policy to match the flow if it is not set
|
1225
|
-
if self.flow_run.empirical_policy.retry_delay is None:
|
1226
|
-
self.flow_run.empirical_policy.retry_delay = (
|
1227
|
-
self.flow.retry_delay_seconds
|
1239
|
+
await self.client.update_flow_run(
|
1240
|
+
flow_run_id=self.flow_run.id,
|
1241
|
+
flow_version=self.flow.version,
|
1242
|
+
empirical_policy=self.flow_run.empirical_policy,
|
1228
1243
|
)
|
1229
1244
|
|
1230
|
-
|
1231
|
-
self.flow_run
|
1232
|
-
|
1233
|
-
|
1234
|
-
flow_run_id=self.flow_run.id,
|
1235
|
-
flow_version=self.flow.version,
|
1236
|
-
empirical_policy=self.flow_run.empirical_policy,
|
1245
|
+
await self._telemetry.async_start_span(
|
1246
|
+
run=self.flow_run,
|
1247
|
+
client=self.client,
|
1248
|
+
parameters=self.parameters,
|
1237
1249
|
)
|
1238
1250
|
|
1239
|
-
|
1240
|
-
|
1241
|
-
client=self.client,
|
1242
|
-
parameters=self.parameters,
|
1243
|
-
)
|
1244
|
-
|
1245
|
-
try:
|
1246
|
-
yield self
|
1251
|
+
try:
|
1252
|
+
yield self
|
1247
1253
|
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1254
|
+
except TerminationSignal as exc:
|
1255
|
+
self.cancel_all_tasks()
|
1256
|
+
await self.handle_crash(exc)
|
1257
|
+
raise
|
1258
|
+
except Exception:
|
1259
|
+
# regular exceptions are caught and re-raised to the user
|
1260
|
+
raise
|
1261
|
+
except (Abort, Pause):
|
1262
|
+
raise
|
1263
|
+
except GeneratorExit:
|
1264
|
+
# Do not capture generator exits as crashes
|
1265
|
+
raise
|
1266
|
+
except BaseException as exc:
|
1267
|
+
# BaseExceptions are caught and handled as crashes
|
1268
|
+
await self.handle_crash(exc)
|
1269
|
+
raise
|
1270
|
+
finally:
|
1271
|
+
# If debugging, use the more complete `repr` than the usual `str` description
|
1272
|
+
display_state = (
|
1273
|
+
repr(self.state) if PREFECT_DEBUG_MODE else str(self.state)
|
1274
|
+
)
|
1275
|
+
self.logger.log(
|
1276
|
+
level=logging.INFO
|
1277
|
+
if self.state.is_completed()
|
1278
|
+
else logging.ERROR,
|
1279
|
+
msg=f"Finished in state {display_state}",
|
1280
|
+
)
|
1273
1281
|
|
1274
|
-
|
1275
|
-
|
1282
|
+
self._is_started = False
|
1283
|
+
self._client = None
|
1276
1284
|
|
1277
1285
|
# --------------------------
|
1278
1286
|
#
|
@@ -1330,12 +1338,14 @@ def run_flow_sync(
|
|
1330
1338
|
parameters: Optional[Dict[str, Any]] = None,
|
1331
1339
|
wait_for: Optional[Iterable[PrefectFuture[Any]]] = None,
|
1332
1340
|
return_type: Literal["state", "result"] = "result",
|
1341
|
+
context: Optional[dict[str, Any]] = None,
|
1333
1342
|
) -> Union[R, State, None]:
|
1334
1343
|
engine = FlowRunEngine[P, R](
|
1335
1344
|
flow=flow,
|
1336
1345
|
parameters=parameters,
|
1337
1346
|
flow_run=flow_run,
|
1338
1347
|
wait_for=wait_for,
|
1348
|
+
context=context,
|
1339
1349
|
)
|
1340
1350
|
|
1341
1351
|
with engine.start():
|
@@ -1352,9 +1362,14 @@ async def run_flow_async(
|
|
1352
1362
|
parameters: Optional[Dict[str, Any]] = None,
|
1353
1363
|
wait_for: Optional[Iterable[PrefectFuture[Any]]] = None,
|
1354
1364
|
return_type: Literal["state", "result"] = "result",
|
1365
|
+
context: Optional[dict[str, Any]] = None,
|
1355
1366
|
) -> Union[R, State, None]:
|
1356
1367
|
engine = AsyncFlowRunEngine[P, R](
|
1357
|
-
flow=flow,
|
1368
|
+
flow=flow,
|
1369
|
+
parameters=parameters,
|
1370
|
+
flow_run=flow_run,
|
1371
|
+
wait_for=wait_for,
|
1372
|
+
context=context,
|
1358
1373
|
)
|
1359
1374
|
|
1360
1375
|
async with engine.start():
|
@@ -1371,12 +1386,17 @@ def run_generator_flow_sync(
|
|
1371
1386
|
parameters: Optional[Dict[str, Any]] = None,
|
1372
1387
|
wait_for: Optional[Iterable[PrefectFuture[Any]]] = None,
|
1373
1388
|
return_type: Literal["state", "result"] = "result",
|
1389
|
+
context: Optional[dict[str, Any]] = None,
|
1374
1390
|
) -> Generator[R, None, None]:
|
1375
1391
|
if return_type != "result":
|
1376
1392
|
raise ValueError("The return_type for a generator flow must be 'result'")
|
1377
1393
|
|
1378
1394
|
engine = FlowRunEngine[P, R](
|
1379
|
-
flow=flow,
|
1395
|
+
flow=flow,
|
1396
|
+
parameters=parameters,
|
1397
|
+
flow_run=flow_run,
|
1398
|
+
wait_for=wait_for,
|
1399
|
+
context=context,
|
1380
1400
|
)
|
1381
1401
|
|
1382
1402
|
with engine.start():
|
@@ -1407,12 +1427,17 @@ async def run_generator_flow_async(
|
|
1407
1427
|
parameters: Optional[Dict[str, Any]] = None,
|
1408
1428
|
wait_for: Optional[Iterable[PrefectFuture[R]]] = None,
|
1409
1429
|
return_type: Literal["state", "result"] = "result",
|
1430
|
+
context: Optional[dict[str, Any]] = None,
|
1410
1431
|
) -> AsyncGenerator[R, None]:
|
1411
1432
|
if return_type != "result":
|
1412
1433
|
raise ValueError("The return_type for a generator flow must be 'result'")
|
1413
1434
|
|
1414
1435
|
engine = AsyncFlowRunEngine[P, R](
|
1415
|
-
flow=flow,
|
1436
|
+
flow=flow,
|
1437
|
+
parameters=parameters,
|
1438
|
+
flow_run=flow_run,
|
1439
|
+
wait_for=wait_for,
|
1440
|
+
context=context,
|
1416
1441
|
)
|
1417
1442
|
|
1418
1443
|
async with engine.start():
|
@@ -1446,8 +1471,23 @@ def run_flow(
|
|
1446
1471
|
wait_for: Optional[Iterable[PrefectFuture[R]]] = None,
|
1447
1472
|
return_type: Literal["state", "result"] = "result",
|
1448
1473
|
error_logger: Optional[logging.Logger] = None,
|
1449
|
-
|
1450
|
-
|
1474
|
+
context: Optional[dict[str, Any]] = None,
|
1475
|
+
) -> (
|
1476
|
+
R
|
1477
|
+
| State
|
1478
|
+
| None
|
1479
|
+
| Coroutine[Any, Any, R | State | None]
|
1480
|
+
| Generator[R, None, None]
|
1481
|
+
| AsyncGenerator[R, None]
|
1482
|
+
):
|
1483
|
+
ret_val: Union[
|
1484
|
+
R,
|
1485
|
+
State,
|
1486
|
+
None,
|
1487
|
+
Coroutine[Any, Any, R | State | None],
|
1488
|
+
Generator[R, None, None],
|
1489
|
+
AsyncGenerator[R, None],
|
1490
|
+
] = None
|
1451
1491
|
|
1452
1492
|
try:
|
1453
1493
|
kwargs: dict[str, Any] = dict(
|
@@ -1458,6 +1498,7 @@ def run_flow(
|
|
1458
1498
|
),
|
1459
1499
|
wait_for=wait_for,
|
1460
1500
|
return_type=return_type,
|
1501
|
+
context=context,
|
1461
1502
|
)
|
1462
1503
|
|
1463
1504
|
if flow.isasync and flow.isgenerator:
|
prefect/flows.py
CHANGED
@@ -127,9 +127,9 @@ if TYPE_CHECKING:
|
|
127
127
|
import logging
|
128
128
|
|
129
129
|
from prefect.client.orchestration import PrefectClient
|
130
|
+
from prefect.client.schemas.objects import FlowRun
|
130
131
|
from prefect.client.types.flexible_schedule_list import FlexibleScheduleList
|
131
132
|
from prefect.deployments.runner import RunnerDeployment
|
132
|
-
from prefect.flows import FlowRun
|
133
133
|
from prefect.runner.storage import RunnerStorage
|
134
134
|
|
135
135
|
logger: "logging.Logger" = get_logger("flows")
|
prefect/logging/configuration.py
CHANGED
@@ -94,12 +94,9 @@ def setup_logging(incremental: Optional[bool] = None) -> dict[str, Any]:
|
|
94
94
|
|
95
95
|
for logger_name in PREFECT_LOGGING_EXTRA_LOGGERS.value():
|
96
96
|
logger = logging.getLogger(logger_name)
|
97
|
-
|
98
|
-
|
97
|
+
if not config["incremental"]:
|
98
|
+
for handler in extra_config.handlers:
|
99
99
|
logger.addHandler(handler)
|
100
|
-
if logger.level == logging.NOTSET:
|
101
|
-
logger.setLevel(extra_config.level)
|
102
|
-
logger.propagate = extra_config.propagate
|
103
100
|
|
104
101
|
PROCESS_LOGGING_CONFIG = config
|
105
102
|
|
prefect/logging/loggers.py
CHANGED
@@ -24,7 +24,6 @@ else:
|
|
24
24
|
LoggingAdapter = logging.LoggerAdapter
|
25
25
|
|
26
26
|
if TYPE_CHECKING:
|
27
|
-
from prefect.client.schemas import FlowRun as ClientFlowRun
|
28
27
|
from prefect.client.schemas.objects import FlowRun, TaskRun
|
29
28
|
from prefect.context import RunContext
|
30
29
|
from prefect.flows import Flow
|
@@ -164,7 +163,7 @@ def get_run_logger(
|
|
164
163
|
|
165
164
|
|
166
165
|
def flow_run_logger(
|
167
|
-
flow_run:
|
166
|
+
flow_run: "FlowRun",
|
168
167
|
flow: Optional["Flow[Any, Any]"] = None,
|
169
168
|
**kwargs: str,
|
170
169
|
) -> PrefectLogAdapter:
|