flyte 2.0.0b1__py3-none-any.whl → 2.0.0b3__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.

@@ -41,7 +41,9 @@ class Controller(Protocol):
41
41
  """
42
42
  ...
43
43
 
44
- async def submit_task_ref(self, _task: task_definition_pb2.TaskDetails, *args, **kwargs) -> Any:
44
+ async def submit_task_ref(
45
+ self, _task: task_definition_pb2.TaskDetails, max_inline_io_bytes: int, *args, **kwargs
46
+ ) -> Any:
45
47
  """
46
48
  Submit a task reference to the controller asynchronously and wait for the result. This is async and will block
47
49
  the current coroutine until the result is available.
@@ -192,5 +192,7 @@ class LocalController:
192
192
  assert info.start_time
193
193
  assert info.end_time
194
194
 
195
- async def submit_task_ref(self, _task: task_definition_pb2.TaskDetails, *args, **kwargs) -> Any:
195
+ async def submit_task_ref(
196
+ self, _task: task_definition_pb2.TaskDetails, max_inline_io_bytes: int, *args, **kwargs
197
+ ) -> Any:
196
198
  raise flyte.errors.ReferenceTaskError("Reference tasks cannot be executed locally, only remotely.")
@@ -7,7 +7,7 @@ import threading
7
7
  from collections import defaultdict
8
8
  from collections.abc import Callable
9
9
  from pathlib import Path
10
- from typing import Any, AsyncIterable, Awaitable, DefaultDict, Tuple, TypeVar
10
+ from typing import Any, Awaitable, DefaultDict, Tuple, TypeVar
11
11
 
12
12
  import flyte
13
13
  import flyte.errors
@@ -27,22 +27,30 @@ from flyte._protos.common import identifier_pb2
27
27
  from flyte._protos.workflow import run_definition_pb2, task_definition_pb2
28
28
  from flyte._task import TaskTemplate
29
29
  from flyte._utils.helpers import _selector_policy
30
- from flyte.models import ActionID, NativeInterface, SerializationContext
30
+ from flyte.models import MAX_INLINE_IO_BYTES, ActionID, NativeInterface, SerializationContext
31
31
 
32
32
  R = TypeVar("R")
33
33
 
34
+ MAX_TRACE_BYTES = MAX_INLINE_IO_BYTES
34
35
 
35
- async def upload_inputs_with_retry(serialized_inputs: AsyncIterable[bytes] | bytes, inputs_uri: str) -> None:
36
+
37
+ async def upload_inputs_with_retry(serialized_inputs: bytes, inputs_uri: str, max_bytes: int) -> None:
36
38
  """
37
39
  Upload inputs to the specified URI with error handling.
38
40
 
39
41
  Args:
40
42
  serialized_inputs: The serialized inputs to upload
41
43
  inputs_uri: The destination URI
44
+ max_bytes: Maximum number of bytes to read from the input stream
42
45
 
43
46
  Raises:
44
47
  RuntimeSystemError: If the upload fails
45
48
  """
49
+ if len(serialized_inputs) > max_bytes:
50
+ raise flyte.errors.InlineIOMaxBytesBreached(
51
+ f"Inputs exceed max_bytes limit of {max_bytes / 1024 / 1024} MB,"
52
+ f" actual size: {len(serialized_inputs) / 1024 / 1024} MB"
53
+ )
46
54
  try:
47
55
  # TODO Add retry decorator to this
48
56
  await storage.put_stream(serialized_inputs, to_path=inputs_uri)
@@ -80,19 +88,20 @@ async def handle_action_failure(action: Action, task_name: str) -> Exception:
80
88
  return exc
81
89
 
82
90
 
83
- async def load_and_convert_outputs(iface: NativeInterface, realized_outputs_uri: str) -> Any:
91
+ async def load_and_convert_outputs(iface: NativeInterface, realized_outputs_uri: str, max_bytes: int) -> Any:
84
92
  """
85
93
  Load outputs from the given URI and convert them to native format.
86
94
 
87
95
  Args:
88
96
  iface: The Native interface
89
97
  realized_outputs_uri: The URI where outputs are stored
98
+ max_bytes: Maximum number of bytes to read from the output file
90
99
 
91
100
  Returns:
92
101
  The converted native outputs
93
102
  """
94
103
  outputs_file_path = io.outputs_path(realized_outputs_uri)
95
- outputs = await io.load_outputs(outputs_file_path)
104
+ outputs = await io.load_outputs(outputs_file_path, max_bytes=max_bytes)
96
105
  return await convert.convert_outputs_to_native(iface, outputs)
97
106
 
98
107
 
@@ -191,7 +200,7 @@ class RemoteController(Controller):
191
200
 
192
201
  serialized_inputs = inputs.proto_inputs.SerializeToString(deterministic=True)
193
202
  inputs_uri = io.inputs_path(sub_action_output_path)
194
- await upload_inputs_with_retry(serialized_inputs, inputs_uri)
203
+ await upload_inputs_with_retry(serialized_inputs, inputs_uri, max_bytes=_task.max_inline_io_bytes)
195
204
 
196
205
  md = task_spec.task_template.metadata
197
206
  ignored_input_vars = []
@@ -254,7 +263,9 @@ class RemoteController(Controller):
254
263
  "RuntimeError",
255
264
  f"Task {n.action_id.name} did not return an output path, but the task has outputs defined.",
256
265
  )
257
- return await load_and_convert_outputs(_task.native_interface, n.realized_outputs_uri)
266
+ return await load_and_convert_outputs(
267
+ _task.native_interface, n.realized_outputs_uri, max_bytes=_task.max_inline_io_bytes
268
+ )
258
269
  return None
259
270
 
260
271
  async def submit(self, _task: TaskTemplate, *args, **kwargs) -> Any:
@@ -357,7 +368,7 @@ class RemoteController(Controller):
357
368
  )
358
369
 
359
370
  inputs_uri = io.inputs_path(sub_action_output_path)
360
- await upload_inputs_with_retry(serialized_inputs, inputs_uri)
371
+ await upload_inputs_with_retry(serialized_inputs, inputs_uri, max_bytes=MAX_TRACE_BYTES)
361
372
  # Clear to free memory
362
373
  serialized_inputs = None # type: ignore
363
374
 
@@ -388,7 +399,7 @@ class RemoteController(Controller):
388
399
  logger.warning(f"Action {prev_action.action_id.name} failed, but no error was found, re-running trace!")
389
400
  elif prev_action.realized_outputs_uri is not None:
390
401
  outputs_file_path = io.outputs_path(prev_action.realized_outputs_uri)
391
- o = await io.load_outputs(outputs_file_path)
402
+ o = await io.load_outputs(outputs_file_path, max_bytes=MAX_TRACE_BYTES)
392
403
  outputs = await convert.convert_outputs_to_native(_interface, o)
393
404
  return (
394
405
  TraceInfo(func_name, sub_action_id, _interface, inputs_uri, output=outputs),
@@ -421,7 +432,7 @@ class RemoteController(Controller):
421
432
  f"Uploading outputs for {info.name} Outputs file path: {outputs_file_path}",
422
433
  flush=True,
423
434
  )
424
- await io.upload_outputs(outputs, sub_run_output_path)
435
+ await io.upload_outputs(outputs, sub_run_output_path, max_bytes=MAX_TRACE_BYTES)
425
436
  elif info.error:
426
437
  err = convert.convert_from_native_to_error(info.error)
427
438
  await io.upload_error(err.err, sub_run_output_path)
@@ -461,7 +472,9 @@ class RemoteController(Controller):
461
472
  # If the action is cancelled, we need to cancel the action on the server as well
462
473
  raise
463
474
 
464
- async def submit_task_ref(self, _task: task_definition_pb2.TaskDetails, *args, **kwargs) -> Any:
475
+ async def submit_task_ref(
476
+ self, _task: task_definition_pb2.TaskDetails, max_inline_io_bytes: int, *args, **kwargs
477
+ ) -> Any:
465
478
  ctx = internal_ctx()
466
479
  tctx = ctx.data.task_context
467
480
  if tctx is None:
@@ -482,7 +495,7 @@ class RemoteController(Controller):
482
495
 
483
496
  serialized_inputs = inputs.proto_inputs.SerializeToString(deterministic=True)
484
497
  inputs_uri = io.inputs_path(sub_action_output_path)
485
- await upload_inputs_with_retry(serialized_inputs, inputs_uri)
498
+ await upload_inputs_with_retry(serialized_inputs, inputs_uri, max_inline_io_bytes)
486
499
  # cache key - task name, task signature, inputs, cache version
487
500
  cache_key = None
488
501
  md = _task.spec.task_template.metadata
@@ -545,5 +558,5 @@ class RemoteController(Controller):
545
558
  "RuntimeError",
546
559
  f"Task {n.action_id.name} did not return an output path, but the task has outputs defined.",
547
560
  )
548
- return await load_and_convert_outputs(native_interface, n.realized_outputs_uri)
561
+ return await load_and_convert_outputs(native_interface, n.realized_outputs_uri, max_inline_io_bytes)
549
562
  return None
@@ -5,14 +5,11 @@ It uses the storage module to handle the actual uploading and downloading of fil
5
5
  TODO: Convert to use streaming apis
6
6
  """
7
7
 
8
- import logging
9
-
10
8
  from flyteidl.core import errors_pb2, execution_pb2
11
9
 
12
10
  import flyte.storage as storage
13
11
  from flyte._protos.workflow import run_definition_pb2
14
12
 
15
- from ..._logging import log
16
13
  from .convert import Inputs, Outputs, _clean_error_code
17
14
 
18
15
  # ------------------------------- CONSTANTS ------------------------------- #
@@ -55,11 +52,19 @@ async def upload_inputs(inputs: Inputs, input_path: str):
55
52
  await storage.put_stream(data_iterable=inputs.proto_inputs.SerializeToString(), to_path=input_path)
56
53
 
57
54
 
58
- async def upload_outputs(outputs: Outputs, output_path: str):
55
+ async def upload_outputs(outputs: Outputs, output_path: str, max_bytes: int = -1):
59
56
  """
60
57
  :param outputs: Outputs
61
58
  :param output_path: The path to upload the output file.
59
+ :param max_bytes: Maximum number of bytes to write to the output file. Default is -1, which means no limit.
62
60
  """
61
+ if max_bytes != -1 and outputs.proto_outputs.ByteSize() > max_bytes:
62
+ import flyte.errors
63
+
64
+ raise flyte.errors.InlineIOMaxBytesBreached(
65
+ f"Output file at {output_path} exceeds max_bytes limit of {max_bytes},"
66
+ f" size: {outputs.proto_outputs.ByteSize()}"
67
+ )
63
68
  output_uri = outputs_path(output_path)
64
69
  await storage.put_stream(data_iterable=outputs.proto_outputs.SerializeToString(), to_path=output_uri)
65
70
 
@@ -85,25 +90,59 @@ async def upload_error(err: execution_pb2.ExecutionError, output_prefix: str):
85
90
 
86
91
 
87
92
  # ------------------------------- DOWNLOAD Methods ------------------------------- #
88
- @log(level=logging.INFO)
89
- async def load_inputs(path: str) -> Inputs:
93
+ async def load_inputs(path: str, max_bytes: int = -1) -> Inputs:
90
94
  """
91
95
  :param path: Input file to be downloaded
96
+ :param max_bytes: Maximum number of bytes to read from the input file. Default is -1, which means no limit.
92
97
  :return: Inputs object
93
98
  """
94
99
  lm = run_definition_pb2.Inputs()
95
- proto_str = b"".join([c async for c in storage.get_stream(path=path)])
100
+
101
+ if max_bytes == -1:
102
+ proto_str = b"".join([c async for c in storage.get_stream(path=path)])
103
+ else:
104
+ proto_bytes = []
105
+ total_bytes = 0
106
+ async for chunk in storage.get_stream(path=path):
107
+ if total_bytes + len(chunk) > max_bytes:
108
+ import flyte.errors
109
+
110
+ raise flyte.errors.InlineIOMaxBytesBreached(
111
+ f"Input file at {path} exceeds max_bytes limit of {max_bytes}"
112
+ )
113
+ proto_bytes.append(chunk)
114
+ total_bytes += len(chunk)
115
+ proto_str = b"".join(proto_bytes)
116
+
96
117
  lm.ParseFromString(proto_str)
97
118
  return Inputs(proto_inputs=lm)
98
119
 
99
120
 
100
- async def load_outputs(path: str) -> Outputs:
121
+ async def load_outputs(path: str, max_bytes: int = -1) -> Outputs:
101
122
  """
102
123
  :param path: output file to be loaded
124
+ :param max_bytes: Maximum number of bytes to read from the output file.
125
+ If -1, reads the entire file.
103
126
  :return: Outputs object
104
127
  """
105
128
  lm = run_definition_pb2.Outputs()
106
- proto_str = b"".join([c async for c in storage.get_stream(path=path)])
129
+
130
+ if max_bytes == -1:
131
+ proto_str = b"".join([c async for c in storage.get_stream(path=path)])
132
+ else:
133
+ proto_bytes = []
134
+ total_bytes = 0
135
+ async for chunk in storage.get_stream(path=path):
136
+ if total_bytes + len(chunk) > max_bytes:
137
+ import flyte.errors
138
+
139
+ raise flyte.errors.InlineIOMaxBytesBreached(
140
+ f"Output file at {path} exceeds max_bytes limit of {max_bytes}"
141
+ )
142
+ proto_bytes.append(chunk)
143
+ total_bytes += len(chunk)
144
+ proto_str = b"".join(proto_bytes)
145
+
107
146
  lm.ParseFromString(proto_str)
108
147
  return Outputs(proto_outputs=lm)
109
148
 
@@ -20,7 +20,7 @@ from flyte._protos.workflow import run_definition_pb2 as workflow_dot_run__defin
20
20
  from flyte._protos.workflow import task_definition_pb2 as workflow_dot_task__definition__pb2
21
21
 
22
22
 
23
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cworkflow/queue_service.proto\x12\x11\x63loudidl.workflow\x1a\x17\x63ommon/identifier.proto\x1a\x19\x66lyteidl/core/types.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x17validate/validate.proto\x1a\x1dworkflow/run_definition.proto\x1a\x1eworkflow/task_definition.proto\"\x7f\n\x10WorkerIdentifier\x12+\n\x0corganization\x18\x01 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x0corganization\x12!\n\x07\x63luster\x18\x02 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x07\x63luster\x12\x1b\n\x04name\x18\x03 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x04name\"\xbf\x04\n\x14\x45nqueueActionRequest\x12H\n\taction_id\x18\x01 \x01(\x0b\x32!.cloudidl.common.ActionIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08\x61\x63tionId\x12\x31\n\x12parent_action_name\x18\x02 \x01(\tH\x01R\x10parentActionName\x88\x01\x01\x12\x35\n\x08run_spec\x18\x03 \x01(\x0b\x32\x1a.cloudidl.workflow.RunSpecR\x07runSpec\x12$\n\tinput_uri\x18\x06 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x08inputUri\x12/\n\x0frun_output_base\x18\x07 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\rrunOutputBase\x12\x14\n\x05group\x18\x08 \x01(\tR\x05group\x12\x18\n\x07subject\x18\t \x01(\tR\x07subject\x12=\n\x04task\x18\n \x01(\x0b\x32\x1d.cloudidl.workflow.TaskActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x04task\x12@\n\x05trace\x18\x0b \x01(\x0b\x32\x1e.cloudidl.workflow.TraceActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x05trace\x12L\n\tcondition\x18\x0c \x01(\x0b\x32\".cloudidl.workflow.ConditionActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\tconditionB\x06\n\x04specB\x15\n\x13_parent_action_name\"\xb5\x01\n\nTaskAction\x12\x31\n\x02id\x18\x01 \x01(\x0b\x32!.cloudidl.workflow.TaskIdentifierR\x02id\x12\x39\n\x04spec\x18\x02 \x01(\x0b\x32\x1b.cloudidl.workflow.TaskSpecB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x04spec\x12\x39\n\tcache_key\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValueR\x08\x63\x61\x63heKey\"\xd8\x02\n\x0bTraceAction\x12\x1b\n\x04name\x18\x01 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x04name\x12.\n\x05phase\x18\x02 \x01(\x0e\x32\x18.cloudidl.workflow.PhaseR\x05phase\x12\x39\n\nstart_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tstartTime\x12:\n\x08\x65nd_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00R\x07\x65ndTime\x88\x01\x01\x12=\n\x07outputs\x18\x05 \x01(\x0b\x32#.cloudidl.workflow.OutputReferencesR\x07outputs\x12\x39\n\x04spec\x18\x06 \x01(\x0b\x32\x1b.cloudidl.workflow.TaskSpecB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x04specB\x0b\n\t_end_time\"\x8a\x02\n\x0f\x43onditionAction\x12\x1b\n\x04name\x18\x01 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x04name\x12 \n\x06run_id\x18\x02 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01H\x00R\x05runId\x12&\n\taction_id\x18\x03 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01H\x00R\x08\x61\x63tionId\x12\x18\n\x06global\x18\x04 \x01(\x08H\x00R\x06global\x12.\n\x04type\x18\x06 \x01(\x0b\x32\x1a.flyteidl.core.LiteralTypeR\x04type\x12\x16\n\x06prompt\x18\x07 \x01(\tR\x06prompt\x12 \n\x0b\x64\x65scription\x18\x08 \x01(\tR\x0b\x64\x65scriptionB\x0c\n\x05scope\x12\x03\xf8\x42\x01\"\x17\n\x15\x45nqueueActionResponse\"X\n\x15\x41\x62ortQueuedRunRequest\x12?\n\x06run_id\x18\x01 \x01(\x0b\x32\x1e.cloudidl.common.RunIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x05runId\"\x18\n\x16\x41\x62ortQueuedRunResponse\"\x80\x03\n\x10HeartbeatRequest\x12J\n\tworker_id\x18\x01 \x01(\x0b\x32#.cloudidl.workflow.WorkerIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08workerId\x12M\n\x11\x61\x63tive_action_ids\x18\x02 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x0f\x61\x63tiveActionIds\x12Q\n\x13terminal_action_ids\x18\x03 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x11terminalActionIds\x12O\n\x12\x61\x62orted_action_ids\x18\x04 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x10\x61\x62ortedActionIds\x12-\n\x12\x61vailable_capacity\x18\x05 \x01(\x05R\x11\x61vailableCapacity\"\xe2\x01\n\x11HeartbeatResponse\x12\x37\n\nnew_leases\x18\x01 \x03(\x0b\x32\x18.cloudidl.workflow.LeaseR\tnewLeases\x12?\n\x0e\x61\x62orted_leases\x18\x02 \x03(\x0b\x32\x18.cloudidl.workflow.LeaseR\rabortedLeases\x12S\n\x14\x66inalized_action_ids\x18\x03 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x12\x66inalizedActionIds\"a\n\x13StreamLeasesRequest\x12J\n\tworker_id\x18\x01 \x01(\x0b\x32#.cloudidl.workflow.WorkerIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08workerId\"H\n\x14StreamLeasesResponse\x12\x30\n\x06leases\x18\x01 \x03(\x0b\x32\x18.cloudidl.workflow.LeaseR\x06leases\"\xc9\x04\n\x05Lease\x12H\n\taction_id\x18\x01 \x01(\x0b\x32!.cloudidl.common.ActionIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08\x61\x63tionId\x12\x31\n\x12parent_action_name\x18\x02 \x01(\tH\x01R\x10parentActionName\x88\x01\x01\x12\x35\n\x08run_spec\x18\x03 \x01(\x0b\x32\x1a.cloudidl.workflow.RunSpecR\x07runSpec\x12$\n\tinput_uri\x18\x04 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x08inputUri\x12/\n\x0frun_output_base\x18\x05 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\rrunOutputBase\x12=\n\x04task\x18\x06 \x01(\x0b\x32\x1d.cloudidl.workflow.TaskActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x04task\x12L\n\tcondition\x18\x07 \x01(\x0b\x32\".cloudidl.workflow.ConditionActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\tcondition\x12@\n\x05trace\x18\n \x01(\x0b\x32\x1e.cloudidl.workflow.TraceActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x05trace\x12\x14\n\x05group\x18\x08 \x01(\tR\x05group\x12\x18\n\x07subject\x18\t \x01(\tR\x07subject\x12\x12\n\x04host\x18\x0b \x01(\tR\x04hostB\x0b\n\x04spec\x12\x03\xf8\x42\x01\x42\x15\n\x13_parent_action_name2\xa0\x03\n\x0cQueueService\x12\x64\n\rEnqueueAction\x12\'.cloudidl.workflow.EnqueueActionRequest\x1a(.cloudidl.workflow.EnqueueActionResponse\"\x00\x12g\n\x0e\x41\x62ortQueuedRun\x12(.cloudidl.workflow.AbortQueuedRunRequest\x1a).cloudidl.workflow.AbortQueuedRunResponse\"\x00\x12\\\n\tHeartbeat\x12#.cloudidl.workflow.HeartbeatRequest\x1a$.cloudidl.workflow.HeartbeatResponse\"\x00(\x01\x30\x01\x12\x63\n\x0cStreamLeases\x12&.cloudidl.workflow.StreamLeasesRequest\x1a\'.cloudidl.workflow.StreamLeasesResponse\"\x00\x30\x01\x42\xbe\x01\n\x15\x63om.cloudidl.workflowB\x11QueueServiceProtoH\x02P\x01Z+github.com/unionai/cloud/gen/pb-go/workflow\xa2\x02\x03\x43WX\xaa\x02\x11\x43loudidl.Workflow\xca\x02\x11\x43loudidl\\Workflow\xe2\x02\x1d\x43loudidl\\Workflow\\GPBMetadata\xea\x02\x12\x43loudidl::Workflowb\x06proto3')
23
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cworkflow/queue_service.proto\x12\x11\x63loudidl.workflow\x1a\x17\x63ommon/identifier.proto\x1a\x19\x66lyteidl/core/types.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x17validate/validate.proto\x1a\x1dworkflow/run_definition.proto\x1a\x1eworkflow/task_definition.proto\"\x7f\n\x10WorkerIdentifier\x12+\n\x0corganization\x18\x01 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x0corganization\x12!\n\x07\x63luster\x18\x02 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x07\x63luster\x12\x1b\n\x04name\x18\x03 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x04name\"\xbf\x04\n\x14\x45nqueueActionRequest\x12H\n\taction_id\x18\x01 \x01(\x0b\x32!.cloudidl.common.ActionIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08\x61\x63tionId\x12\x31\n\x12parent_action_name\x18\x02 \x01(\tH\x01R\x10parentActionName\x88\x01\x01\x12\x35\n\x08run_spec\x18\x03 \x01(\x0b\x32\x1a.cloudidl.workflow.RunSpecR\x07runSpec\x12$\n\tinput_uri\x18\x06 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x08inputUri\x12/\n\x0frun_output_base\x18\x07 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\rrunOutputBase\x12\x14\n\x05group\x18\x08 \x01(\tR\x05group\x12\x18\n\x07subject\x18\t \x01(\tR\x07subject\x12=\n\x04task\x18\n \x01(\x0b\x32\x1d.cloudidl.workflow.TaskActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x04task\x12@\n\x05trace\x18\x0b \x01(\x0b\x32\x1e.cloudidl.workflow.TraceActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x05trace\x12L\n\tcondition\x18\x0c \x01(\x0b\x32\".cloudidl.workflow.ConditionActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\tconditionB\x06\n\x04specB\x15\n\x13_parent_action_name\"\xb5\x01\n\nTaskAction\x12\x31\n\x02id\x18\x01 \x01(\x0b\x32!.cloudidl.workflow.TaskIdentifierR\x02id\x12\x39\n\x04spec\x18\x02 \x01(\x0b\x32\x1b.cloudidl.workflow.TaskSpecB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x04spec\x12\x39\n\tcache_key\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValueR\x08\x63\x61\x63heKey\"\xce\x02\n\x0bTraceAction\x12\x1b\n\x04name\x18\x01 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x04name\x12.\n\x05phase\x18\x02 \x01(\x0e\x32\x18.cloudidl.workflow.PhaseR\x05phase\x12\x39\n\nstart_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tstartTime\x12:\n\x08\x65nd_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00R\x07\x65ndTime\x88\x01\x01\x12=\n\x07outputs\x18\x05 \x01(\x0b\x32#.cloudidl.workflow.OutputReferencesR\x07outputs\x12/\n\x04spec\x18\x06 \x01(\x0b\x32\x1b.cloudidl.workflow.TaskSpecR\x04specB\x0b\n\t_end_time\"\x8a\x02\n\x0f\x43onditionAction\x12\x1b\n\x04name\x18\x01 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x04name\x12 \n\x06run_id\x18\x02 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01H\x00R\x05runId\x12&\n\taction_id\x18\x03 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01H\x00R\x08\x61\x63tionId\x12\x18\n\x06global\x18\x04 \x01(\x08H\x00R\x06global\x12.\n\x04type\x18\x06 \x01(\x0b\x32\x1a.flyteidl.core.LiteralTypeR\x04type\x12\x16\n\x06prompt\x18\x07 \x01(\tR\x06prompt\x12 \n\x0b\x64\x65scription\x18\x08 \x01(\tR\x0b\x64\x65scriptionB\x0c\n\x05scope\x12\x03\xf8\x42\x01\"\x17\n\x15\x45nqueueActionResponse\"X\n\x15\x41\x62ortQueuedRunRequest\x12?\n\x06run_id\x18\x01 \x01(\x0b\x32\x1e.cloudidl.common.RunIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x05runId\"\x18\n\x16\x41\x62ortQueuedRunResponse\"\x80\x03\n\x10HeartbeatRequest\x12J\n\tworker_id\x18\x01 \x01(\x0b\x32#.cloudidl.workflow.WorkerIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08workerId\x12M\n\x11\x61\x63tive_action_ids\x18\x02 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x0f\x61\x63tiveActionIds\x12Q\n\x13terminal_action_ids\x18\x03 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x11terminalActionIds\x12O\n\x12\x61\x62orted_action_ids\x18\x04 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x10\x61\x62ortedActionIds\x12-\n\x12\x61vailable_capacity\x18\x05 \x01(\x05R\x11\x61vailableCapacity\"\xe2\x01\n\x11HeartbeatResponse\x12\x37\n\nnew_leases\x18\x01 \x03(\x0b\x32\x18.cloudidl.workflow.LeaseR\tnewLeases\x12?\n\x0e\x61\x62orted_leases\x18\x02 \x03(\x0b\x32\x18.cloudidl.workflow.LeaseR\rabortedLeases\x12S\n\x14\x66inalized_action_ids\x18\x03 \x03(\x0b\x32!.cloudidl.common.ActionIdentifierR\x12\x66inalizedActionIds\"a\n\x13StreamLeasesRequest\x12J\n\tworker_id\x18\x01 \x01(\x0b\x32#.cloudidl.workflow.WorkerIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08workerId\"H\n\x14StreamLeasesResponse\x12\x30\n\x06leases\x18\x01 \x03(\x0b\x32\x18.cloudidl.workflow.LeaseR\x06leases\"\xc9\x04\n\x05Lease\x12H\n\taction_id\x18\x01 \x01(\x0b\x32!.cloudidl.common.ActionIdentifierB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01R\x08\x61\x63tionId\x12\x31\n\x12parent_action_name\x18\x02 \x01(\tH\x01R\x10parentActionName\x88\x01\x01\x12\x35\n\x08run_spec\x18\x03 \x01(\x0b\x32\x1a.cloudidl.workflow.RunSpecR\x07runSpec\x12$\n\tinput_uri\x18\x04 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\x08inputUri\x12/\n\x0frun_output_base\x18\x05 \x01(\tB\x07\xfa\x42\x04r\x02\x10\x01R\rrunOutputBase\x12=\n\x04task\x18\x06 \x01(\x0b\x32\x1d.cloudidl.workflow.TaskActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x04task\x12L\n\tcondition\x18\x07 \x01(\x0b\x32\".cloudidl.workflow.ConditionActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\tcondition\x12@\n\x05trace\x18\n \x01(\x0b\x32\x1e.cloudidl.workflow.TraceActionB\x08\xfa\x42\x05\x8a\x01\x02\x10\x01H\x00R\x05trace\x12\x14\n\x05group\x18\x08 \x01(\tR\x05group\x12\x18\n\x07subject\x18\t \x01(\tR\x07subject\x12\x12\n\x04host\x18\x0b \x01(\tR\x04hostB\x0b\n\x04spec\x12\x03\xf8\x42\x01\x42\x15\n\x13_parent_action_name2\xa0\x03\n\x0cQueueService\x12\x64\n\rEnqueueAction\x12\'.cloudidl.workflow.EnqueueActionRequest\x1a(.cloudidl.workflow.EnqueueActionResponse\"\x00\x12g\n\x0e\x41\x62ortQueuedRun\x12(.cloudidl.workflow.AbortQueuedRunRequest\x1a).cloudidl.workflow.AbortQueuedRunResponse\"\x00\x12\\\n\tHeartbeat\x12#.cloudidl.workflow.HeartbeatRequest\x1a$.cloudidl.workflow.HeartbeatResponse\"\x00(\x01\x30\x01\x12\x63\n\x0cStreamLeases\x12&.cloudidl.workflow.StreamLeasesRequest\x1a\'.cloudidl.workflow.StreamLeasesResponse\"\x00\x30\x01\x42\xbe\x01\n\x15\x63om.cloudidl.workflowB\x11QueueServiceProtoH\x02P\x01Z+github.com/unionai/cloud/gen/pb-go/workflow\xa2\x02\x03\x43WX\xaa\x02\x11\x43loudidl.Workflow\xca\x02\x11\x43loudidl\\Workflow\xe2\x02\x1d\x43loudidl\\Workflow\\GPBMetadata\xea\x02\x12\x43loudidl::Workflowb\x06proto3')
24
24
 
25
25
  _globals = globals()
26
26
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -50,8 +50,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
50
50
  _TASKACTION.fields_by_name['spec']._serialized_options = b'\372B\005\212\001\002\020\001'
51
51
  _TRACEACTION.fields_by_name['name']._options = None
52
52
  _TRACEACTION.fields_by_name['name']._serialized_options = b'\372B\004r\002\020\001'
53
- _TRACEACTION.fields_by_name['spec']._options = None
54
- _TRACEACTION.fields_by_name['spec']._serialized_options = b'\372B\005\212\001\002\020\001'
55
53
  _CONDITIONACTION.oneofs_by_name['scope']._options = None
56
54
  _CONDITIONACTION.oneofs_by_name['scope']._serialized_options = b'\370B\001'
57
55
  _CONDITIONACTION.fields_by_name['name']._options = None
@@ -87,25 +85,25 @@ if _descriptor._USE_C_DESCRIPTORS == False:
87
85
  _globals['_TASKACTION']._serialized_start=964
88
86
  _globals['_TASKACTION']._serialized_end=1145
89
87
  _globals['_TRACEACTION']._serialized_start=1148
90
- _globals['_TRACEACTION']._serialized_end=1492
91
- _globals['_CONDITIONACTION']._serialized_start=1495
92
- _globals['_CONDITIONACTION']._serialized_end=1761
93
- _globals['_ENQUEUEACTIONRESPONSE']._serialized_start=1763
94
- _globals['_ENQUEUEACTIONRESPONSE']._serialized_end=1786
95
- _globals['_ABORTQUEUEDRUNREQUEST']._serialized_start=1788
96
- _globals['_ABORTQUEUEDRUNREQUEST']._serialized_end=1876
97
- _globals['_ABORTQUEUEDRUNRESPONSE']._serialized_start=1878
98
- _globals['_ABORTQUEUEDRUNRESPONSE']._serialized_end=1902
99
- _globals['_HEARTBEATREQUEST']._serialized_start=1905
100
- _globals['_HEARTBEATREQUEST']._serialized_end=2289
101
- _globals['_HEARTBEATRESPONSE']._serialized_start=2292
102
- _globals['_HEARTBEATRESPONSE']._serialized_end=2518
103
- _globals['_STREAMLEASESREQUEST']._serialized_start=2520
104
- _globals['_STREAMLEASESREQUEST']._serialized_end=2617
105
- _globals['_STREAMLEASESRESPONSE']._serialized_start=2619
106
- _globals['_STREAMLEASESRESPONSE']._serialized_end=2691
107
- _globals['_LEASE']._serialized_start=2694
108
- _globals['_LEASE']._serialized_end=3279
109
- _globals['_QUEUESERVICE']._serialized_start=3282
110
- _globals['_QUEUESERVICE']._serialized_end=3698
88
+ _globals['_TRACEACTION']._serialized_end=1482
89
+ _globals['_CONDITIONACTION']._serialized_start=1485
90
+ _globals['_CONDITIONACTION']._serialized_end=1751
91
+ _globals['_ENQUEUEACTIONRESPONSE']._serialized_start=1753
92
+ _globals['_ENQUEUEACTIONRESPONSE']._serialized_end=1776
93
+ _globals['_ABORTQUEUEDRUNREQUEST']._serialized_start=1778
94
+ _globals['_ABORTQUEUEDRUNREQUEST']._serialized_end=1866
95
+ _globals['_ABORTQUEUEDRUNRESPONSE']._serialized_start=1868
96
+ _globals['_ABORTQUEUEDRUNRESPONSE']._serialized_end=1892
97
+ _globals['_HEARTBEATREQUEST']._serialized_start=1895
98
+ _globals['_HEARTBEATREQUEST']._serialized_end=2279
99
+ _globals['_HEARTBEATRESPONSE']._serialized_start=2282
100
+ _globals['_HEARTBEATRESPONSE']._serialized_end=2508
101
+ _globals['_STREAMLEASESREQUEST']._serialized_start=2510
102
+ _globals['_STREAMLEASESREQUEST']._serialized_end=2607
103
+ _globals['_STREAMLEASESRESPONSE']._serialized_start=2609
104
+ _globals['_STREAMLEASESRESPONSE']._serialized_end=2681
105
+ _globals['_LEASE']._serialized_start=2684
106
+ _globals['_LEASE']._serialized_end=3269
107
+ _globals['_QUEUESERVICE']._serialized_start=3272
108
+ _globals['_QUEUESERVICE']._serialized_end=3688
111
109
  # @@protoc_insertion_point(module_scope)
flyte/_task.py CHANGED
@@ -33,7 +33,7 @@ from ._retry import RetryStrategy
33
33
  from ._reusable_environment import ReusePolicy
34
34
  from ._secret import SecretRequest
35
35
  from ._timeout import TimeoutType
36
- from .models import NativeInterface, SerializationContext
36
+ from .models import MAX_INLINE_IO_BYTES, NativeInterface, SerializationContext
37
37
 
38
38
  if TYPE_CHECKING:
39
39
  from flyteidl.core.tasks_pb2 import DataLoadingConfig
@@ -79,6 +79,8 @@ class TaskTemplate(Generic[P, R]):
79
79
  :param env: Optional The environment variables to set for the task.
80
80
  :param secrets: Optional The secrets that will be injected into the task at runtime.
81
81
  :param timeout: Optional The timeout for the task.
82
+ :param max_inline_io_bytes: Maximum allowed size (in bytes) for all inputs and outputs passed directly to the task
83
+ (e.g., primitives, strings, dicts). Does not apply to files, directories, or dataframes.
82
84
  """
83
85
 
84
86
  name: str
@@ -100,8 +102,8 @@ class TaskTemplate(Generic[P, R]):
100
102
  report: bool = False
101
103
 
102
104
  parent_env: Optional[weakref.ReferenceType[TaskEnvironment]] = None
103
- local: bool = field(default=False, init=False)
104
105
  ref: bool = field(default=False, init=False, repr=False, compare=False)
106
+ max_inline_io_bytes: int = MAX_INLINE_IO_BYTES
105
107
 
106
108
  # Only used in python 3.10 and 3.11, where we cannot use markcoroutinefunction
107
109
  _call_as_synchronous: bool = False
@@ -315,6 +317,7 @@ class TaskTemplate(Generic[P, R]):
315
317
  reusable: Union[ReusePolicy, Literal["off"], None] = None,
316
318
  env: Optional[Dict[str, str]] = None,
317
319
  secrets: Optional[SecretRequest] = None,
320
+ max_inline_io_bytes: int | None = None,
318
321
  **kwargs: Any,
319
322
  ) -> TaskTemplate:
320
323
  """
@@ -324,6 +327,8 @@ class TaskTemplate(Generic[P, R]):
324
327
  cache = cache or self.cache
325
328
  retries = retries or self.retries
326
329
  timeout = timeout or self.timeout
330
+ max_inline_io_bytes = max_inline_io_bytes or self.max_inline_io_bytes
331
+
327
332
  reusable = reusable or self.reusable
328
333
  if reusable == "off":
329
334
  reusable = None
@@ -371,6 +376,7 @@ class TaskTemplate(Generic[P, R]):
371
376
  reusable=cast(Optional[ReusePolicy], reusable),
372
377
  env=env,
373
378
  secrets=secrets,
379
+ max_inline_io_bytes=max_inline_io_bytes,
374
380
  )
375
381
 
376
382
 
@@ -27,7 +27,7 @@ from ._retry import RetryStrategy
27
27
  from ._reusable_environment import ReusePolicy
28
28
  from ._secret import SecretRequest
29
29
  from ._task import AsyncFunctionTaskTemplate, TaskTemplate
30
- from .models import NativeInterface
30
+ from .models import MAX_INLINE_IO_BYTES, NativeInterface
31
31
 
32
32
  if TYPE_CHECKING:
33
33
  from kubernetes.client import V1PodTemplate
@@ -55,8 +55,9 @@ class TaskEnvironment(Environment):
55
55
  :param resources: Resources to allocate for the environment.
56
56
  :param env: Environment variables to set for the environment.
57
57
  :param secrets: Secrets to inject into the environment.
58
- :param depends_on: Environment dependencies to hint, so when you deploy the environment, the dependencies are
59
- also deployed. This is useful when you have a set of environments that depend on each other.
58
+ :param depends_on: Environment dependencies to hint, so when you deploy the environment,
59
+ the dependencies are also deployed. This is useful when you have a set of environments
60
+ that depend on each other.
60
61
  :param cache: Cache policy for the environment.
61
62
  :param reusable: Reuse policy for the environment, if set, a python process may be reused for multiple tasks.
62
63
  """
@@ -86,8 +87,18 @@ class TaskEnvironment(Environment):
86
87
  ) -> TaskEnvironment:
87
88
  """
88
89
  Clone the TaskEnvironment with new parameters.
89
- besides the base environment parameters, you can override, kwargs like `cache`, `reusable`, etc.
90
90
 
91
+ Besides the base environment parameters, you can override kwargs like `cache`, `reusable`, etc.
92
+
93
+ :param name: The name of the environment.
94
+ :param image: The image to use for the environment.
95
+ :param resources: The resources to allocate for the environment.
96
+ :param env: The environment variables to set for the environment.
97
+ :param secrets: The secrets to inject into the environment.
98
+ :param depends_on: The environment dependencies to hint, so when you deploy the environment,
99
+ the dependencies are also deployed. This is useful when you have a set of environments
100
+ that depend on each other.
101
+ :param kwargs: Additional parameters to override the environment (e.g., cache, reusable, plugin_config).
91
102
  """
92
103
  cache = kwargs.pop("cache", None)
93
104
  reusable = None
@@ -130,9 +141,13 @@ class TaskEnvironment(Environment):
130
141
  secrets: Optional[SecretRequest] = None,
131
142
  pod_template: Optional[Union[str, "V1PodTemplate"]] = None,
132
143
  report: bool = False,
144
+ max_inline_io_bytes: int = MAX_INLINE_IO_BYTES,
133
145
  ) -> Union[AsyncFunctionTaskTemplate, Callable[P, R]]:
134
146
  """
147
+ Decorate a function to be a task.
148
+
135
149
  :param _func: Optional The function to decorate. If not provided, the decorator will return a callable that
150
+ accepts a function to be decorated.
136
151
  :param name: Optional A friendly name for the task (defaults to the function name)
137
152
  :param cache: Optional The cache policy for the task, defaults to auto, which will cache the results of the
138
153
  task.
@@ -143,6 +158,8 @@ class TaskEnvironment(Environment):
143
158
  :param pod_template: Optional The pod template for the task, if not provided the default pod template will be
144
159
  used.
145
160
  :param report: Optional Whether to generate the html report for the task, defaults to False.
161
+ :param max_inline_io_bytes: Maximum allowed size (in bytes) for all inputs and outputs passed directly to the
162
+ task (e.g., primitives, strings, dicts). Does not apply to files, directories, or dataframes.
146
163
  """
147
164
  from ._task import P, R
148
165
 
@@ -194,6 +211,7 @@ class TaskEnvironment(Environment):
194
211
  report=report,
195
212
  friendly_name=friendly_name,
196
213
  plugin_config=self.plugin_config,
214
+ max_inline_io_bytes=max_inline_io_bytes,
197
215
  )
198
216
  self._tasks[task_name] = tmpl
199
217
  return tmpl
@@ -212,6 +230,10 @@ class TaskEnvironment(Environment):
212
230
  def add_task(self, task: TaskTemplate) -> TaskTemplate:
213
231
  """
214
232
  Add a task to the environment.
233
+
234
+ Useful when you want to add a task to an environment that is not defined using the `task` decorator.
235
+
236
+ :param task: The TaskTemplate to add to this environment.
215
237
  """
216
238
  if task.name in self._tasks:
217
239
  raise ValueError(f"Task {task.name} already exists in the environment. Task names should be unique.")
flyte/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.0.0b1'
21
- __version_tuple__ = version_tuple = (2, 0, 0, 'b1')
20
+ __version__ = version = '2.0.0b3'
21
+ __version_tuple__ = version_tuple = (2, 0, 0, 'b3')
flyte/errors.py CHANGED
@@ -179,3 +179,13 @@ class ImageBuildError(RuntimeUserError):
179
179
 
180
180
  def __init__(self, message: str):
181
181
  super().__init__("ImageBuildError", message, "user")
182
+
183
+
184
+ class InlineIOMaxBytesBreached(RuntimeUserError):
185
+ """
186
+ This error is raised when the inline IO max bytes limit is breached.
187
+ This can be adjusted per task by setting max_inline_io_bytes in the task definition.
188
+ """
189
+
190
+ def __init__(self, message: str):
191
+ super().__init__("InlineIOMaxBytesBreached", message, "user")
@@ -7,6 +7,7 @@ from flyteidl.core import tasks_pb2
7
7
  from flyte import Image, storage
8
8
  from flyte._logging import logger
9
9
  from flyte._task import TaskTemplate
10
+ from flyte.io import Dir, File
10
11
  from flyte.models import NativeInterface, SerializationContext
11
12
 
12
13
 
@@ -191,7 +192,9 @@ class ContainerTask(TaskTemplate):
191
192
  microseconds=microseconds,
192
193
  )
193
194
 
194
- def _convert_output_val_to_correct_type(self, output_val: Any, output_type: Type) -> Any:
195
+ async def _convert_output_val_to_correct_type(
196
+ self, output_path: pathlib.Path, output_val: Any, output_type: Type
197
+ ) -> Any:
195
198
  import datetime
196
199
 
197
200
  if issubclass(output_type, bool):
@@ -200,17 +203,25 @@ class ContainerTask(TaskTemplate):
200
203
  return datetime.datetime.fromisoformat(output_val)
201
204
  elif issubclass(output_type, datetime.timedelta):
202
205
  return self._string_to_timedelta(output_val)
206
+ elif issubclass(output_type, File):
207
+ return await File.from_local(output_path)
208
+ elif issubclass(output_type, Dir):
209
+ return await Dir.from_local(output_path)
203
210
  else:
204
211
  return output_type(output_val)
205
212
 
206
- def _get_output(self, output_directory: pathlib.Path) -> Tuple[Any]:
213
+ async def _get_output(self, output_directory: pathlib.Path) -> Tuple[Any]:
207
214
  output_items = []
208
215
  if self._outputs:
209
216
  for k, output_type in self._outputs.items():
210
217
  output_path = output_directory / k
211
- with output_path.open("r") as f:
212
- output_val = f.read()
213
- output_items.append(self._convert_output_val_to_correct_type(output_val, output_type))
218
+ if os.path.isfile(output_path):
219
+ with output_path.open("r") as f:
220
+ output_val = f.read()
221
+ else:
222
+ output_val = None
223
+ parsed = await self._convert_output_val_to_correct_type(output_path, output_val, output_type)
224
+ output_items.append(parsed)
214
225
  # return a tuple so that each element is treated as a separate output.
215
226
  # this allows flyte to map the user-defined output types (dict) to individual values.
216
227
  # if we returned a list instead, it would be treated as a single output.
@@ -249,7 +260,7 @@ class ContainerTask(TaskTemplate):
249
260
 
250
261
  container.wait()
251
262
 
252
- output = self._get_output(output_directory)
263
+ output = await self._get_output(output_directory)
253
264
  return output
254
265
 
255
266
  def data_loading_config(self, sctx: SerializationContext) -> tasks_pb2.DataLoadingConfig:
flyte/models.py CHANGED
@@ -18,6 +18,9 @@ if TYPE_CHECKING:
18
18
  from flyte._internal.imagebuild.image_builder import ImageCache
19
19
  from flyte.report import Report
20
20
 
21
+ # --- Constants ----
22
+ MAX_INLINE_IO_BYTES = 10 * 1024 * 1024 # 100 MB
23
+
21
24
 
22
25
  def generate_random_name() -> str:
23
26
  """
flyte/remote/_task.py CHANGED
@@ -81,6 +81,7 @@ AutoVersioning = Literal["latest", "current"]
81
81
  @dataclass
82
82
  class TaskDetails:
83
83
  pb2: task_definition_pb2.TaskDetails
84
+ max_inline_io_bytes: int = 10 * 1024 * 1024 # 10 MB
84
85
 
85
86
  @classmethod
86
87
  def get(
@@ -252,7 +253,7 @@ class TaskDetails:
252
253
 
253
254
  controller = get_controller()
254
255
  if controller:
255
- return await controller.submit_task_ref(self.pb2, *args, **kwargs)
256
+ return await controller.submit_task_ref(self.pb2, self.max_inline_io_bytes, *args, **kwargs)
256
257
  raise flyte.errors
257
258
 
258
259
  def override(
@@ -267,6 +268,7 @@ class TaskDetails:
267
268
  reusable: Union[flyte.ReusePolicy, Literal["auto"], None] = None,
268
269
  env: Optional[Dict[str, str]] = None,
269
270
  secrets: Optional[flyte.SecretRequest] = None,
271
+ max_inline_io_bytes: int | None = None,
270
272
  **kwargs: Any,
271
273
  ) -> TaskDetails:
272
274
  raise NotImplementedError
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flyte
3
- Version: 2.0.0b1
3
+ Version: 2.0.0b3
4
4
  Summary: Add your description here
5
5
  Author-email: Ketan Umare <kumare3@users.noreply.github.com>
6
6
  Requires-Python: >=3.10
@@ -8,7 +8,7 @@ Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
9
  Requires-Dist: aiofiles>=24.1.0
10
10
  Requires-Dist: click>=8.2.1
11
- Requires-Dist: flyteidl==1.15.4b0
11
+ Requires-Dist: flyteidl>=1.15.4b0
12
12
  Requires-Dist: cloudpickle>=3.1.1
13
13
  Requires-Dist: fsspec>=2025.3.0
14
14
  Requires-Dist: grpcio>=1.71.0
@@ -36,6 +36,14 @@ Dynamic: license-file
36
36
 
37
37
  > ⚡ **Pure Python workflows** • 🔄 **Async-first parallelism** • 🛠️ **Zero DSL constraints** • 📊 **Sub-task observability**
38
38
 
39
+ ## 🌍 Ecosystem & Resources
40
+
41
+ - **📖 Documentation**: [Docs Link](https://www.union.ai/docs/v2/flyte/user-guide/)
42
+ - **▶️ Getting Started**: [Docs Link](https://www.union.ai/docs/v2/flyte/user-guide/getting-started/)
43
+ - **💬 Community**: [Slack](https://slack.flyte.org/) | [GitHub Discussions](https://github.com/flyteorg/flyte/discussions)
44
+ - **🎓 Examples**: [GitHub Examples](https://github.com/flyteorg/flyte-sdk/tree/main/examples)
45
+ - **🐛 Issues**: [Bug Reports](https://github.com/flyteorg/flyte/issues)
46
+
39
47
  ## What is Flyte 2?
40
48
 
41
49
  Flyte 2 represents a fundamental shift from constrained domain-specific languages to **pure Python workflows**. Write data pipelines, ML training jobs, and distributed compute exactly like you write Python—because it *is* Python.
@@ -65,21 +73,11 @@ if __name__ == "__main__":
65
73
 
66
74
  ## 🌟 Why Flyte 2?
67
75
 
68
- ### **No More Workflow DSL**
69
- - `@workflow` decorators with Python subset limitations
70
- - ✅ **Pure Python**: loops, conditionals, error handling, dynamic structures
71
-
72
- ### **Async-First Parallelism**
73
- - ❌ Custom `map()` functions and workflow-specific parallel constructs
74
- - ✅ **Native `asyncio`**: `await asyncio.gather()` for distributed parallel execution
75
-
76
- ### **True Container Reusability**
77
- - ❌ Cold container starts for every task
78
- - ✅ **Millisecond scheduling** with warm, reusable container pools
79
-
80
- ### **Fine-Grained Observability**
81
- - ❌ Task-level logging only
82
- - ✅ **Function-level tracing** with `@flyte.trace` for sub-task checkpoints
76
+ | Feature Highlight | Flyte 1 | Flyte 2 |
77
+ |-| ------- | ------- |
78
+ | **No More Workflow DSL** | ❌ `@workflow` decorators with Python subset limitations | ✅ **Pure Python**: loops, conditionals, error handling, dynamic structures |
79
+ | **Async-First Parallelism** | ❌ Custom `map()` functions and workflow-specific parallel constructs | ✅ **Native `asyncio`**: `await asyncio.gather()` for distributed parallel execution |
80
+ | **Fine-Grained Observability** | ❌ Task-level logging only | ✅ **Function-level tracing** with `@flyte.trace` for sub-task checkpoints |
83
81
 
84
82
  ## 🚀 Quick Start
85
83
 
@@ -102,13 +100,13 @@ uv pip install --prerelease=allow flyte
102
100
  # hello.py
103
101
  # /// script
104
102
  # requires-python = ">=3.10"
105
- # dependencies = ["flyte>=0.2.0"]
103
+ # dependencies = ["flyte>=2.0.0b0"]
106
104
  # ///
107
105
 
108
106
  import flyte
109
107
 
110
108
  env = flyte.TaskEnvironment(
111
- name="hello_world",
109
+ name="hello_world",
112
110
  resources=flyte.Resources(memory="250Mi")
113
111
  )
114
112
 
@@ -116,7 +114,7 @@ env = flyte.TaskEnvironment(
116
114
  def calculate(x: int) -> int:
117
115
  return x * 2 + 5
118
116
 
119
- @env.task
117
+ @env.task
120
118
  async def main(numbers: list[int]) -> float:
121
119
  # Parallel execution across distributed containers
122
120
  results = await asyncio.gather(*[
@@ -156,7 +154,7 @@ def train_model(data: flyte.File) -> flyte.File:
156
154
  # Runs in configured container with GPU access
157
155
  pass
158
156
 
159
- @env.task
157
+ @env.task
160
158
  def evaluate_model(model: flyte.File, test_data: flyte.File) -> dict:
161
159
  # Same container configuration, different instance
162
160
  pass
@@ -168,7 +166,7 @@ def evaluate_model(model: flyte.File, test_data: flyte.File) -> dict:
168
166
  @env.task
169
167
  async def dynamic_pipeline(config: dict) -> list[str]:
170
168
  results = []
171
-
169
+
172
170
  # ✅ Use any Python construct
173
171
  for dataset in config["datasets"]:
174
172
  try:
@@ -182,7 +180,7 @@ async def dynamic_pipeline(config: dict) -> list[str]:
182
180
  # ✅ Custom error recovery
183
181
  result = await handle_error(dataset, e)
184
182
  results.append(result)
185
-
183
+
186
184
  return results
187
185
  ```
188
186
 
@@ -191,18 +189,18 @@ async def dynamic_pipeline(config: dict) -> list[str]:
191
189
  ```python
192
190
  @env.task
193
191
  async def parallel_training(hyperparams: list[dict]) -> dict:
194
- # Each model trains on separate infrastructure
192
+ # Each model trains on separate infrastructure
195
193
  models = await asyncio.gather(*[
196
194
  train_model.aio(params) for params in hyperparams
197
195
  ])
198
-
196
+
199
197
  # Evaluate all models in parallel
200
198
  evaluations = await asyncio.gather(*[
201
- evaluate_model.aio(model) for model in models
199
+ evaluate_model.aio(model) for model in models
202
200
  ])
203
-
201
+
204
202
  # Find best model
205
- best_idx = max(range(len(evaluations)),
203
+ best_idx = max(range(len(evaluations)),
206
204
  key=lambda i: evaluations[i]["accuracy"])
207
205
  return {"best_model": models[best_idx], "accuracy": evaluations[best_idx]}
208
206
  ```
@@ -223,7 +221,7 @@ async def main_task(inputs: list[str]) -> list[str]:
223
221
  results = []
224
222
  for inp in inputs:
225
223
  # If task fails here, it resumes from the last successful trace
226
- result = await expensive_computation(inp)
224
+ result = await expensive_computation(inp)
227
225
  results.append(result)
228
226
  return results
229
227
  ```
@@ -241,31 +239,11 @@ spark_task = flyte.remote.Task.get("spark_env.process_data", auto_version="lates
241
239
  async def orchestrator(raw_data: flyte.File) -> flyte.File:
242
240
  # Execute Spark job on big data cluster
243
241
  processed = await spark_task(raw_data)
244
-
245
- # Execute PyTorch training on GPU cluster
246
- model = await torch_task(processed)
247
-
248
- return model
249
- ```
250
-
251
- ### **High-Performance Container Reuse**
252
242
 
253
- ```python
254
- env = flyte.TaskEnvironment(
255
- name="high_throughput",
256
- reusable=flyte.ReusePolicy(
257
- replicas=10, # Keep 10 warm containers
258
- idle_ttl=600, # 10-minute idle timeout
259
- ),
260
- resources=flyte.Resources(cpu=2, memory="4Gi")
261
- )
243
+ # Execute PyTorch training on GPU cluster
244
+ model = await torch_task(processed)
262
245
 
263
- # Tasks scheduled in milliseconds on warm containers
264
- @env.task
265
- async def process_thousands(items: list[str]) -> list[str]:
266
- return await asyncio.gather(*[
267
- process_item.aio(item) for item in items
268
- ])
246
+ return model
269
247
  ```
270
248
 
271
249
  ## 📊 Native Jupyter Integration
@@ -296,7 +274,7 @@ endpoint: https://my-flyte-instance.com
296
274
  project: ml-team
297
275
  domain: production
298
276
  image:
299
- builder: remote
277
+ builder: local
300
278
  registry: ghcr.io/my-org
301
279
  auth:
302
280
  type: oauth2
@@ -308,14 +286,14 @@ auth:
308
286
  # Deploy tasks to remote cluster
309
287
  flyte deploy my_workflow.py
310
288
 
311
- # Run deployed workflow
289
+ # Run deployed workflow
312
290
  flyte run my_workflow --input-file params.json
313
291
 
314
292
  # Monitor execution
315
293
  flyte logs <execution-id>
316
294
  ```
317
295
 
318
- ## 🆚 Migration from Flyte 1
296
+ ## Migration from Flyte 1
319
297
 
320
298
  | Flyte 1 | Flyte 2 |
321
299
  |---------|---------|
@@ -326,46 +304,40 @@ flyte logs <execution-id>
326
304
  | `LaunchPlan` schedules | `@env.task(on_schedule=...)` |
327
305
  | Workflow failure handlers | Python `try/except` |
328
306
 
329
- ### Example Migration
330
-
331
- ```python
332
- # Flyte 1
333
- @flytekit.workflow
334
- def old_workflow(data: list[str]) -> list[str]:
335
- return [process_item(item=item) for item in data]
336
-
337
- # Flyte 2
338
- @env.task
339
- async def new_workflow(data: list[str]) -> list[str]:
340
- return await asyncio.gather(*[
341
- process_item.aio(item) for item in data
342
- ])
343
- ```
344
-
345
- ## 🌍 Ecosystem & Resources
346
-
347
- - **📖 Documentation**: [flyte.org/docs](https://flyte.org/docs)
348
- - **💬 Community**: [Slack](https://flyte.org/slack) | [GitHub Discussions](https://github.com/flyteorg/flyte/discussions)
349
- - **🎓 Examples**: [GitHub Examples](https://github.com/flyteorg/flytesnacks)
350
- - **🐛 Issues**: [Bug Reports](https://github.com/flyteorg/flyte/issues)
351
-
352
307
  ## 🤝 Contributing
353
308
 
354
309
  We welcome contributions! Whether it's:
355
310
 
356
311
  - 🐛 **Bug fixes**
357
- - ✨ **New features**
312
+ - ✨ **New features**
358
313
  - 📚 **Documentation improvements**
359
314
  - 🧪 **Testing enhancements**
360
315
 
361
- See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
316
+ ### Setup & Iteration Cycle
317
+ To get started, make sure you start from a new virtual environment and install this package in editable mode with any of the supported Python versions, from 3.10 to 3.13.
362
318
 
363
- ## 📄 License
319
+ ```bash
320
+ uv venv --python 3.13
321
+ uv pip install -e .
322
+ ```
364
323
 
365
- Flyte 2 is licensed under the [Apache 2.0 License](LICENSE).
324
+ Besides from picking up local code changes, installing the package in editable mode
325
+ also changes the definition of the default `Image()` object to use a locally
326
+ build wheel. You will need to build said wheel by yourself though, with the `make dist` target.
366
327
 
367
- ---
328
+ ```bash
329
+ make dist
330
+ python maint_tools/build_default_image.py
331
+ ```
332
+ You'll need to have a local docker daemon running for this. The build script does nothing
333
+ more than invoke the local image builder, which will create a buildx builder named `flytex` if not present. Note that only members of the `Flyte Maintainers` group has
334
+ access to push to the default registry. If you don't have access, please make sure to
335
+ specify the registry and name to the build script.
368
336
 
369
- **Ready to build the future of distributed computing with pure Python?**
337
+ ```bash
338
+ python maint_tools/build_default_image.py --registry ghcr.io/my-org --name my-flyte-image
339
+ ```
370
340
 
371
- **Star this repo** | 🚀 **[Get Started Now](https://flyte.org/docs/getting-started)** | 💬 **[Join our Community](https://flyte.org/slack)**
341
+ ## 📄 License
342
+
343
+ Flyte 2 is licensed under the [Apache 2.0 License](LICENSE).
@@ -19,16 +19,16 @@ flyte/_retry.py,sha256=rfLv0MvWxzPByKESTglEmjPsytEAKiIvvmzlJxXwsfE,941
19
19
  flyte/_reusable_environment.py,sha256=f8Y1GilUwGcXH4n2Fckrnx0SrZmhk3nCfoe-TqUKivI,3740
20
20
  flyte/_run.py,sha256=HkTD3rHL34pAwvn1WPN6OXYmk-GWX0txLdRH1OIMvEA,24338
21
21
  flyte/_secret.py,sha256=ogXmCNfYYIphV6p-2iiWmwr2cNUES5Cq01PPjY6uQNA,3217
22
- flyte/_task.py,sha256=pPq44DDr3PzaWXOJro0W2_mY4wdbS8Hwn0VFd-kel3Q,18985
23
- flyte/_task_environment.py,sha256=qYcTG9452a_POueQCHqkTafN4HG8Xo7KkBPwSMkKRRU,8536
22
+ flyte/_task.py,sha256=rYR7SVGihfBp7UYrhdmqhHp0ngl2K7Za8IJfhv1K2oc,19402
23
+ flyte/_task_environment.py,sha256=Zpfr8gjwXg5KuCfIbT4s3l2mtJCFqDxXwv6ZStHWBuc,9840
24
24
  flyte/_task_plugins.py,sha256=9MH3nFPOH_e8_92BT4sFk4oyAnj6GJFvaPYWaraX7yE,1037
25
25
  flyte/_timeout.py,sha256=zx5sFcbYmjJAJbZWSGzzX-BpC9HC7Jfs35T7vVhKwkk,1571
26
26
  flyte/_tools.py,sha256=tWb0sx3t3mm4jbaQVjCTc9y39oR_Ibo3z_KHToP3Lto,966
27
27
  flyte/_trace.py,sha256=SSE1nzUgmVTS2xFNtchEOjEjlRavMOIInasXzY8i9lU,4911
28
- flyte/_version.py,sha256=tih12kl71zm-lSZ-WK20LgQ1skyymSxHAu3d0I8n6WM,519
29
- flyte/errors.py,sha256=3PCjGAxqifLBY6RE1n_ttmrmhcHwwtzS4UWDPql-FX4,5175
28
+ flyte/_version.py,sha256=fn05QckBHXt6TeCLv-zTOz1tLPEdQLSISwMKmzhR-ks,519
29
+ flyte/errors.py,sha256=MsVZxq6oeIOXe6AVWpxqA3ZiyxCGM0A6UqnYuvmSUCU,5514
30
30
  flyte/extend.py,sha256=GB4ZedGzKa30vYWRVPOdxEeK62xnUVFY4z2tD6H9eEw,376
31
- flyte/models.py,sha256=k0hLoyOYQHnu5DXclEtKK2owDOXCdy0UKdGcl3xR7BQ,15250
31
+ flyte/models.py,sha256=AJZXL8eRmZ2RHEvjL6VSdpTmgF5S1Ekh_tAKRn0b6mM,15321
32
32
  flyte/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  flyte/_bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  flyte/_bin/runtime.py,sha256=2jTy3ccvrJ__Xrfdo2t0Fxhsojc5o2zIxDHt98RE_eU,6475
@@ -42,13 +42,13 @@ flyte/_code_bundle/_packaging.py,sha256=5QUuea6kg9s-ebBg7gFAHaxOMchxR5MhTQ8KohWs
42
42
  flyte/_code_bundle/_utils.py,sha256=qlAVmik9rLasfd1oNrCxhL870w5ntk5ZlNGeaKSKaAU,12028
43
43
  flyte/_code_bundle/bundle.py,sha256=nUAwYTVAE3Z9dfgkBtsqCoKJImjSl4AicG36yweWHLc,8797
44
44
  flyte/_internal/__init__.py,sha256=vjXgGzAAjy609YFkAy9_RVPuUlslsHSJBXCLNTVnqOY,136
45
- flyte/_internal/controllers/__init__.py,sha256=5CBnS9lb1VFMzZuRXUiaPhlN3G9qh7Aq9kTwxW5hsRw,4301
46
- flyte/_internal/controllers/_local_controller.py,sha256=tbX6x8TBKwZHN1vYumftUcaX9fy162hGibo3AQZHYKA,7260
45
+ flyte/_internal/controllers/__init__.py,sha256=TVAc4ydsldcIFmN3PW9-IX5UkKeD8oOmuIukIgEae9M,4341
46
+ flyte/_internal/controllers/_local_controller.py,sha256=__-eEira0k18DsBu1LBXeEjhFGFcp1Uai9K0YEBbwKM,7300
47
47
  flyte/_internal/controllers/_trace.py,sha256=ywFg_M2nGrCKYLbh4iVdsVlRtPT1K2S-XZMvDJU8AKU,1499
48
48
  flyte/_internal/controllers/remote/__init__.py,sha256=9_azH1eHLqY6VULpDugXi7Kf1kK1ODqEnsQ_3wM6IqU,1919
49
49
  flyte/_internal/controllers/remote/_action.py,sha256=ENV1thRXllSpi2s4idL-vCVcmXQNS17hmP2lMDKzNdo,7397
50
50
  flyte/_internal/controllers/remote/_client.py,sha256=HPbzbfaWZVv5wpOvKNtFXR6COiZDwd1cUJQqi60A7oU,1421
51
- flyte/_internal/controllers/remote/_controller.py,sha256=oubfymmNgZtVEDJF8HiV3r2i_6lGgBZBzh0437jY0zQ,23766
51
+ flyte/_internal/controllers/remote/_controller.py,sha256=80e7Sbvg0SKFvF5wln_8RlSkwaYmT1QUFYUao9BwvUA,24508
52
52
  flyte/_internal/controllers/remote/_core.py,sha256=49l1X3YFyX-QYeSlvkOWdyEU2xc1Fr7I8qHvC3nQ6MA,19069
53
53
  flyte/_internal/controllers/remote/_informer.py,sha256=w4p29_dzS_ns762eNBljvnbJLgCm36d1Ogo2ZkgV1yg,14418
54
54
  flyte/_internal/controllers/remote/_service_protocol.py,sha256=B9qbIg6DiGeac-iSccLmX_AL2xUgX4ezNUOiAbSy4V0,1357
@@ -63,7 +63,7 @@ flyte/_internal/resolvers/default.py,sha256=nX4DHUYod1nRvEsl_vSgutQVEdExu2xL8pRk
63
63
  flyte/_internal/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
64
  flyte/_internal/runtime/convert.py,sha256=yK5Fy25-CVSqTtWF8BuBel2jwlVoh8R5F4UhIMYpgmg,16086
65
65
  flyte/_internal/runtime/entrypoints.py,sha256=9Ng-aQ45M-_MMWeOe9uGmgx69qO9b0xaMRiu542ZI9g,6581
66
- flyte/_internal/runtime/io.py,sha256=Lgdy4iPjlKjUO-V_AkoPZff6lywaFjZUG-PErRukmx4,4248
66
+ flyte/_internal/runtime/io.py,sha256=ysL7hMpfVumvsEYWOM-_VPa8MXn5_X_CZorKbOThyv4,5935
67
67
  flyte/_internal/runtime/resources_serde.py,sha256=TObMVsSjVcQhcY8-nY81pbvrz7TP-adDD5xV-LqAaxM,4813
68
68
  flyte/_internal/runtime/reuse.py,sha256=WEuBfC9tBezxaIXeUQDgnJfnRHiUmPK0S25nTOFle4E,4676
69
69
  flyte/_internal/runtime/rusty.py,sha256=puMaa6aLaoR4Tl5xxZulC4AzY58nmGg-5ok4ydHHjdM,6145
@@ -124,7 +124,7 @@ flyte/_protos/workflow/environment_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDC
124
124
  flyte/_protos/workflow/node_execution_service_pb2.py,sha256=IOLg3tNikY7n00kLOVsC69yyXc5Ttnx-_-xUuc0q05Q,1654
125
125
  flyte/_protos/workflow/node_execution_service_pb2.pyi,sha256=C7VVuw_bnxp68qemD3SLoGIL-Hmno6qkIoq3l6W2qb8,135
126
126
  flyte/_protos/workflow/node_execution_service_pb2_grpc.py,sha256=2JJDS3Aww3FFDW-qYdTaxC75gRpsgnn4an6LPZmF9uA,947
127
- flyte/_protos/workflow/queue_service_pb2.py,sha256=zrYxvapY74-xz0RVXsXv6wG0u054kUnNQDL5b7GJ5lw,13561
127
+ flyte/_protos/workflow/queue_service_pb2.py,sha256=idHNrsnJglPVxoviySSkVqfSTf3H1lAGIBXNVZACYBA,13374
128
128
  flyte/_protos/workflow/queue_service_pb2.pyi,sha256=lZ9rO0KpuyGadl5GqQ8JgffZcDlzfSeyNmsZ3du9Gqg,9499
129
129
  flyte/_protos/workflow/queue_service_pb2_grpc.py,sha256=6KK87jYXrmK0jacf4AKhHp21QU9JFJPOiEBjbDRkBm0,7839
130
130
  flyte/_protos/workflow/run_definition_pb2.py,sha256=sdyl7xgl6tTqkKNXrWcrhvV4KOZPqoMa9vjEmwVyfZc,16193
@@ -172,17 +172,13 @@ flyte/config/_internal.py,sha256=LMcAtDjvTjf5bGlsJVxPuLxQQ82mLd00xK5-JlYGCi8,298
172
172
  flyte/config/_reader.py,sha256=coidKV5CVODEnqDnsHZ9-VMC0UGXanXhAZE1SmYRhxI,7021
173
173
  flyte/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
174
174
  flyte/extras/__init__.py,sha256=FhB0uK7H1Yo5De9vOuF7UGnezTKncj3u2Wo5uQdWN0g,74
175
- flyte/extras/_container.py,sha256=kxwiMltfMizjOKmsXYQ-rLOCHmX-TCCeJRM7ukuHoOg,11367
175
+ flyte/extras/_container.py,sha256=xfbxaGrx2JyQyrvQx1UWTzho2ion8_xujPW5V4uDEIs,11818
176
176
  flyte/io/__init__.py,sha256=qF8jq_IKuocuGU0LAvoy_uxjMs4G-vXjDA9Prba0JGU,538
177
177
  flyte/io/_dir.py,sha256=rih9CY1YjNX05bcAu5LG62Xoyij5GXAlv7jLyVF0je8,15310
178
178
  flyte/io/_file.py,sha256=kp5700SKPy5htmMhm4hE2ybb99Ykny1b0Kwm3huCWXs,15572
179
179
  flyte/io/_dataframe/__init__.py,sha256=SDgNw45uf7m3cHhbUCOA3V3-5A2zSKgPcsWriRLwd74,4283
180
180
  flyte/io/_dataframe/basic_dfs.py,sha256=weQ8EfzdU-LcKi8Eebq1AiATVS1fGdfcbqtCDOrVLos,7728
181
181
  flyte/io/_dataframe/dataframe.py,sha256=uecLLjaAuLyYta2d4Tkk-DjxuHkzZjFUBbvMapPM7R8,51554
182
- flyte/migrate/__init__.py,sha256=I1I0JoESM6s_kILMUcuP972Zks1DeTc5CiU2zjKxTeU,64
183
- flyte/migrate/dynamic.py,sha256=igL6lMgKKH-g3CwF48SGi-F5YWdE9p8iXlMi4LJGnxc,296
184
- flyte/migrate/task.py,sha256=V1-bKQuz0aPYG9jzHpjdujPJSGTQRH4Yda3ZPmwkVxA,3714
185
- flyte/migrate/workflow.py,sha256=AbPchkUZXUAAGlrdy43M23fdpo9tsVaXcMLVSh7z9pU,328
186
182
  flyte/remote/__init__.py,sha256=y9eke9JzEJkygk8eKZjSj44fJGlyepuW4i-j6lbCAPY,617
187
183
  flyte/remote/_action.py,sha256=5DN6rEb4WhsdDEZsYPFFOUyn2yjSMefVojkMF7DE7XM,23839
188
184
  flyte/remote/_console.py,sha256=avmELJPx8nQMAVPrHlh6jEIRPjrMwFpdZjJsWOOa9rE,660
@@ -191,7 +187,7 @@ flyte/remote/_logs.py,sha256=aDG18-uPVb2J3PxmqmAY1C0Z4Iv1P1agg-iF4nSQR4U,6709
191
187
  flyte/remote/_project.py,sha256=CFNTGpgXU3X599tkJ_oxijs9zPzzCWOB6mAWn6WeDEU,2828
192
188
  flyte/remote/_run.py,sha256=fpr_YcGZIv6K7Jt1if3-HHHVB2TVt_8AWcZ55rN_fgk,9750
193
189
  flyte/remote/_secret.py,sha256=l5xeMS83uMcWWeSSTRsSZUNhS0N--1Dze09C-thSOQs,4341
194
- flyte/remote/_task.py,sha256=pIQ2pIIcaEaOo5J1ua3eRlj9NAue9WOSyw64f1-A2oY,15183
190
+ flyte/remote/_task.py,sha256=xHfWChnC-L7Hdp2IB9qDnbNyaOgM2TWOlnkmevoc2dA,15314
195
191
  flyte/remote/_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
196
192
  flyte/remote/_client/_protocols.py,sha256=JyBWHs5WsVOxEDUyG9X7wPLDzzzjkoaNhJlU-X4YlN0,5599
197
193
  flyte/remote/_client/controlplane.py,sha256=FsOfj4rO4MIMnYrpAT53F8q588VVf5t4sDuwoPuc840,3102
@@ -230,10 +226,10 @@ flyte/types/_renderer.py,sha256=ygcCo5l60lHufyQISFddZfWwLlQ8kJAKxUT_XnR_6dY,4818
230
226
  flyte/types/_string_literals.py,sha256=NlG1xV8RSA-sZ-n-IFQCAsdB6jXJOAKkHWtnopxVVDk,4231
231
227
  flyte/types/_type_engine.py,sha256=Tas_OXYddOi0nDuORjqan2SkJ96wKD8937I2l1bo8vk,97916
232
228
  flyte/types/_utils.py,sha256=pbts9E1_2LTdLygAY0UYTLYJ8AsN3BZyviSXvrtcutc,2626
233
- flyte-2.0.0b1.data/scripts/runtime.py,sha256=2jTy3ccvrJ__Xrfdo2t0Fxhsojc5o2zIxDHt98RE_eU,6475
234
- flyte-2.0.0b1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
235
- flyte-2.0.0b1.dist-info/METADATA,sha256=v8ZPND_lTS1evo9ypHWHFL7pcb1Xs1xB3b5eW_d9WNs,10015
236
- flyte-2.0.0b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
237
- flyte-2.0.0b1.dist-info/entry_points.txt,sha256=MIq2z5dBurdCJfpXfMKzgBv7sJOakKRYxr8G0cMiTrg,75
238
- flyte-2.0.0b1.dist-info/top_level.txt,sha256=7dkyFbikvA12LEZEqawx8oDG1CMod6hTliPj7iWzgYo,6
239
- flyte-2.0.0b1.dist-info/RECORD,,
229
+ flyte-2.0.0b3.data/scripts/runtime.py,sha256=2jTy3ccvrJ__Xrfdo2t0Fxhsojc5o2zIxDHt98RE_eU,6475
230
+ flyte-2.0.0b3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
231
+ flyte-2.0.0b3.dist-info/METADATA,sha256=DxTr4d_6Ohm1VRSqhqILMy_McBGsKB4ykk274bne-fM,9955
232
+ flyte-2.0.0b3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
233
+ flyte-2.0.0b3.dist-info/entry_points.txt,sha256=MIq2z5dBurdCJfpXfMKzgBv7sJOakKRYxr8G0cMiTrg,75
234
+ flyte-2.0.0b3.dist-info/top_level.txt,sha256=7dkyFbikvA12LEZEqawx8oDG1CMod6hTliPj7iWzgYo,6
235
+ flyte-2.0.0b3.dist-info/RECORD,,
flyte/migrate/__init__.py DELETED
@@ -1 +0,0 @@
1
- from flyte.migrate import dynamic, task, workflow # noqa: F401
flyte/migrate/dynamic.py DELETED
@@ -1,13 +0,0 @@
1
- from typing import Callable, Union
2
-
3
- import flytekit
4
-
5
- import flyte.migrate
6
- from flyte._task import AsyncFunctionTaskTemplate, P, R
7
-
8
-
9
- def dynamic_shim(**kwargs) -> Union[AsyncFunctionTaskTemplate, Callable[P, R]]:
10
- return flyte.migrate.task.task_shim(**kwargs)
11
-
12
-
13
- flytekit.dynamic = dynamic_shim
flyte/migrate/task.py DELETED
@@ -1,99 +0,0 @@
1
- import datetime
2
- from typing import Callable, Dict, Iterable, List, Literal, Optional, Tuple, Union
3
-
4
- import flytekit
5
- from flytekit.core import launch_plan, workflow
6
- from flytekit.core.base_task import T, TaskResolverMixin
7
- from flytekit.core.python_function_task import PythonFunctionTask
8
- from flytekit.core.task import FuncOut
9
- from flytekit.deck import DeckField
10
- from flytekit.extras.accelerators import BaseAccelerator
11
-
12
- import flyte
13
- from flyte import Image, Resources, TaskEnvironment
14
- from flyte._doc import Documentation
15
- from flyte._task import AsyncFunctionTaskTemplate, P, R
16
-
17
-
18
- def task_shim(
19
- _task_function: Optional[Callable[P, FuncOut]] = None,
20
- task_config: Optional[T] = None,
21
- cache: Union[bool, flytekit.Cache] = False,
22
- retries: int = 0,
23
- interruptible: Optional[bool] = None,
24
- deprecated: str = "",
25
- timeout: Union[datetime.timedelta, int] = 0,
26
- container_image: Optional[Union[str, flytekit.ImageSpec]] = None,
27
- environment: Optional[Dict[str, str]] = None,
28
- requests: Optional[flytekit.Resources] = None,
29
- limits: Optional[flytekit.Resources] = None,
30
- secret_requests: Optional[List[flytekit.Secret]] = None,
31
- execution_mode: PythonFunctionTask.ExecutionBehavior = PythonFunctionTask.ExecutionBehavior.DEFAULT,
32
- node_dependency_hints: Optional[
33
- Iterable[
34
- Union[
35
- flytekit.PythonFunctionTask,
36
- launch_plan.LaunchPlan,
37
- workflow.WorkflowBase,
38
- ]
39
- ]
40
- ] = None,
41
- task_resolver: Optional[TaskResolverMixin] = None,
42
- docs: Optional[flytekit.Documentation] = None,
43
- disable_deck: Optional[bool] = None,
44
- enable_deck: Optional[bool] = None,
45
- deck_fields: Optional[Tuple[DeckField, ...]] = (
46
- DeckField.SOURCE_CODE,
47
- DeckField.DEPENDENCIES,
48
- DeckField.TIMELINE,
49
- DeckField.INPUT,
50
- DeckField.OUTPUT,
51
- ),
52
- pod_template: Optional[flytekit.PodTemplate] = None,
53
- pod_template_name: Optional[str] = None,
54
- accelerator: Optional[BaseAccelerator] = None,
55
- pickle_untyped: bool = False,
56
- shared_memory: Optional[Union[Literal[True], str]] = None,
57
- resources: Optional[Resources] = None,
58
- labels: Optional[dict[str, str]] = None,
59
- annotations: Optional[dict[str, str]] = None,
60
- **kwargs,
61
- ) -> Union[AsyncFunctionTaskTemplate, Callable[P, R]]:
62
- plugin_config = task_config
63
- pod_template = (
64
- flyte.PodTemplate(
65
- pod_spec=pod_template.pod_spec,
66
- primary_container_name=pod_template.primary_container_name,
67
- labels=pod_template.labels,
68
- annotations=pod_template.annotations,
69
- )
70
- if pod_template
71
- else None
72
- )
73
-
74
- if isinstance(container_image, flytekit.ImageSpec):
75
- image = Image.from_debian_base()
76
- if container_image.apt_packages:
77
- image = image.with_apt_packages(*container_image.apt_packages)
78
- pip_packages = ["flytekit"]
79
- if container_image.packages:
80
- pip_packages.extend(container_image.packages)
81
- image = image.with_pip_packages(*pip_packages)
82
- elif isinstance(container_image, str):
83
- image = Image.from_base(container_image).with_pip_packages("flyte")
84
- else:
85
- image = Image.from_debian_base().with_pip_packages("flytekit")
86
-
87
- docs = Documentation(description=docs.short_description) if docs else None
88
-
89
- env = TaskEnvironment(
90
- name="flytekit",
91
- resources=Resources(cpu=0.8, memory="800Mi"),
92
- image=image,
93
- cache="enabled" if cache else "disable",
94
- plugin_config=plugin_config,
95
- )
96
- return env.task(retries=retries, pod_template=pod_template_name or pod_template, docs=docs)
97
-
98
-
99
- flytekit.task = task_shim
flyte/migrate/workflow.py DELETED
@@ -1,13 +0,0 @@
1
- import flytekit
2
-
3
- from flyte import Image, Resources, TaskEnvironment
4
-
5
- env = TaskEnvironment(
6
- name="flytekit",
7
- resources=Resources(cpu=0.8, memory="800Mi"),
8
- image=Image.from_debian_base().with_apt_packages("vim").with_pip_packages("flytekit", "pandas"),
9
- )
10
-
11
- # TODO: Build subtask's image
12
-
13
- flytekit.workflow = env.task