flyte 0.2.0b9__py3-none-any.whl → 0.2.0b10__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 CHANGED
@@ -38,7 +38,7 @@ __all__ = [
38
38
  "deploy",
39
39
  "group",
40
40
  "init",
41
- "init_auto_from_config",
41
+ "init_from_config",
42
42
  "map",
43
43
  "run",
44
44
  "trace",
@@ -51,7 +51,7 @@ from ._deploy import deploy
51
51
  from ._environment import Environment
52
52
  from ._group import group
53
53
  from ._image import Image
54
- from ._initialize import init, init_auto_from_config
54
+ from ._initialize import init, init_from_config
55
55
  from ._map import map
56
56
  from ._resources import GPU, TPU, Device, Resources
57
57
  from ._retry import RetryStrategy
flyte/_deploy.py CHANGED
@@ -128,6 +128,9 @@ async def apply(deployment: DeploymentPlan, copy_style: CopyFiles, dryrun: bool
128
128
  else:
129
129
  code_bundle = await build_code_bundle(from_dir=cfg.root_dir, dryrun=dryrun, copy_style=copy_style)
130
130
  deployment.version = code_bundle.computed_version
131
+ # TODO we should update the version to include the image cache digest and code bundle digest. This is
132
+ # to ensure that changes in image dependencies, cause an update to the deployment version.
133
+ # TODO Also hash the environment and tasks to ensure that changes in the environment or tasks
131
134
 
132
135
  sc = SerializationContext(
133
136
  project=cfg.project,
flyte/_initialize.py CHANGED
@@ -138,14 +138,13 @@ async def init(
138
138
  :param project: Optional project name (not used in this implementation)
139
139
  :param domain: Optional domain name (not used in this implementation)
140
140
  :param root_dir: Optional root directory from which to determine how to load files, and find paths to files.
141
+ This is useful for determining the root directory for the current project, and for locating files like config etc.
142
+ also use to determine all the code that needs to be copied to the remote location.
141
143
  defaults to the editable install directory if the cwd is in a Python editable install, else just the cwd.
142
144
  :param log_level: Optional logging level for the logger, default is set using the default initialization policies
143
145
  :param api_key: Optional API key for authentication
144
146
  :param endpoint: Optional API endpoint URL
145
147
  :param headless: Optional Whether to run in headless mode
146
- :param mode: Optional execution model (local, remote). Default is local. When local is used,
147
- the execution will be done locally. When remote is used, the execution will be sent to a remote server,
148
- In the remote case, the endpoint or api_key must be set.
149
148
  :param insecure_skip_verify: Whether to skip SSL certificate verification
150
149
  :param auth_client_config: Optional client configuration for authentication
151
150
  :param auth_type: The authentication type to use (Pkce, ClientSecret, ExternalCommand, DeviceFlow)
@@ -177,6 +176,9 @@ async def init(
177
176
 
178
177
  global _init_config # noqa: PLW0603
179
178
 
179
+ if endpoint and "://" not in endpoint:
180
+ endpoint = f"dns:///{endpoint}"
181
+
180
182
  with _init_lock:
181
183
  client = None
182
184
  if endpoint or api_key:
@@ -209,12 +211,16 @@ async def init(
209
211
 
210
212
 
211
213
  @syncify
212
- async def init_auto_from_config(path_or_config: str | Config | None = None) -> None:
214
+ async def init_from_config(path_or_config: str | Config | None = None, root_dir: Path | None = None) -> None:
213
215
  """
214
216
  Initialize the Flyte system using a configuration file or Config object. This method should be called before any
215
217
  other Flyte remote API methods are called. Thread-safe implementation.
216
218
 
217
219
  :param path_or_config: Path to the configuration file or Config object
220
+ :param root_dir: Optional root directory from which to determine how to load files, and find paths to
221
+ files like config etc. For example if one uses the copy-style=="all", it is essential to determine the
222
+ root directory for the current project. If not provided, it defaults to the editable install directory or
223
+ if not available, the current working directory.
218
224
  :return: None
219
225
  """
220
226
  import flyte.config as config
@@ -222,7 +228,10 @@ async def init_auto_from_config(path_or_config: str | Config | None = None) -> N
222
228
  cfg: config.Config
223
229
  if path_or_config is None or isinstance(path_or_config, str):
224
230
  # If a string is passed, treat it as a path to the config file
225
- cfg = config.auto(path_or_config)
231
+ if root_dir and path_or_config:
232
+ cfg = config.auto(str(root_dir / path_or_config))
233
+ else:
234
+ cfg = config.auto(path_or_config)
226
235
  else:
227
236
  # If a Config object is passed, use it directly
228
237
  cfg = path_or_config
@@ -241,6 +250,7 @@ async def init_auto_from_config(path_or_config: str | Config | None = None) -> N
241
250
  proxy_command=cfg.platform.proxy_command,
242
251
  client_id=cfg.platform.client_id,
243
252
  client_credentials_secret=cfg.platform.client_credentials_secret,
253
+ root_dir=root_dir,
244
254
  )
245
255
 
246
256
 
@@ -14,7 +14,7 @@ from flyte._logging import log, logger
14
14
  from flyte._protos.workflow import task_definition_pb2
15
15
  from flyte._task import TaskTemplate
16
16
  from flyte._utils.helpers import _selector_policy
17
- from flyte.models import ActionID, NativeInterface, RawDataPath
17
+ from flyte.models import ActionID, NativeInterface
18
18
 
19
19
  R = TypeVar("R")
20
20
 
@@ -86,7 +86,7 @@ class LocalController:
86
86
  sub_action_id, sub_action_output_path = convert.generate_sub_action_id_and_output_path(
87
87
  tctx, _task.name, serialized_inputs, 0
88
88
  )
89
- sub_action_raw_data_path = RawDataPath(path=sub_action_output_path)
89
+ sub_action_raw_data_path = tctx.raw_data_path
90
90
 
91
91
  out, err = await direct_dispatch(
92
92
  _task,
flyte/_run.py CHANGED
@@ -5,6 +5,7 @@ import pathlib
5
5
  import uuid
6
6
  from typing import TYPE_CHECKING, Any, Literal, Optional, Tuple, Union, cast
7
7
 
8
+ import flyte.errors
8
9
  from flyte.errors import InitializationError
9
10
  from flyte.models import ActionID, Checkpoints, CodeBundle, RawDataPath, SerializationContext, TaskContext
10
11
  from flyte.syncify import syncify
@@ -25,6 +26,7 @@ from ._tools import ipython_check
25
26
 
26
27
  if TYPE_CHECKING:
27
28
  from flyte.remote import Run
29
+ from flyte.remote._task import LazyEntity
28
30
 
29
31
  from ._code_bundle import CopyFiles
30
32
 
@@ -81,8 +83,11 @@ class _Runner:
81
83
  self._run_base_dir = run_base_dir or "/tmp/base"
82
84
 
83
85
  @requires_initialization
84
- async def _run_remote(self, obj: TaskTemplate[P, R], *args: P.args, **kwargs: P.kwargs) -> Run:
86
+ async def _run_remote(self, obj: TaskTemplate[P, R] | LazyEntity, *args: P.args, **kwargs: P.kwargs) -> Run:
87
+ import grpc
88
+
85
89
  from flyte.remote import Run
90
+ from flyte.remote._task import LazyEntity
86
91
 
87
92
  from ._code_bundle import build_code_bundle, build_pkl_bundle
88
93
  from ._deploy import build_images, plan_deploy
@@ -93,37 +98,47 @@ class _Runner:
93
98
 
94
99
  cfg = get_common_config()
95
100
 
96
- if obj.parent_env is None:
97
- raise ValueError("Task is not attached to an environment. Please attach the task to an environment.")
101
+ if isinstance(obj, LazyEntity):
102
+ task = await obj.fetch.aio()
103
+ task_spec = task.pb2.spec
104
+ inputs = await convert_from_native_to_inputs(task.interface, *args, **kwargs)
105
+ version = task.pb2.task_id.version
106
+ code_bundle = None
107
+ else:
108
+ if obj.parent_env is None:
109
+ raise ValueError("Task is not attached to an environment. Please attach the task to an environment")
98
110
 
99
- deploy_plan = plan_deploy(cast(Environment, obj.parent_env()))
100
- image_cache = await build_images(deploy_plan)
111
+ deploy_plan = plan_deploy(cast(Environment, obj.parent_env()))
112
+ image_cache = await build_images(deploy_plan)
101
113
 
102
- if self._interactive_mode:
103
- code_bundle = await build_pkl_bundle(
104
- obj, upload_to_controlplane=not self._dry_run, copy_bundle_to=self._copy_bundle_to
105
- )
106
- else:
107
- if self._copy_files != "none":
108
- code_bundle = await build_code_bundle(
109
- from_dir=cfg.root_dir, dryrun=self._dry_run, copy_bundle_to=self._copy_bundle_to
114
+ if self._interactive_mode:
115
+ code_bundle = await build_pkl_bundle(
116
+ obj, upload_to_controlplane=not self._dry_run, copy_bundle_to=self._copy_bundle_to
110
117
  )
111
118
  else:
112
- code_bundle = None
119
+ if self._copy_files != "none":
120
+ code_bundle = await build_code_bundle(
121
+ from_dir=cfg.root_dir,
122
+ dryrun=self._dry_run,
123
+ copy_bundle_to=self._copy_bundle_to,
124
+ copy_style=self._copy_files,
125
+ )
126
+ else:
127
+ code_bundle = None
113
128
 
114
- version = self._version or (
115
- code_bundle.computed_version if code_bundle and code_bundle.computed_version else None
116
- )
117
- if not version:
118
- raise ValueError("Version is required when running a task")
119
- s_ctx = SerializationContext(
120
- code_bundle=code_bundle,
121
- version=version,
122
- image_cache=image_cache,
123
- root_dir=cfg.root_dir,
124
- )
125
- task_spec = translate_task_to_wire(obj, s_ctx)
126
- inputs = await convert_from_native_to_inputs(obj.native_interface, *args, **kwargs)
129
+ version = self._version or (
130
+ code_bundle.computed_version if code_bundle and code_bundle.computed_version else None
131
+ )
132
+ if not version:
133
+ raise ValueError("Version is required when running a task")
134
+ s_ctx = SerializationContext(
135
+ code_bundle=code_bundle,
136
+ version=version,
137
+ image_cache=image_cache,
138
+ root_dir=cfg.root_dir,
139
+ )
140
+ task_spec = translate_task_to_wire(obj, s_ctx)
141
+ inputs = await convert_from_native_to_inputs(obj.native_interface, *args, **kwargs)
127
142
 
128
143
  if not self._dry_run:
129
144
  if get_client() is None:
@@ -160,15 +175,35 @@ class _Runner:
160
175
  if task_spec.task_template.id.version == "":
161
176
  task_spec.task_template.id.version = version
162
177
 
163
- resp = await get_client().run_service.CreateRun(
164
- run_service_pb2.CreateRunRequest(
165
- run_id=run_id,
166
- project_id=project_id,
167
- task_spec=task_spec,
168
- inputs=inputs.proto_inputs,
169
- ),
170
- )
171
- return Run(pb2=resp.run)
178
+ try:
179
+ resp = await get_client().run_service.CreateRun(
180
+ run_service_pb2.CreateRunRequest(
181
+ run_id=run_id,
182
+ project_id=project_id,
183
+ task_spec=task_spec,
184
+ inputs=inputs.proto_inputs,
185
+ ),
186
+ )
187
+ return Run(pb2=resp.run)
188
+ except grpc.aio.AioRpcError as e:
189
+ if e.code() == grpc.StatusCode.UNAVAILABLE:
190
+ raise flyte.errors.RuntimeSystemError(
191
+ "SystemUnavailableError",
192
+ "Flyte system is currently unavailable. check your configuration, or the service status.",
193
+ ) from e
194
+ elif e.code() == grpc.StatusCode.INVALID_ARGUMENT:
195
+ raise flyte.errors.RuntimeUserError("InvalidArgumentError", e.details())
196
+ elif e.code() == grpc.StatusCode.ALREADY_EXISTS:
197
+ # TODO maybe this should be a pass and return existing run?
198
+ raise flyte.errors.RuntimeUserError(
199
+ "RunAlreadyExistsError",
200
+ f"A run with the name '{self._name}' already exists. Please choose a different name.",
201
+ )
202
+ else:
203
+ raise flyte.errors.RuntimeSystemError(
204
+ "RunCreationError",
205
+ f"Failed to create run: {e.details()}",
206
+ ) from e
172
207
 
173
208
  class DryRun(Run):
174
209
  def __init__(self, _task_spec, _inputs, _code_bundle):
@@ -225,7 +260,10 @@ class _Runner:
225
260
  else:
226
261
  if self._copy_files != "none":
227
262
  code_bundle = await build_code_bundle(
228
- from_dir=cfg.root_dir, dryrun=self._dry_run, copy_bundle_to=self._copy_bundle_to
263
+ from_dir=cfg.root_dir,
264
+ dryrun=self._dry_run,
265
+ copy_bundle_to=self._copy_bundle_to,
266
+ copy_style=self._copy_files,
229
267
  )
230
268
  else:
231
269
  code_bundle = None
@@ -313,7 +351,7 @@ class _Runner:
313
351
  report=Report(name=action.name),
314
352
  mode="local",
315
353
  )
316
- async with ctx.replace_task_context(tctx):
354
+ with ctx.replace_task_context(tctx):
317
355
  # make the local version always runs on a different thread, returns a wrapped future.
318
356
  if obj._call_as_synchronous:
319
357
  fut = controller.submit_sync(obj, *args, **kwargs)
@@ -323,7 +361,9 @@ class _Runner:
323
361
  return await controller.submit(obj, *args, **kwargs)
324
362
 
325
363
  @syncify
326
- async def run(self, task: TaskTemplate[P, Union[R, Run]], *args: P.args, **kwargs: P.kwargs) -> Union[R, Run]:
364
+ async def run(
365
+ self, task: TaskTemplate[P, Union[R, Run]] | LazyEntity, *args: P.args, **kwargs: P.kwargs
366
+ ) -> Union[R, Run]:
327
367
  """
328
368
  Run an async `@env.task` or `TaskTemplate` instance. The existing async context will be used.
329
369
 
@@ -345,8 +385,13 @@ class _Runner:
345
385
  :param kwargs: Keyword arguments to pass to the Task
346
386
  :return: Run instance or the result of the task
347
387
  """
388
+ from flyte.remote._task import LazyEntity
389
+
390
+ if isinstance(task, LazyEntity) and self._mode != "remote":
391
+ raise ValueError("Remote task can only be run in remote mode.")
348
392
  if self._mode == "remote":
349
393
  return await self._run_remote(task, *args, **kwargs)
394
+ task = cast(TaskTemplate, task)
350
395
  if self._mode == "hybrid":
351
396
  return await self._run_hybrid(task, *args, **kwargs)
352
397
 
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 = '0.2.0b9'
21
- __version_tuple__ = version_tuple = (0, 2, 0, 'b9')
20
+ __version__ = version = '0.2.0b10'
21
+ __version_tuple__ = version_tuple = (0, 2, 0, 'b10')
flyte/cli/_common.py CHANGED
@@ -32,7 +32,7 @@ PROJECT_OPTION = click.Option(
32
32
  required=False,
33
33
  type=str,
34
34
  default=None,
35
- help="Project to operate on",
35
+ help="Project to which this command applies.",
36
36
  show_default=True,
37
37
  )
38
38
 
@@ -41,7 +41,7 @@ DOMAIN_OPTION = click.Option(
41
41
  required=False,
42
42
  type=str,
43
43
  default=None,
44
- help="Domain to operate on",
44
+ help="Domain to which this command applies.",
45
45
  show_default=True,
46
46
  )
47
47
 
@@ -51,7 +51,7 @@ DRY_RUN_OPTION = click.Option(
51
51
  type=bool,
52
52
  is_flag=True,
53
53
  default=False,
54
- help="Dry run, do not actually call the backend service.",
54
+ help="Dry run. Do not actually call the backend service.",
55
55
  show_default=True,
56
56
  )
57
57
 
@@ -105,7 +105,7 @@ class CLIConfig:
105
105
  updated_config = self.config.with_params(platform_cfg, task_cfg)
106
106
 
107
107
  logger.debug(f"Initializing CLI with config: {updated_config}")
108
- flyte.init_auto_from_config(updated_config)
108
+ flyte.init_from_config(updated_config)
109
109
 
110
110
 
111
111
  class InvokeBaseMixin:
flyte/cli/_create.py CHANGED
@@ -70,7 +70,7 @@ def secret(
70
70
  "--org",
71
71
  type=str,
72
72
  required=False,
73
- help="Organization to use, this will override the organization in the configusraion file.",
73
+ help="Organization to use. This will override the organization in the configuration file.",
74
74
  )
75
75
  @click.option(
76
76
  "-o",
flyte/cli/_params.py CHANGED
@@ -23,7 +23,7 @@ from mashumaro.codecs.json import JSONEncoder
23
23
 
24
24
  from flyte._logging import logger
25
25
  from flyte.io import Dir, File
26
- from flyte.io.pickle.transformer import FlytePickleTransformer
26
+ from flyte.types._pickle import FlytePickleTransformer
27
27
 
28
28
 
29
29
  class StructuredDataset:
flyte/cli/main.py CHANGED
@@ -90,7 +90,7 @@ def _verbosity_to_loglevel(verbosity: int) -> int | None:
90
90
  "config_file",
91
91
  required=False,
92
92
  type=click.Path(exists=True),
93
- help="Path to the configuration file to use. If not specified, the default configuration file is used."
93
+ help="Path to the configuration file to use. If not specified, the default configuration file is used.",
94
94
  )
95
95
  @click.rich_config(help_config=help_config)
96
96
  @click.pass_context
@@ -12,17 +12,14 @@ from flyte.models import NativeInterface, SerializationContext
12
12
  _PRIMARY_CONTAINER_NAME_FIELD = "primary_container_name"
13
13
 
14
14
 
15
- def _extract_command_key(cmd: str, **kwargs) -> Any:
15
+ def _extract_command_key(cmd: str, **kwargs) -> List[Any] | None:
16
16
  """
17
17
  Extract the key from the command using regex.
18
18
  """
19
19
  import re
20
20
 
21
- input_regex = r"^\{\{\s*\.inputs\.(.*?)\s*\}\}$"
22
- match = re.match(input_regex, cmd)
23
- if match:
24
- return match.group(1)
25
- return None
21
+ input_regex = r"\{\{\.inputs\.([a-zA-Z0-9_]+)\}\}"
22
+ return re.findall(input_regex, cmd)
26
23
 
27
24
 
28
25
  def _extract_path_command_key(cmd: str, input_data_dir: Optional[str]) -> Optional[str]:
@@ -70,7 +67,7 @@ class ContainerTask(TaskTemplate):
70
67
  input_data_dir: str | pathlib.Path = "/var/inputs",
71
68
  output_data_dir: str | pathlib.Path = "/var/outputs",
72
69
  metadata_format: MetadataFormat = "JSON",
73
- local_logs: bool = False,
70
+ local_logs: bool = True,
74
71
  **kwargs,
75
72
  ):
76
73
  super().__init__(
@@ -106,34 +103,33 @@ class ContainerTask(TaskTemplate):
106
103
  For FlyteFile and FlyteDirectory commands, e.g., "/var/inputs/inputs", we extract the key from strings that
107
104
  begin with the specified `input_data_dir`.
108
105
  """
109
- # from flytekit.types.directory import FlyteDirectory
110
- # from flytekit.types.file import FlyteFile
106
+ from flyte.io import Dir, File
111
107
 
112
108
  volume_binding: Dict[str, Dict[str, str]] = {}
113
109
  path_k = _extract_path_command_key(cmd, str(self._input_data_dir))
114
- k = path_k if path_k else _extract_command_key(cmd)
115
-
116
- if k:
117
- input_val = kwargs.get(k)
118
- # TODO: Add support file and directory transformer first
119
- # if type(input_val) in [FlyteFile, FlyteDirectory]:
120
- # if not path_k:
121
- # raise AssertionError(
122
- # "FlyteFile and FlyteDirectory commands should not use the template syntax like this:
123
- # {{.inputs.infile}}\n"
124
- # "Please use a path-like syntax, such as: /var/inputs/infile.\n"
125
- # "This requirement is due to how Flyte Propeller processes template syntax inputs."
126
- # )
127
- # local_flyte_file_or_dir_path = str(input_val)
128
- # remote_flyte_file_or_dir_path = os.path.join(self._input_data_dir, k) # type: ignore
129
- # volume_binding[local_flyte_file_or_dir_path] = {
130
- # "bind": remote_flyte_file_or_dir_path,
131
- # "mode": "rw",
132
- # }
133
- # command = remote_flyte_file_or_dir_path
134
- command = str(input_val)
135
- else:
136
- command = cmd
110
+ keys = path_k if path_k else _extract_command_key(cmd)
111
+
112
+ if keys:
113
+ for k in keys:
114
+ input_val = kwargs.get(k)
115
+ # TODO: Add support file and directory transformer first
116
+ if type(input_val) in [File, Dir]:
117
+ if not path_k:
118
+ raise AssertionError(
119
+ "File and Directory commands should not use the template syntax "
120
+ "like this: {{.inputs.infile}}\n"
121
+ "Please use a path-like syntax, such as: /var/inputs/infile.\n"
122
+ "This requirement is due to how Flyte Propeller processes template syntax inputs."
123
+ )
124
+ local_flyte_file_or_dir_path = str(input_val)
125
+ remote_flyte_file_or_dir_path = os.path.join(self._input_data_dir, k) # type: ignore
126
+ volume_binding[local_flyte_file_or_dir_path] = {
127
+ "bind": remote_flyte_file_or_dir_path,
128
+ "mode": "rw",
129
+ }
130
+ command = remote_flyte_file_or_dir_path
131
+ else:
132
+ command = cmd
137
133
 
138
134
  return command, volume_binding
139
135
 
@@ -235,6 +231,7 @@ class ContainerTask(TaskTemplate):
235
231
  raise AssertionError(f"Only Image objects are supported, not strings. Got {self._image} instead.")
236
232
  uri = self._image.uri
237
233
  self._pull_image_if_not_exists(client, uri)
234
+ print(f"Command: {commands!r}")
238
235
 
239
236
  container = client.containers.run(uri, command=commands, remove=True, volumes=volume_bindings, detach=True)
240
237
 
flyte/io/__init__.py CHANGED
@@ -3,9 +3,25 @@
3
3
 
4
4
  This package contains additional data types beyond the primitive data types in python to abstract data flow
5
5
  of large datasets in Union.
6
+
6
7
  """
7
8
 
8
- __all__ = ["Dir", "File"]
9
+ __all__ = [
10
+ "Dir",
11
+ "File",
12
+ "StructuredDataset",
13
+ "StructuredDatasetDecoder",
14
+ "StructuredDatasetEncoder",
15
+ "StructuredDatasetTransformerEngine",
16
+ "lazy_import_structured_dataset_handler",
17
+ ]
9
18
 
10
19
  from ._dir import Dir
11
20
  from ._file import File
21
+ from ._structured_dataset import (
22
+ StructuredDataset,
23
+ StructuredDatasetDecoder,
24
+ StructuredDatasetEncoder,
25
+ StructuredDatasetTransformerEngine,
26
+ lazy_import_structured_dataset_handler,
27
+ )
flyte/io/_file.py CHANGED
@@ -232,6 +232,8 @@ class File(BaseModel, Generic[T], SerializableType):
232
232
  # This code is broadly similar to what storage.get_stream does, but without actually reading from the stream
233
233
  file_handle = None
234
234
  try:
235
+ if "b" not in mode:
236
+ raise ValueError("Mode must include 'b' for binary access, when using remote files.")
235
237
  if isinstance(fs, AsyncFileSystem):
236
238
  file_handle = await fs.open_async(self.path, mode)
237
239
  yield file_handle
@@ -9,7 +9,7 @@ from fsspec.core import split_protocol, strip_protocol
9
9
  import flyte.storage as storage
10
10
  from flyte._logging import logger
11
11
  from flyte._utils import lazy_module
12
- from flyte.io.structured_dataset.structured_dataset import (
12
+ from flyte.io._structured_dataset.structured_dataset import (
13
13
  CSV,
14
14
  PARQUET,
15
15
  StructuredDataset,
@@ -168,7 +168,7 @@ class StructuredDataset(SerializableType, DataClassJSONMixin):
168
168
  return self._literal_sd
169
169
 
170
170
  def open(self, dataframe_type: Type[DF]):
171
- from flyte.io.structured_dataset import lazy_import_structured_dataset_handler
171
+ from flyte.io._structured_dataset import lazy_import_structured_dataset_handler
172
172
 
173
173
  """
174
174
  Load the handler if needed. For the use case like:
flyte/models.py CHANGED
@@ -95,6 +95,7 @@ class RawDataPath:
95
95
  # Create a temporary directory for data storage
96
96
  p = tempfile.mkdtemp()
97
97
  logger.debug(f"Creating temporary directory for data storage: {p}")
98
+ pathlib.Path(p).mkdir(parents=True, exist_ok=True)
98
99
  return RawDataPath(path=p)
99
100
  case str():
100
101
  return RawDataPath(path=local_folder)
flyte/types/__init__.py CHANGED
@@ -1,9 +1,32 @@
1
+ """
2
+ # Flyte Type System
3
+
4
+ The Flyte type system provides a way to define, transform, and manipulate types in Flyte workflows.
5
+ Since the data flowing through Flyte has to often cross process, container and langauge boundaries, the type system
6
+ is designed to be serializable to a universal format that can be understood across different environments. This
7
+ universal format is based on Protocol Buffers. The types are called LiteralTypes and the runtime
8
+ representation of data is called Literals.
9
+
10
+ The type system includes:
11
+ - **TypeEngine**: The core engine that manages type transformations and serialization. This is the main entry point for
12
+ for all the internal type transformations and serialization logic.
13
+ - **TypeTransformer**: A class that defines how to transform one type to another. This is extensible
14
+ allowing users to define custom types and transformations.
15
+ - **Renderable**: An interface for types that can be rendered as HTML, that can be outputted to a flyte.report.
16
+
17
+ It is always possible to bypass the type system and use the `FlytePickle` type to serialize any python object
18
+ into a pickle format. The pickle format is not human-readable, but can be passed between flyte tasks that are
19
+ written in python. The Pickled objects cannot be represented in the UI, and may be in-efficient for large datasets.
20
+ """
21
+
1
22
  from ._interface import guess_interface
23
+ from ._pickle import FlytePickle
2
24
  from ._renderer import Renderable
3
25
  from ._string_literals import literal_string_repr
4
26
  from ._type_engine import TypeEngine, TypeTransformer, TypeTransformerFailedError
5
27
 
6
28
  __all__ = [
29
+ "FlytePickle",
7
30
  "Renderable",
8
31
  "TypeEngine",
9
32
  "TypeTransformer",
@@ -8,7 +8,8 @@ import cloudpickle
8
8
  from flyteidl.core import literals_pb2, types_pb2
9
9
 
10
10
  import flyte.storage as storage
11
- from flyte.types import TypeEngine, TypeTransformer
11
+
12
+ from ._type_engine import TypeEngine, TypeTransformer
12
13
 
13
14
  T = typing.TypeVar("T")
14
15
 
@@ -1008,7 +1008,7 @@ class TypeEngine(typing.Generic[T]):
1008
1008
  return cls._DATACLASS_TRANSFORMER
1009
1009
 
1010
1010
  display_pickle_warning(str(python_type))
1011
- from flyte.io.pickle.transformer import FlytePickleTransformer
1011
+ from flyte.types._pickle import FlytePickleTransformer
1012
1012
 
1013
1013
  return FlytePickleTransformer()
1014
1014
 
@@ -1021,7 +1021,7 @@ class TypeEngine(typing.Generic[T]):
1021
1021
  # Avoid a race condition where concurrent threads may exit lazy_import_transformers before the transformers
1022
1022
  # have been imported. This could be implemented without a lock if you assume python assignments are atomic
1023
1023
  # and re-registering transformers is acceptable, but I decided to play it safe.
1024
- from flyte.io.structured_dataset import lazy_import_structured_dataset_handler
1024
+ from flyte.io import lazy_import_structured_dataset_handler
1025
1025
 
1026
1026
  # todo: bring in extras transformers (pytorch, etc.)
1027
1027
  lazy_import_structured_dataset_handler()
@@ -1657,7 +1657,7 @@ class DictTransformer(TypeTransformer[dict]):
1657
1657
  Converts a Python dictionary to a Flyte-specific ``Literal`` using MessagePack encoding.
1658
1658
  Falls back to Pickle if encoding fails and `allow_pickle` is True.
1659
1659
  """
1660
- from flyte.io.pickle.transformer import FlytePickle
1660
+ from flyte.types._pickle import FlytePickle
1661
1661
 
1662
1662
  try:
1663
1663
  # Handle dictionaries with non-string keys (e.g., Dict[int, Type])
@@ -1763,7 +1763,7 @@ class DictTransformer(TypeTransformer[dict]):
1763
1763
  # pr: han-ru is this part still necessary?
1764
1764
  if lv and lv.HasField("scalar") and lv.scalar.HasField("generic"):
1765
1765
  if lv.metadata and lv.metadata.get("format", None) == "pickle":
1766
- from flyte.io.pickle.transformer import FlytePickle
1766
+ from flyte.types._pickle import FlytePickle
1767
1767
 
1768
1768
  uri = json.loads(_json_format.MessageToJson(lv.scalar.generic)).get("pickle_file")
1769
1769
  return await FlytePickle.from_pickle(uri)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flyte
3
- Version: 0.2.0b9
3
+ Version: 0.2.0b10
4
4
  Summary: Add your description here
5
5
  Author-email: Ketan Umare <kumare3@users.noreply.github.com>
6
6
  Requires-Python: >=3.10
@@ -61,7 +61,6 @@ Note that the `--follow` command is optional. Use this to stream updates to the
61
61
  3. look at examples/... for various examples.
62
62
  4. For a single script recommend using uv run scripts with metadata headers.
63
63
 
64
-
65
64
  ```python
66
65
  import flyte
67
66
 
@@ -80,14 +79,14 @@ async def say_hello_nested(data: str) -> str:
80
79
 
81
80
  if __name__ == "__main__":
82
81
  import asyncio
83
-
82
+
84
83
  # to run pure python - the SDK is not invoked at all
85
84
  asyncio.run(say_hello_nested("test"))
86
-
85
+
87
86
  # To run locally, but run through type system etc
88
87
  flyte.init()
89
88
  flyte.run(say_hello_nested, "World")
90
-
89
+
91
90
  # To run remote
92
91
  flyte.init(endpoint="dns:///localhost:8090", insecure=True)
93
92
  flyte.run(say_hello_nested, "World")
@@ -95,7 +94,7 @@ if __name__ == "__main__":
95
94
  flyte.with_runcontext(mode="local").run(...) # this will run locally only
96
95
 
97
96
  # To run remote with a config
98
- flyte.init_auto_from_config("config.yaml")
97
+ flyte.init_from_config("config.yaml")
99
98
  ```
100
99
 
101
100
  # CLI
@@ -1,30 +1,30 @@
1
- flyte/__init__.py,sha256=-gRsCKXTW5kOSQPq-MLdJjiPDXO1bjxFssa_7_RnywU,1425
1
+ flyte/__init__.py,sha256=QzKbvypcEAJCF7g8oqpIZhpQfYOsqz6hEvT2OwK0IAc,1415
2
2
  flyte/_build.py,sha256=MkgfLAPeL56YeVrGRNZUCZgbwzlEzVP3wLbl5Qru4yk,578
3
3
  flyte/_context.py,sha256=K0-TCt-_pHOoE5Xni87_8uIe2vCBOhfNQEtjGT4Hu4k,5239
4
- flyte/_deploy.py,sha256=hHZKLU3U7t1ZF_8x6LykkPu_KSDyaHL3f2WzyjLj9BQ,7723
4
+ flyte/_deploy.py,sha256=NApDDNQRGauhZP_eBYUnVSQilooSLpmmHQNhqNa5jmk,8034
5
5
  flyte/_doc.py,sha256=_OPCf3t_git6UT7kSJISFaWO9cfNzJhhoe6JjVdyCJo,706
6
6
  flyte/_docstring.py,sha256=SsG0Ab_YMAwy2ABJlEo3eBKlyC3kwPdnDJ1FIms-ZBQ,1127
7
7
  flyte/_environment.py,sha256=BkChtdVhWB3SwMSvetDZ-KiNBgRFlAXgq69PHT4zyG0,2942
8
8
  flyte/_group.py,sha256=7o1j16sZyUmYB50mOiq1ui4TBAKhRpDqLakV8Ya1kw4,803
9
9
  flyte/_hash.py,sha256=Of_Zl_DzzzF2jp4ZsLm-3o-xJFCCJ8_GubmLI1htx78,504
10
10
  flyte/_image.py,sha256=NeBvjCdwFAVGd666ufi1q-YOvhwdTEzAeJl5YBfl0bI,29043
11
- flyte/_initialize.py,sha256=ihTIvoMHs67UKbtFLR_zy9M1e7OK26ywoc_yMfLYwMw,16499
11
+ flyte/_initialize.py,sha256=N7q2n22iHSWmOB86ZLfgMd1En_XU6dz3OusB-t5nUwg,17073
12
12
  flyte/_interface.py,sha256=MP5o_qpIwfBNtAc7zo_cLSjMugsPyanuO6EgUSk4fBE,3644
13
13
  flyte/_logging.py,sha256=FQvF3W1kkFypbARcOQ7WZVXO0XJasXp8EhozF6E6-aQ,3379
14
14
  flyte/_map.py,sha256=efPd8O-JKUg1OY3_MzU3KGbhsGYDVRNBwWr0ceNIXhQ,7444
15
15
  flyte/_resources.py,sha256=UOLyEVhdxolvrHhddiBbYdJuE1RkM_l7xeS9G1abe6M,7583
16
16
  flyte/_retry.py,sha256=rfLv0MvWxzPByKESTglEmjPsytEAKiIvvmzlJxXwsfE,941
17
17
  flyte/_reusable_environment.py,sha256=P4FBATVKAYcIKpdFN98sI8acPyKy8eIGx6V0kUb9YdM,1289
18
- flyte/_run.py,sha256=gMcQ6km5jm34BAfubJkp7SChTACblBH4M6m8FfZQeP8,17723
18
+ flyte/_run.py,sha256=ePlFrABDR0ud_qxY55Nk4eATDialHGHsxNdTiVWYQkw,19919
19
19
  flyte/_secret.py,sha256=SqIHs6mi8hEkIIBZe3bI9jJsPt65Mt6dV5uh9_op1ME,2392
20
20
  flyte/_task.py,sha256=Gq34LbELz5dIc4dvYjgRXyzAnBvs8ED3iU1FWVuAFRE,18391
21
21
  flyte/_task_environment.py,sha256=J1LFH9Zz1nPhlsrc_rYny1SS3QC1b55X7tRYoTG7Vk4,6815
22
22
  flyte/_timeout.py,sha256=zx5sFcbYmjJAJbZWSGzzX-BpC9HC7Jfs35T7vVhKwkk,1571
23
23
  flyte/_tools.py,sha256=JewkQZBR_M85tS6QY8e4xXue75jbOE48nID4ZHnc9jY,632
24
24
  flyte/_trace.py,sha256=7OQtQNosIlycTwaMjdc3GW4h3T3N0bYTsY6og4clPl8,5234
25
- flyte/_version.py,sha256=6yaYOwx6af-xfDGkZHMO3lXrEv1xpPMopHstyivLlUQ,519
25
+ flyte/_version.py,sha256=mlXpANdUuYfy0QPXXxhosF8MwMVypx0OlvhibSGO2P8,521
26
26
  flyte/errors.py,sha256=m2JUNqLC6anVW6UiDK_ihuA06q_Hkw1mIUMDskb2OW8,4289
27
- flyte/models.py,sha256=8ZqWar7n-u9ZYyxct88T_0-41LXjSjstoQvDfiDjp64,12841
27
+ flyte/models.py,sha256=A85HnTLqInJiMmQKhpl2IXb2Uh6_46tdRrwW2TTzD9o,12908
28
28
  flyte/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  flyte/_bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  flyte/_bin/runtime.py,sha256=Q1vajoQ913KUfCQSP0u8Qoj-AYgfvU2i2wI19ydqnDw,4849
@@ -39,7 +39,7 @@ flyte/_code_bundle/_utils.py,sha256=b0s3ZVKSRwaa_2CMTCqt2iRrUvTTW3FmlyqCD9k5BS0,
39
39
  flyte/_code_bundle/bundle.py,sha256=8T0gcXck6dmg-8L2-0G3B2iNjC-Xwydu806iyKneMMY,8789
40
40
  flyte/_internal/__init__.py,sha256=vjXgGzAAjy609YFkAy9_RVPuUlslsHSJBXCLNTVnqOY,136
41
41
  flyte/_internal/controllers/__init__.py,sha256=5CBnS9lb1VFMzZuRXUiaPhlN3G9qh7Aq9kTwxW5hsRw,4301
42
- flyte/_internal/controllers/_local_controller.py,sha256=Nsqy1Grrw6JggKwiQn7lsChjL2gT5f-bHyaqrT2vjnA,7111
42
+ flyte/_internal/controllers/_local_controller.py,sha256=LDwVxwm365L6-OEpwo5FcWe6abxK8L1231Hf54pYLZ8,7076
43
43
  flyte/_internal/controllers/_trace.py,sha256=Ga2b65sn9q2IoOwHBZV2inMYyO6-CSDwzN7E3pDxsEI,1126
44
44
  flyte/_internal/controllers/remote/__init__.py,sha256=9_azH1eHLqY6VULpDugXi7Kf1kK1ODqEnsQ_3wM6IqU,1919
45
45
  flyte/_internal/controllers/remote/_action.py,sha256=w6vE1vPz1BwxvwfotDWjTNbDXfGEPrRBA8N3UVQ6P0w,4905
@@ -137,31 +137,28 @@ flyte/_utils/lazy_module.py,sha256=fvXPjvZLzCfcI8Vzs4pKedUDdY0U_RQ1ZVrp9b8qBQY,1
137
137
  flyte/_utils/uv_script_parser.py,sha256=PxqD8lSMi6xv0uDd1s8LKB2IPZr4ttZJCUweqlyMTKk,1483
138
138
  flyte/cli/__init__.py,sha256=M02O-UGqQlA8JJ_jyWRiwQhTNc5CJJ7x9J7fNxTxBT0,52
139
139
  flyte/cli/_abort.py,sha256=lTftDmVXEIrFz1XAASCqWbXQEQDqRdTCJqY7izk2USI,593
140
- flyte/cli/_common.py,sha256=UkhKgjoti-5iLGczUkcwN5QmhkWk5uFsoL9C2gHoiCo,10766
141
- flyte/cli/_create.py,sha256=fPyme_o8-Qf1Cy7DSspXgwYcBDO4G8nPmoUpSDprfz4,4087
140
+ flyte/cli/_common.py,sha256=dwZ5OPz3x8-8uVtMiV1HpqA1MaoBJZH8yBON-axFSZs,10795
141
+ flyte/cli/_create.py,sha256=DFdNemGqNVdlgDxcIqMmZJBF1zPtAHeWO1XeT2caEPs,4087
142
142
  flyte/cli/_delete.py,sha256=qq5A9d6vXdYvYz-SECXiC6LU5rAzahNTZKiKacOtcZ4,545
143
143
  flyte/cli/_deploy.py,sha256=owGe_RVwC73p3dOPWYSo442OVuZyagF8LKTvC57xubQ,4466
144
144
  flyte/cli/_gen.py,sha256=vlE5l8UR1zz4RSdaRyUfYFvGR0TLxGcTYcP4dhA3Pvg,5458
145
145
  flyte/cli/_get.py,sha256=Pl9nHVHzRQT8IG3k_VAMJ2Xvaq9URsovm96op_153os,9843
146
- flyte/cli/_params.py,sha256=X3GpuftXmtfIsYQ7vBilD4kmlkXTc7_AxpaxohRjSuY,19458
146
+ flyte/cli/_params.py,sha256=fs6fNBRGYXZMmjjcySi3U1O_pQNgCnW9ko89KCcS6nU,19450
147
147
  flyte/cli/_run.py,sha256=zRu4DTO__BVsLgpSLUbYR1Twvzc_2zivUhcviymCRf0,7884
148
- flyte/cli/main.py,sha256=V_gXj3YDr43igWQtugcPt8CbJincoTE9g1uG52JdHgk,4449
148
+ flyte/cli/main.py,sha256=PJUQ6slm1CcwIfeP6pbJKlPuyOqXxb_K8PjnZb8sbhw,4450
149
149
  flyte/config/__init__.py,sha256=MiwEYK5Iv7MRR22z61nzbsbvZ9Q6MdmAU_g9If1Pmb8,144
150
150
  flyte/config/_config.py,sha256=QE3T0W8xOULjJaqDMdMF90f9gFVjGR6h8QPOLsyqjYw,9831
151
151
  flyte/config/_internal.py,sha256=Bj0uzn3PYgxKbzM-q2GKXxp7Y6cyzhPzUB-Y2i6cQKo,2836
152
152
  flyte/config/_reader.py,sha256=c16jm0_IYxwEAjXENtllLeO_sT5Eg2RNLG4UjnAv_x4,7157
153
153
  flyte/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
154
  flyte/extras/__init__.py,sha256=FhB0uK7H1Yo5De9vOuF7UGnezTKncj3u2Wo5uQdWN0g,74
155
- flyte/extras/_container.py,sha256=R7tMIy2EuprEGowYhjPMwnszSutgWIzAeKPeXNc2nmI,11255
156
- flyte/io/__init__.py,sha256=e2wHVEoZ84TGOtOPrtTg6hJpeuxiYI56Sg011yq6nUQ,236
157
- flyte/io/_dataframe.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
155
+ flyte/extras/_container.py,sha256=kMrYPmfnDFxPmFhI9cZeoBKzQ96jMCO4l4FpwV1b0PA,11202
156
+ flyte/io/__init__.py,sha256=F7hlpin_1JJjsdFZSn7_jQgltPzsjETX1DCYGz-ELqI,629
158
157
  flyte/io/_dir.py,sha256=rih9CY1YjNX05bcAu5LG62Xoyij5GXAlv7jLyVF0je8,15310
159
- flyte/io/_file.py,sha256=eL48TwJjPDyN9tPG9Hfs22P4qqc-GBsTm3E5e-JmfdY,15430
160
- flyte/io/pickle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
- flyte/io/pickle/transformer.py,sha256=b7vAxLHgi-HMHy3vOG0sGMeDf6LimFmU_jAcvNOZI1o,4047
162
- flyte/io/structured_dataset/__init__.py,sha256=69ixVV9OEXiLiQ6SV2S8tEC7dVQe7YTt9NV1OotlG64,4524
163
- flyte/io/structured_dataset/basic_dfs.py,sha256=lrcALNYke_gSmmAhIiUN5afqhA-W5bSuKJUCoW6S4CE,8223
164
- flyte/io/structured_dataset/structured_dataset.py,sha256=DrRIHA3zbkfLBekw3pPTF_SM0Rbn_BGBp1YJPyd9zY0,52644
158
+ flyte/io/_file.py,sha256=kp5700SKPy5htmMhm4hE2ybb99Ykny1b0Kwm3huCWXs,15572
159
+ flyte/io/_structured_dataset/__init__.py,sha256=69ixVV9OEXiLiQ6SV2S8tEC7dVQe7YTt9NV1OotlG64,4524
160
+ flyte/io/_structured_dataset/basic_dfs.py,sha256=77aYFrFigPC7cjM6UjCbU26REtXmwIBBapFN6KGYOO8,8224
161
+ flyte/io/_structured_dataset/structured_dataset.py,sha256=ddRjz36RhNxIy0gakzdLStBzoo4cAOgXbNqiqt5YhMI,52645
165
162
  flyte/remote/__init__.py,sha256=zBWV88VF-L8430xVrOyk07EmLsOKhOUMVBsqFUDtO6Q,565
166
163
  flyte/remote/_console.py,sha256=avmELJPx8nQMAVPrHlh6jEIRPjrMwFpdZjJsWOOa9rE,660
167
164
  flyte/remote/_data.py,sha256=DPK85gB6M71RjxqIh1Q5PdZ9xcJ0m1w_3cT2lAO0r7w,5795
@@ -201,14 +198,15 @@ flyte/storage/_storage.py,sha256=mBy7MKII2M1UTVm_EUUDwVb7uT1_AOPzQr2wCJ-fgW0,987
201
198
  flyte/storage/_utils.py,sha256=8oLCM-7D7JyJhzUi1_Q1NFx8GBUPRfou0T_5tPBmPbE,309
202
199
  flyte/syncify/__init__.py,sha256=WgTk-v-SntULnI55CsVy71cxGJ9Q6pxpTrhbPFuouJ0,1974
203
200
  flyte/syncify/_api.py,sha256=x37A7OtUS0WVUB1wkoN0i5iu6HQPDYlPc1uwzVFOrfM,10927
204
- flyte/types/__init__.py,sha256=xMIYOolT3Vq0qXy7unw90IVdYztdMDpKg0oG0XAPC9o,364
201
+ flyte/types/__init__.py,sha256=9310PRtVrwJePwEPeoUO0HPyIkgaja7-Dar_QlE_MUI,1745
205
202
  flyte/types/_interface.py,sha256=mY7mb8v2hJPGk7AU99gdOWl4_jArA1VFtjYGlE31SK0,953
203
+ flyte/types/_pickle.py,sha256=PjdR66OTDMZ3OYq6GvM_Ua0cIo5t2XQaIjmpJ9xo4Ys,4050
206
204
  flyte/types/_renderer.py,sha256=ygcCo5l60lHufyQISFddZfWwLlQ8kJAKxUT_XnR_6dY,4818
207
205
  flyte/types/_string_literals.py,sha256=NlG1xV8RSA-sZ-n-IFQCAsdB6jXJOAKkHWtnopxVVDk,4231
208
- flyte/types/_type_engine.py,sha256=QxyoDWRG_whfLCz88YqEVVoTTnca0FZv9eHeLLT0_-s,93645
206
+ flyte/types/_type_engine.py,sha256=3PiRPYtE0UmEpTfwwcFWaiVmG1XOfXQl3Pj4v2zClNk,93602
209
207
  flyte/types/_utils.py,sha256=pbts9E1_2LTdLygAY0UYTLYJ8AsN3BZyviSXvrtcutc,2626
210
- flyte-0.2.0b9.dist-info/METADATA,sha256=4iN_NmCj__wWn6iVgYBAaYotKg6posAg0V34TzisufQ,4828
211
- flyte-0.2.0b9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
212
- flyte-0.2.0b9.dist-info/entry_points.txt,sha256=MIq2z5dBurdCJfpXfMKzgBv7sJOakKRYxr8G0cMiTrg,75
213
- flyte-0.2.0b9.dist-info/top_level.txt,sha256=7dkyFbikvA12LEZEqawx8oDG1CMod6hTliPj7iWzgYo,6
214
- flyte-0.2.0b9.dist-info/RECORD,,
208
+ flyte-0.2.0b10.dist-info/METADATA,sha256=XALFwwiy3iCSCTVj80DPGhfL8gfPIVUOsyAMmbpNzac,4811
209
+ flyte-0.2.0b10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
210
+ flyte-0.2.0b10.dist-info/entry_points.txt,sha256=MIq2z5dBurdCJfpXfMKzgBv7sJOakKRYxr8G0cMiTrg,75
211
+ flyte-0.2.0b10.dist-info/top_level.txt,sha256=7dkyFbikvA12LEZEqawx8oDG1CMod6hTliPj7iWzgYo,6
212
+ flyte-0.2.0b10.dist-info/RECORD,,
flyte/io/_dataframe.py DELETED
File without changes
File without changes