flyte 2.0.0b21__py3-none-any.whl → 2.0.0b23__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.
Potentially problematic release.
This version of flyte might be problematic. Click here for more details.
- flyte/__init__.py +5 -0
- flyte/_bin/runtime.py +36 -6
- flyte/_cache/cache.py +4 -2
- flyte/_cache/local_cache.py +215 -0
- flyte/_code_bundle/bundle.py +1 -0
- flyte/_debug/constants.py +0 -1
- flyte/_debug/vscode.py +6 -1
- flyte/_deploy.py +204 -55
- flyte/_environment.py +5 -0
- flyte/_excepthook.py +1 -1
- flyte/_image.py +101 -68
- flyte/_initialize.py +30 -1
- flyte/_interface.py +3 -1
- flyte/_internal/controllers/_local_controller.py +64 -24
- flyte/_internal/controllers/remote/_action.py +4 -1
- flyte/_internal/controllers/remote/_controller.py +5 -2
- flyte/_internal/controllers/remote/_core.py +6 -3
- flyte/_internal/controllers/remote/_informer.py +1 -1
- flyte/_internal/imagebuild/docker_builder.py +95 -28
- flyte/_internal/imagebuild/image_builder.py +0 -5
- flyte/_internal/imagebuild/remote_builder.py +6 -1
- flyte/_internal/runtime/io.py +13 -1
- flyte/_internal/runtime/rusty.py +17 -2
- flyte/_internal/runtime/task_serde.py +15 -11
- flyte/_internal/runtime/taskrunner.py +1 -1
- flyte/_internal/runtime/trigger_serde.py +153 -0
- flyte/_keyring/file.py +2 -2
- flyte/_logging.py +1 -1
- flyte/_protos/common/identifier_pb2.py +19 -1
- flyte/_protos/common/identifier_pb2.pyi +22 -0
- flyte/_protos/workflow/common_pb2.py +14 -3
- flyte/_protos/workflow/common_pb2.pyi +49 -0
- flyte/_protos/workflow/queue_service_pb2.py +41 -35
- flyte/_protos/workflow/queue_service_pb2.pyi +26 -12
- flyte/_protos/workflow/queue_service_pb2_grpc.py +34 -0
- flyte/_protos/workflow/run_definition_pb2.py +38 -38
- flyte/_protos/workflow/run_definition_pb2.pyi +4 -2
- flyte/_protos/workflow/run_service_pb2.py +60 -50
- flyte/_protos/workflow/run_service_pb2.pyi +24 -6
- flyte/_protos/workflow/run_service_pb2_grpc.py +34 -0
- flyte/_protos/workflow/task_definition_pb2.py +15 -11
- flyte/_protos/workflow/task_definition_pb2.pyi +19 -2
- flyte/_protos/workflow/task_service_pb2.py +18 -17
- flyte/_protos/workflow/task_service_pb2.pyi +5 -2
- flyte/_protos/workflow/trigger_definition_pb2.py +66 -0
- flyte/_protos/workflow/trigger_definition_pb2.pyi +117 -0
- flyte/_protos/workflow/trigger_definition_pb2_grpc.py +4 -0
- flyte/_protos/workflow/trigger_service_pb2.py +96 -0
- flyte/_protos/workflow/trigger_service_pb2.pyi +110 -0
- flyte/_protos/workflow/trigger_service_pb2_grpc.py +281 -0
- flyte/_run.py +42 -15
- flyte/_task.py +35 -4
- flyte/_task_environment.py +61 -16
- flyte/_trigger.py +382 -0
- flyte/_version.py +3 -3
- flyte/cli/_abort.py +3 -3
- flyte/cli/_build.py +1 -3
- flyte/cli/_common.py +17 -4
- flyte/cli/_create.py +74 -0
- flyte/cli/_delete.py +23 -1
- flyte/cli/_deploy.py +16 -10
- flyte/cli/_get.py +75 -34
- flyte/cli/_params.py +4 -2
- flyte/cli/_run.py +25 -6
- flyte/cli/_update.py +36 -0
- flyte/cli/_user.py +17 -0
- flyte/cli/main.py +9 -1
- flyte/errors.py +9 -0
- flyte/io/_dir.py +513 -115
- flyte/io/_file.py +495 -135
- flyte/models.py +32 -0
- flyte/remote/__init__.py +6 -1
- flyte/remote/_action.py +9 -8
- flyte/remote/_client/_protocols.py +36 -2
- flyte/remote/_client/controlplane.py +19 -3
- flyte/remote/_run.py +42 -2
- flyte/remote/_task.py +14 -1
- flyte/remote/_trigger.py +308 -0
- flyte/remote/_user.py +33 -0
- flyte/storage/__init__.py +6 -1
- flyte/storage/_storage.py +119 -101
- flyte/types/_pickle.py +34 -7
- flyte/types/_type_engine.py +6 -0
- {flyte-2.0.0b21.data → flyte-2.0.0b23.data}/scripts/runtime.py +36 -6
- {flyte-2.0.0b21.dist-info → flyte-2.0.0b23.dist-info}/METADATA +3 -1
- {flyte-2.0.0b21.dist-info → flyte-2.0.0b23.dist-info}/RECORD +91 -79
- flyte/_protos/secret/secret_pb2_grpc_grpc.py +0 -198
- {flyte-2.0.0b21.data → flyte-2.0.0b23.data}/scripts/debug.py +0 -0
- {flyte-2.0.0b21.dist-info → flyte-2.0.0b23.dist-info}/WHEEL +0 -0
- {flyte-2.0.0b21.dist-info → flyte-2.0.0b23.dist-info}/entry_points.txt +0 -0
- {flyte-2.0.0b21.dist-info → flyte-2.0.0b23.dist-info}/licenses/LICENSE +0 -0
- {flyte-2.0.0b21.dist-info → flyte-2.0.0b23.dist-info}/top_level.txt +0 -0
flyte/_run.py
CHANGED
|
@@ -90,9 +90,10 @@ class _Runner:
|
|
|
90
90
|
env_vars: Dict[str, str] | None = None,
|
|
91
91
|
labels: Dict[str, str] | None = None,
|
|
92
92
|
annotations: Dict[str, str] | None = None,
|
|
93
|
-
interruptible: bool =
|
|
93
|
+
interruptible: bool | None = None,
|
|
94
94
|
log_level: int | None = None,
|
|
95
95
|
disable_run_cache: bool = False,
|
|
96
|
+
queue: Optional[str] = None,
|
|
96
97
|
):
|
|
97
98
|
from flyte._tools import ipython_check
|
|
98
99
|
|
|
@@ -111,8 +112,8 @@ class _Runner:
|
|
|
111
112
|
self._copy_bundle_to = copy_bundle_to
|
|
112
113
|
self._interactive_mode = interactive_mode if interactive_mode else ipython_check()
|
|
113
114
|
self._raw_data_path = raw_data_path
|
|
114
|
-
self._metadata_path = metadata_path
|
|
115
|
-
self._run_base_dir = run_base_dir
|
|
115
|
+
self._metadata_path = metadata_path
|
|
116
|
+
self._run_base_dir = run_base_dir
|
|
116
117
|
self._overwrite_cache = overwrite_cache
|
|
117
118
|
self._project = project
|
|
118
119
|
self._domain = domain
|
|
@@ -122,6 +123,7 @@ class _Runner:
|
|
|
122
123
|
self._interruptible = interruptible
|
|
123
124
|
self._log_level = log_level
|
|
124
125
|
self._disable_run_cache = disable_run_cache
|
|
126
|
+
self._queue = queue
|
|
125
127
|
|
|
126
128
|
@requires_initialization
|
|
127
129
|
async def _run_remote(self, obj: TaskTemplate[P, R] | LazyEntity, *args: P.args, **kwargs: P.kwargs) -> Run:
|
|
@@ -150,6 +152,7 @@ class _Runner:
|
|
|
150
152
|
version = task.pb2.task_id.version
|
|
151
153
|
code_bundle = None
|
|
152
154
|
else:
|
|
155
|
+
task = cast(TaskTemplate[P, R], obj)
|
|
153
156
|
if obj.parent_env is None:
|
|
154
157
|
raise ValueError("Task is not attached to an environment. Please attach the task to an environment")
|
|
155
158
|
|
|
@@ -204,10 +207,11 @@ class _Runner:
|
|
|
204
207
|
inputs = await convert_from_native_to_inputs(obj.native_interface, *args, **kwargs)
|
|
205
208
|
|
|
206
209
|
env = self._env_vars or {}
|
|
207
|
-
if
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
if env.get("LOG_LEVEL") is None:
|
|
211
|
+
if self._log_level:
|
|
212
|
+
env["LOG_LEVEL"] = str(self._log_level)
|
|
213
|
+
else:
|
|
214
|
+
env["LOG_LEVEL"] = str(logger.getEffectiveLevel())
|
|
211
215
|
|
|
212
216
|
if not self._dry_run:
|
|
213
217
|
if get_client() is None:
|
|
@@ -263,10 +267,13 @@ class _Runner:
|
|
|
263
267
|
inputs=inputs.proto_inputs,
|
|
264
268
|
run_spec=run_definition_pb2.RunSpec(
|
|
265
269
|
overwrite_cache=self._overwrite_cache,
|
|
266
|
-
interruptible=wrappers_pb2.BoolValue(value=self._interruptible)
|
|
270
|
+
interruptible=wrappers_pb2.BoolValue(value=self._interruptible)
|
|
271
|
+
if self._interruptible is not None
|
|
272
|
+
else None,
|
|
267
273
|
annotations=annotations,
|
|
268
274
|
labels=labels,
|
|
269
275
|
envs=env_kv,
|
|
276
|
+
cluster=self._queue or task.queue,
|
|
270
277
|
),
|
|
271
278
|
),
|
|
272
279
|
)
|
|
@@ -385,6 +392,7 @@ class _Runner:
|
|
|
385
392
|
" flyte.with_runcontext(run_base_dir='s3://bucket/metadata/outputs')",
|
|
386
393
|
)
|
|
387
394
|
output_path = self._run_base_dir
|
|
395
|
+
run_base_dir = self._run_base_dir
|
|
388
396
|
raw_data_path = f"{output_path}/rd/{random_id}"
|
|
389
397
|
raw_data_path_obj = RawDataPath(path=raw_data_path)
|
|
390
398
|
checkpoint_path = f"{raw_data_path}/checkpoint"
|
|
@@ -401,7 +409,7 @@ class _Runner:
|
|
|
401
409
|
version=version if version else "na",
|
|
402
410
|
raw_data_path=raw_data_path_obj,
|
|
403
411
|
compiled_image_cache=image_cache,
|
|
404
|
-
run_base_dir=
|
|
412
|
+
run_base_dir=run_base_dir,
|
|
405
413
|
report=flyte.report.Report(name=action.name),
|
|
406
414
|
)
|
|
407
415
|
async with ctx.replace_task_context(tctx):
|
|
@@ -426,6 +434,18 @@ class _Runner:
|
|
|
426
434
|
else:
|
|
427
435
|
action = ActionID(name=self._name)
|
|
428
436
|
|
|
437
|
+
metadata_path = self._metadata_path
|
|
438
|
+
if metadata_path is None:
|
|
439
|
+
metadata_path = pathlib.Path("/") / "tmp" / "flyte" / "metadata" / action.name
|
|
440
|
+
else:
|
|
441
|
+
metadata_path = pathlib.Path(metadata_path) / action.name
|
|
442
|
+
output_path = metadata_path / "a0"
|
|
443
|
+
if self._raw_data_path is None:
|
|
444
|
+
path = pathlib.Path("/") / "tmp" / "flyte" / "raw_data" / action.name
|
|
445
|
+
raw_data_path = RawDataPath(path=str(path))
|
|
446
|
+
else:
|
|
447
|
+
raw_data_path = RawDataPath(path=self._raw_data_path)
|
|
448
|
+
|
|
429
449
|
ctx = internal_ctx()
|
|
430
450
|
tctx = TaskContext(
|
|
431
451
|
action=action,
|
|
@@ -434,10 +454,10 @@ class _Runner:
|
|
|
434
454
|
checkpoint_path=internal_ctx().raw_data.path,
|
|
435
455
|
),
|
|
436
456
|
code_bundle=None,
|
|
437
|
-
output_path=
|
|
438
|
-
run_base_dir=
|
|
457
|
+
output_path=str(output_path),
|
|
458
|
+
run_base_dir=str(metadata_path),
|
|
439
459
|
version="na",
|
|
440
|
-
raw_data_path=
|
|
460
|
+
raw_data_path=raw_data_path,
|
|
441
461
|
compiled_image_cache=None,
|
|
442
462
|
report=Report(name=action.name),
|
|
443
463
|
mode="local",
|
|
@@ -469,7 +489,7 @@ class _Runner:
|
|
|
469
489
|
|
|
470
490
|
@property
|
|
471
491
|
def url(self) -> str:
|
|
472
|
-
return
|
|
492
|
+
return str(metadata_path)
|
|
473
493
|
|
|
474
494
|
def wait(
|
|
475
495
|
self,
|
|
@@ -550,9 +570,10 @@ def with_runcontext(
|
|
|
550
570
|
env_vars: Dict[str, str] | None = None,
|
|
551
571
|
labels: Dict[str, str] | None = None,
|
|
552
572
|
annotations: Dict[str, str] | None = None,
|
|
553
|
-
interruptible: bool =
|
|
573
|
+
interruptible: bool | None = None,
|
|
554
574
|
log_level: int | None = None,
|
|
555
575
|
disable_run_cache: bool = False,
|
|
576
|
+
queue: Optional[str] = None,
|
|
556
577
|
) -> _Runner:
|
|
557
578
|
"""
|
|
558
579
|
Launch a new run with the given parameters as the context.
|
|
@@ -590,15 +611,20 @@ def with_runcontext(
|
|
|
590
611
|
:param env_vars: Optional Environment variables to set for the run
|
|
591
612
|
:param labels: Optional Labels to set for the run
|
|
592
613
|
:param annotations: Optional Annotations to set for the run
|
|
593
|
-
:param interruptible: Optional If true, the run can be
|
|
614
|
+
:param interruptible: Optional If true, the run can be scheduled on interruptible instances and false implies
|
|
615
|
+
that all tasks in the run should only be scheduled on non-interruptible instances. If not specified the
|
|
616
|
+
original setting on all tasks is retained.
|
|
594
617
|
:param log_level: Optional Log level to set for the run. If not provided, it will be set to the default log level
|
|
595
618
|
set using `flyte.init()`
|
|
596
619
|
:param disable_run_cache: Optional If true, the run cache will be disabled. This is useful for testing purposes.
|
|
620
|
+
:param queue: Optional The queue to use for the run. This is used to specify the cluster to use for the run.
|
|
597
621
|
|
|
598
622
|
:return: runner
|
|
599
623
|
"""
|
|
600
624
|
if mode == "hybrid" and not name and not run_base_dir:
|
|
601
625
|
raise ValueError("Run name and run base dir are required for hybrid mode")
|
|
626
|
+
if copy_style == "none" and not version:
|
|
627
|
+
raise ValueError("Version is required when copy_style is 'none'")
|
|
602
628
|
return _Runner(
|
|
603
629
|
force_mode=mode,
|
|
604
630
|
name=name,
|
|
@@ -619,6 +645,7 @@ def with_runcontext(
|
|
|
619
645
|
domain=domain,
|
|
620
646
|
log_level=log_level,
|
|
621
647
|
disable_run_cache=disable_run_cache,
|
|
648
|
+
queue=queue,
|
|
622
649
|
)
|
|
623
650
|
|
|
624
651
|
|
flyte/_task.py
CHANGED
|
@@ -15,6 +15,7 @@ from typing import (
|
|
|
15
15
|
Literal,
|
|
16
16
|
Optional,
|
|
17
17
|
ParamSpec,
|
|
18
|
+
Tuple,
|
|
18
19
|
TypeAlias,
|
|
19
20
|
TypeVar,
|
|
20
21
|
Union,
|
|
@@ -38,6 +39,8 @@ from .models import MAX_INLINE_IO_BYTES, NativeInterface, SerializationContext
|
|
|
38
39
|
if TYPE_CHECKING:
|
|
39
40
|
from flyteidl.core.tasks_pb2 import DataLoadingConfig
|
|
40
41
|
|
|
42
|
+
from flyte.trigger import Trigger
|
|
43
|
+
|
|
41
44
|
from ._task_environment import TaskEnvironment
|
|
42
45
|
|
|
43
46
|
P = ParamSpec("P") # capture the function's parameters
|
|
@@ -69,8 +72,8 @@ class TaskTemplate(Generic[P, R]):
|
|
|
69
72
|
version with flyte installed
|
|
70
73
|
:param resources: Optional The resources to use for the task
|
|
71
74
|
:param cache: Optional The cache policy for the task, defaults to auto, which will cache the results of the task.
|
|
72
|
-
:param
|
|
73
|
-
will not be scheduled on
|
|
75
|
+
:param interruptible: Optional The interruptible policy for the task, defaults to False, which means the task
|
|
76
|
+
will not be scheduled on interruptible nodes. If set to True, the task will be scheduled on interruptible nodes,
|
|
74
77
|
and the code should handle interruptions and resumptions.
|
|
75
78
|
:param retries: Optional The number of retries for the task, defaults to 0, which means no retries.
|
|
76
79
|
:param reusable: Optional The reusability policy for the task, defaults to None, which means the task environment
|
|
@@ -81,6 +84,9 @@ class TaskTemplate(Generic[P, R]):
|
|
|
81
84
|
:param timeout: Optional The timeout for the task.
|
|
82
85
|
:param max_inline_io_bytes: Maximum allowed size (in bytes) for all inputs and outputs passed directly to the task
|
|
83
86
|
(e.g., primitives, strings, dicts). Does not apply to files, directories, or dataframes.
|
|
87
|
+
:param pod_template: Optional The pod template to use for the task.
|
|
88
|
+
:param report: Optional Whether to report the task execution to the Flyte console, defaults to False.
|
|
89
|
+
:param queue: Optional The queue to use for the task. If not provided, the default queue will be used.
|
|
84
90
|
"""
|
|
85
91
|
|
|
86
92
|
name: str
|
|
@@ -90,8 +96,8 @@ class TaskTemplate(Generic[P, R]):
|
|
|
90
96
|
task_type_version: int = 0
|
|
91
97
|
image: Union[str, Image, Literal["auto"]] = "auto"
|
|
92
98
|
resources: Optional[Resources] = None
|
|
93
|
-
cache: CacheRequest = "
|
|
94
|
-
|
|
99
|
+
cache: CacheRequest = "disable"
|
|
100
|
+
interruptible: bool = False
|
|
95
101
|
retries: Union[int, RetryStrategy] = 0
|
|
96
102
|
reusable: Union[ReusePolicy, None] = None
|
|
97
103
|
docs: Optional[Documentation] = None
|
|
@@ -100,10 +106,12 @@ class TaskTemplate(Generic[P, R]):
|
|
|
100
106
|
timeout: Optional[TimeoutType] = None
|
|
101
107
|
pod_template: Optional[Union[str, PodTemplate]] = None
|
|
102
108
|
report: bool = False
|
|
109
|
+
queue: Optional[str] = None
|
|
103
110
|
|
|
104
111
|
parent_env: Optional[weakref.ReferenceType[TaskEnvironment]] = None
|
|
105
112
|
ref: bool = field(default=False, init=False, repr=False, compare=False)
|
|
106
113
|
max_inline_io_bytes: int = MAX_INLINE_IO_BYTES
|
|
114
|
+
triggers: Tuple[Trigger, ...] = field(default_factory=tuple)
|
|
107
115
|
|
|
108
116
|
# Only used in python 3.10 and 3.11, where we cannot use markcoroutinefunction
|
|
109
117
|
_call_as_synchronous: bool = False
|
|
@@ -327,11 +335,30 @@ class TaskTemplate(Generic[P, R]):
|
|
|
327
335
|
secrets: Optional[SecretRequest] = None,
|
|
328
336
|
max_inline_io_bytes: int | None = None,
|
|
329
337
|
pod_template: Optional[Union[str, PodTemplate]] = None,
|
|
338
|
+
queue: Optional[str] = None,
|
|
339
|
+
interruptible: Optional[bool] = None,
|
|
330
340
|
**kwargs: Any,
|
|
331
341
|
) -> TaskTemplate:
|
|
332
342
|
"""
|
|
333
343
|
Override various parameters of the task template. This allows for dynamic configuration of the task
|
|
334
344
|
when it is called, such as changing the image, resources, cache policy, etc.
|
|
345
|
+
|
|
346
|
+
:param short_name: Optional override for the short name of the task.
|
|
347
|
+
:param resources: Optional override for the resources to use for the task.
|
|
348
|
+
:param cache: Optional override for the cache policy for the task.
|
|
349
|
+
:param retries: Optional override for the number of retries for the task.
|
|
350
|
+
:param timeout: Optional override for the timeout for the task.
|
|
351
|
+
:param reusable: Optional override for the reusability policy for the task.
|
|
352
|
+
:param env_vars: Optional override for the environment variables to set for the task.
|
|
353
|
+
:param secrets: Optional override for the secrets that will be injected into the task at runtime.
|
|
354
|
+
:param max_inline_io_bytes: Optional override for the maximum allowed size (in bytes) for all inputs and outputs
|
|
355
|
+
passed directly to the task.
|
|
356
|
+
:param pod_template: Optional override for the pod template to use for the task.
|
|
357
|
+
:param queue: Optional override for the queue to use for the task.
|
|
358
|
+
:param kwargs: Additional keyword arguments for further overrides. Some fields like name, image, docs,
|
|
359
|
+
and interface cannot be overridden.
|
|
360
|
+
|
|
361
|
+
:return: A new TaskTemplate instance with the overridden parameters.
|
|
335
362
|
"""
|
|
336
363
|
cache = cache or self.cache
|
|
337
364
|
retries = retries or self.retries
|
|
@@ -366,6 +393,8 @@ class TaskTemplate(Generic[P, R]):
|
|
|
366
393
|
env_vars = env_vars or self.env_vars
|
|
367
394
|
secrets = secrets or self.secrets
|
|
368
395
|
|
|
396
|
+
interruptible = interruptible if interruptible is not None else self.interruptible
|
|
397
|
+
|
|
369
398
|
for k, v in kwargs.items():
|
|
370
399
|
if k == "name":
|
|
371
400
|
raise ValueError("Name cannot be overridden")
|
|
@@ -388,6 +417,8 @@ class TaskTemplate(Generic[P, R]):
|
|
|
388
417
|
secrets=secrets,
|
|
389
418
|
max_inline_io_bytes=max_inline_io_bytes,
|
|
390
419
|
pod_template=pod_template,
|
|
420
|
+
interruptible=interruptible,
|
|
421
|
+
queue=queue or self.queue,
|
|
391
422
|
**kwargs,
|
|
392
423
|
)
|
|
393
424
|
|
flyte/_task_environment.py
CHANGED
|
@@ -12,6 +12,7 @@ from typing import (
|
|
|
12
12
|
List,
|
|
13
13
|
Literal,
|
|
14
14
|
Optional,
|
|
15
|
+
Tuple,
|
|
15
16
|
Union,
|
|
16
17
|
cast,
|
|
17
18
|
)
|
|
@@ -22,16 +23,16 @@ from ._cache import Cache, CacheRequest
|
|
|
22
23
|
from ._doc import Documentation
|
|
23
24
|
from ._environment import Environment
|
|
24
25
|
from ._image import Image
|
|
26
|
+
from ._pod import PodTemplate
|
|
25
27
|
from ._resources import Resources
|
|
26
28
|
from ._retry import RetryStrategy
|
|
27
29
|
from ._reusable_environment import ReusePolicy
|
|
28
30
|
from ._secret import SecretRequest
|
|
29
31
|
from ._task import AsyncFunctionTaskTemplate, TaskTemplate
|
|
32
|
+
from ._trigger import Trigger
|
|
30
33
|
from .models import MAX_INLINE_IO_BYTES, NativeInterface
|
|
31
34
|
|
|
32
35
|
if TYPE_CHECKING:
|
|
33
|
-
from kubernetes.client import V1PodTemplate
|
|
34
|
-
|
|
35
36
|
from ._task import FunctionTypes, P, R
|
|
36
37
|
|
|
37
38
|
|
|
@@ -60,13 +61,18 @@ class TaskEnvironment(Environment):
|
|
|
60
61
|
that depend on each other.
|
|
61
62
|
:param cache: Cache policy for the environment.
|
|
62
63
|
:param reusable: Reuse policy for the environment, if set, a python process may be reused for multiple tasks.
|
|
64
|
+
:param plugin_config: Optional plugin configuration for custom task types.
|
|
65
|
+
If set, all tasks in this environment will use the specified plugin configuration.
|
|
66
|
+
:param queue: Optional queue name to use for tasks in this environment.
|
|
67
|
+
If not set, the default queue will be used.
|
|
68
|
+
:param pod_template: Optional pod template to use for tasks in this environment.
|
|
69
|
+
If not set, the default pod template will be used.
|
|
63
70
|
"""
|
|
64
71
|
|
|
65
72
|
cache: CacheRequest = "disable"
|
|
66
73
|
reusable: ReusePolicy | None = None
|
|
67
74
|
plugin_config: Optional[Any] = None
|
|
68
|
-
|
|
69
|
-
# TODO also we could add list of files that are used by this environment
|
|
75
|
+
queue: Optional[str] = None
|
|
70
76
|
|
|
71
77
|
_tasks: Dict[str, TaskTemplate] = field(default_factory=dict, init=False)
|
|
72
78
|
|
|
@@ -87,6 +93,8 @@ class TaskEnvironment(Environment):
|
|
|
87
93
|
env_vars: Optional[Dict[str, str]] = None,
|
|
88
94
|
secrets: Optional[SecretRequest] = None,
|
|
89
95
|
depends_on: Optional[List[Environment]] = None,
|
|
96
|
+
description: Optional[str] = None,
|
|
97
|
+
interruptible: Optional[bool] = None,
|
|
90
98
|
**kwargs: Any,
|
|
91
99
|
) -> TaskEnvironment:
|
|
92
100
|
"""
|
|
@@ -102,6 +110,11 @@ class TaskEnvironment(Environment):
|
|
|
102
110
|
:param depends_on: The environment dependencies to hint, so when you deploy the environment,
|
|
103
111
|
the dependencies are also deployed. This is useful when you have a set of environments
|
|
104
112
|
that depend on each other.
|
|
113
|
+
:param queue: The queue name to use for tasks in this environment.
|
|
114
|
+
:param pod_template: The pod template to use for tasks in this environment.
|
|
115
|
+
:param description: The description of the environment.
|
|
116
|
+
:param interruptible: Whether the environment is interruptible and can be scheduled on spot/preemptible
|
|
117
|
+
instances.
|
|
105
118
|
:param kwargs: Additional parameters to override the environment (e.g., cache, reusable, plugin_config).
|
|
106
119
|
"""
|
|
107
120
|
cache = kwargs.pop("cache", None)
|
|
@@ -131,21 +144,28 @@ class TaskEnvironment(Environment):
|
|
|
131
144
|
kwargs["secrets"] = secrets
|
|
132
145
|
if depends_on is not None:
|
|
133
146
|
kwargs["depends_on"] = depends_on
|
|
147
|
+
if description is not None:
|
|
148
|
+
kwargs["description"] = description
|
|
149
|
+
if interruptible is not None:
|
|
150
|
+
kwargs["interruptible"] = interruptible
|
|
134
151
|
return replace(self, **kwargs)
|
|
135
152
|
|
|
136
153
|
def task(
|
|
137
154
|
self,
|
|
138
|
-
_func=None,
|
|
155
|
+
_func: Callable[P, R] | None = None,
|
|
139
156
|
*,
|
|
140
157
|
short_name: Optional[str] = None,
|
|
141
158
|
cache: CacheRequest | None = None,
|
|
142
159
|
retries: Union[int, RetryStrategy] = 0,
|
|
143
160
|
timeout: Union[timedelta, int] = 0,
|
|
144
161
|
docs: Optional[Documentation] = None,
|
|
145
|
-
pod_template: Optional[Union[str,
|
|
162
|
+
pod_template: Optional[Union[str, PodTemplate]] = None,
|
|
146
163
|
report: bool = False,
|
|
164
|
+
interruptible: bool | None = None,
|
|
147
165
|
max_inline_io_bytes: int = MAX_INLINE_IO_BYTES,
|
|
148
|
-
|
|
166
|
+
queue: Optional[str] = None,
|
|
167
|
+
triggers: Tuple[Trigger, ...] | Trigger = (),
|
|
168
|
+
) -> Union[AsyncFunctionTaskTemplate[P, R], Callable[P, R]]:
|
|
149
169
|
"""
|
|
150
170
|
Decorate a function to be a task.
|
|
151
171
|
|
|
@@ -162,6 +182,12 @@ class TaskEnvironment(Environment):
|
|
|
162
182
|
:param report: Optional Whether to generate the html report for the task, defaults to False.
|
|
163
183
|
:param max_inline_io_bytes: Maximum allowed size (in bytes) for all inputs and outputs passed directly to the
|
|
164
184
|
task (e.g., primitives, strings, dicts). Does not apply to files, directories, or dataframes.
|
|
185
|
+
:param triggers: Optional A tuple of triggers to associate with the task. This allows the task to be run on a
|
|
186
|
+
schedule or in response to events. Triggers can be defined using the `flyte.trigger` module.
|
|
187
|
+
:param interruptible: Optional Whether the task is interruptible, defaults to environment setting.
|
|
188
|
+
:param queue: Optional queue name to use for this task. If not set, the environment's queue will be used.
|
|
189
|
+
|
|
190
|
+
:return: A TaskTemplate that can be used to deploy the task.
|
|
165
191
|
"""
|
|
166
192
|
from ._task import P, R
|
|
167
193
|
|
|
@@ -214,6 +240,9 @@ class TaskEnvironment(Environment):
|
|
|
214
240
|
short_name=short,
|
|
215
241
|
plugin_config=self.plugin_config,
|
|
216
242
|
max_inline_io_bytes=max_inline_io_bytes,
|
|
243
|
+
queue=queue or self.queue,
|
|
244
|
+
interruptible=interruptible if interruptible is not None else self.interruptible,
|
|
245
|
+
triggers=triggers if isinstance(triggers, tuple) else (triggers,),
|
|
217
246
|
)
|
|
218
247
|
self._tasks[task_name] = tmpl
|
|
219
248
|
return tmpl
|
|
@@ -229,16 +258,32 @@ class TaskEnvironment(Environment):
|
|
|
229
258
|
"""
|
|
230
259
|
return self._tasks
|
|
231
260
|
|
|
232
|
-
|
|
261
|
+
@classmethod
|
|
262
|
+
def from_task(cls, name: str, *tasks: TaskTemplate) -> TaskEnvironment:
|
|
233
263
|
"""
|
|
234
|
-
|
|
264
|
+
Create a TaskEnvironment from a list of tasks. All tasks should have the same image or no Image defined.
|
|
265
|
+
Similarity of Image is determined by the python reference, not by value.
|
|
266
|
+
|
|
267
|
+
If images are different, an error is raised. If no image is defined, the image is set to "auto".
|
|
235
268
|
|
|
236
|
-
|
|
269
|
+
For any other tasks that need to be use these tasks, the returned environment can be used in the `depends_on`
|
|
270
|
+
attribute of the other TaskEnvironment.
|
|
271
|
+
|
|
272
|
+
:param name: The name of the environment.
|
|
273
|
+
:param tasks: The list of tasks to create the environment from.
|
|
237
274
|
|
|
238
|
-
:
|
|
275
|
+
:raises ValueError: If tasks are assigned to multiple environments or have different images.
|
|
276
|
+
:return: The created TaskEnvironment.
|
|
239
277
|
"""
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
278
|
+
envs = [t.parent_env() for t in tasks if t.parent_env and t.parent_env() is not None]
|
|
279
|
+
if envs:
|
|
280
|
+
raise ValueError("Tasks cannot assigned to multiple environments.")
|
|
281
|
+
images = {t.image for t in tasks}
|
|
282
|
+
if len(images) > 1:
|
|
283
|
+
raise ValueError("Tasks must have the same image to be in the same environment.")
|
|
284
|
+
image: Union[str, Image] = images.pop() if images else "auto"
|
|
285
|
+
env = cls(name, image=image)
|
|
286
|
+
for t in tasks:
|
|
287
|
+
env._tasks[t.name] = t
|
|
288
|
+
t.parent_env = weakref.ref(env)
|
|
289
|
+
return env
|