flyte 2.0.0b32__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.

Files changed (204) hide show
  1. flyte/__init__.py +108 -0
  2. flyte/_bin/__init__.py +0 -0
  3. flyte/_bin/debug.py +38 -0
  4. flyte/_bin/runtime.py +195 -0
  5. flyte/_bin/serve.py +178 -0
  6. flyte/_build.py +26 -0
  7. flyte/_cache/__init__.py +12 -0
  8. flyte/_cache/cache.py +147 -0
  9. flyte/_cache/defaults.py +9 -0
  10. flyte/_cache/local_cache.py +216 -0
  11. flyte/_cache/policy_function_body.py +42 -0
  12. flyte/_code_bundle/__init__.py +8 -0
  13. flyte/_code_bundle/_ignore.py +121 -0
  14. flyte/_code_bundle/_packaging.py +218 -0
  15. flyte/_code_bundle/_utils.py +347 -0
  16. flyte/_code_bundle/bundle.py +266 -0
  17. flyte/_constants.py +1 -0
  18. flyte/_context.py +155 -0
  19. flyte/_custom_context.py +73 -0
  20. flyte/_debug/__init__.py +0 -0
  21. flyte/_debug/constants.py +38 -0
  22. flyte/_debug/utils.py +17 -0
  23. flyte/_debug/vscode.py +307 -0
  24. flyte/_deploy.py +408 -0
  25. flyte/_deployer.py +109 -0
  26. flyte/_doc.py +29 -0
  27. flyte/_docstring.py +32 -0
  28. flyte/_environment.py +122 -0
  29. flyte/_excepthook.py +37 -0
  30. flyte/_group.py +32 -0
  31. flyte/_hash.py +8 -0
  32. flyte/_image.py +1055 -0
  33. flyte/_initialize.py +628 -0
  34. flyte/_interface.py +119 -0
  35. flyte/_internal/__init__.py +3 -0
  36. flyte/_internal/controllers/__init__.py +129 -0
  37. flyte/_internal/controllers/_local_controller.py +239 -0
  38. flyte/_internal/controllers/_trace.py +48 -0
  39. flyte/_internal/controllers/remote/__init__.py +58 -0
  40. flyte/_internal/controllers/remote/_action.py +211 -0
  41. flyte/_internal/controllers/remote/_client.py +47 -0
  42. flyte/_internal/controllers/remote/_controller.py +583 -0
  43. flyte/_internal/controllers/remote/_core.py +465 -0
  44. flyte/_internal/controllers/remote/_informer.py +381 -0
  45. flyte/_internal/controllers/remote/_service_protocol.py +50 -0
  46. flyte/_internal/imagebuild/__init__.py +3 -0
  47. flyte/_internal/imagebuild/docker_builder.py +706 -0
  48. flyte/_internal/imagebuild/image_builder.py +277 -0
  49. flyte/_internal/imagebuild/remote_builder.py +386 -0
  50. flyte/_internal/imagebuild/utils.py +78 -0
  51. flyte/_internal/resolvers/__init__.py +0 -0
  52. flyte/_internal/resolvers/_task_module.py +21 -0
  53. flyte/_internal/resolvers/common.py +31 -0
  54. flyte/_internal/resolvers/default.py +28 -0
  55. flyte/_internal/runtime/__init__.py +0 -0
  56. flyte/_internal/runtime/convert.py +486 -0
  57. flyte/_internal/runtime/entrypoints.py +204 -0
  58. flyte/_internal/runtime/io.py +188 -0
  59. flyte/_internal/runtime/resources_serde.py +152 -0
  60. flyte/_internal/runtime/reuse.py +125 -0
  61. flyte/_internal/runtime/rusty.py +193 -0
  62. flyte/_internal/runtime/task_serde.py +362 -0
  63. flyte/_internal/runtime/taskrunner.py +209 -0
  64. flyte/_internal/runtime/trigger_serde.py +160 -0
  65. flyte/_internal/runtime/types_serde.py +54 -0
  66. flyte/_keyring/__init__.py +0 -0
  67. flyte/_keyring/file.py +115 -0
  68. flyte/_logging.py +300 -0
  69. flyte/_map.py +312 -0
  70. flyte/_module.py +72 -0
  71. flyte/_pod.py +30 -0
  72. flyte/_resources.py +473 -0
  73. flyte/_retry.py +32 -0
  74. flyte/_reusable_environment.py +102 -0
  75. flyte/_run.py +724 -0
  76. flyte/_secret.py +96 -0
  77. flyte/_task.py +550 -0
  78. flyte/_task_environment.py +316 -0
  79. flyte/_task_plugins.py +47 -0
  80. flyte/_timeout.py +47 -0
  81. flyte/_tools.py +27 -0
  82. flyte/_trace.py +119 -0
  83. flyte/_trigger.py +1000 -0
  84. flyte/_utils/__init__.py +30 -0
  85. flyte/_utils/asyn.py +121 -0
  86. flyte/_utils/async_cache.py +139 -0
  87. flyte/_utils/coro_management.py +27 -0
  88. flyte/_utils/docker_credentials.py +173 -0
  89. flyte/_utils/file_handling.py +72 -0
  90. flyte/_utils/helpers.py +134 -0
  91. flyte/_utils/lazy_module.py +54 -0
  92. flyte/_utils/module_loader.py +104 -0
  93. flyte/_utils/org_discovery.py +57 -0
  94. flyte/_utils/uv_script_parser.py +49 -0
  95. flyte/_version.py +34 -0
  96. flyte/app/__init__.py +22 -0
  97. flyte/app/_app_environment.py +157 -0
  98. flyte/app/_deploy.py +125 -0
  99. flyte/app/_input.py +160 -0
  100. flyte/app/_runtime/__init__.py +3 -0
  101. flyte/app/_runtime/app_serde.py +347 -0
  102. flyte/app/_types.py +101 -0
  103. flyte/app/extras/__init__.py +3 -0
  104. flyte/app/extras/_fastapi.py +151 -0
  105. flyte/cli/__init__.py +12 -0
  106. flyte/cli/_abort.py +28 -0
  107. flyte/cli/_build.py +114 -0
  108. flyte/cli/_common.py +468 -0
  109. flyte/cli/_create.py +371 -0
  110. flyte/cli/_delete.py +45 -0
  111. flyte/cli/_deploy.py +293 -0
  112. flyte/cli/_gen.py +176 -0
  113. flyte/cli/_get.py +370 -0
  114. flyte/cli/_option.py +33 -0
  115. flyte/cli/_params.py +554 -0
  116. flyte/cli/_plugins.py +209 -0
  117. flyte/cli/_run.py +597 -0
  118. flyte/cli/_serve.py +64 -0
  119. flyte/cli/_update.py +37 -0
  120. flyte/cli/_user.py +17 -0
  121. flyte/cli/main.py +221 -0
  122. flyte/config/__init__.py +3 -0
  123. flyte/config/_config.py +248 -0
  124. flyte/config/_internal.py +73 -0
  125. flyte/config/_reader.py +225 -0
  126. flyte/connectors/__init__.py +11 -0
  127. flyte/connectors/_connector.py +270 -0
  128. flyte/connectors/_server.py +197 -0
  129. flyte/connectors/utils.py +135 -0
  130. flyte/errors.py +243 -0
  131. flyte/extend.py +19 -0
  132. flyte/extras/__init__.py +5 -0
  133. flyte/extras/_container.py +286 -0
  134. flyte/git/__init__.py +3 -0
  135. flyte/git/_config.py +21 -0
  136. flyte/io/__init__.py +29 -0
  137. flyte/io/_dataframe/__init__.py +131 -0
  138. flyte/io/_dataframe/basic_dfs.py +223 -0
  139. flyte/io/_dataframe/dataframe.py +1026 -0
  140. flyte/io/_dir.py +910 -0
  141. flyte/io/_file.py +914 -0
  142. flyte/io/_hashing_io.py +342 -0
  143. flyte/models.py +479 -0
  144. flyte/py.typed +0 -0
  145. flyte/remote/__init__.py +35 -0
  146. flyte/remote/_action.py +738 -0
  147. flyte/remote/_app.py +57 -0
  148. flyte/remote/_client/__init__.py +0 -0
  149. flyte/remote/_client/_protocols.py +189 -0
  150. flyte/remote/_client/auth/__init__.py +12 -0
  151. flyte/remote/_client/auth/_auth_utils.py +14 -0
  152. flyte/remote/_client/auth/_authenticators/__init__.py +0 -0
  153. flyte/remote/_client/auth/_authenticators/base.py +403 -0
  154. flyte/remote/_client/auth/_authenticators/client_credentials.py +73 -0
  155. flyte/remote/_client/auth/_authenticators/device_code.py +117 -0
  156. flyte/remote/_client/auth/_authenticators/external_command.py +79 -0
  157. flyte/remote/_client/auth/_authenticators/factory.py +200 -0
  158. flyte/remote/_client/auth/_authenticators/pkce.py +516 -0
  159. flyte/remote/_client/auth/_channel.py +213 -0
  160. flyte/remote/_client/auth/_client_config.py +85 -0
  161. flyte/remote/_client/auth/_default_html.py +32 -0
  162. flyte/remote/_client/auth/_grpc_utils/__init__.py +0 -0
  163. flyte/remote/_client/auth/_grpc_utils/auth_interceptor.py +288 -0
  164. flyte/remote/_client/auth/_grpc_utils/default_metadata_interceptor.py +151 -0
  165. flyte/remote/_client/auth/_keyring.py +152 -0
  166. flyte/remote/_client/auth/_token_client.py +260 -0
  167. flyte/remote/_client/auth/errors.py +16 -0
  168. flyte/remote/_client/controlplane.py +128 -0
  169. flyte/remote/_common.py +30 -0
  170. flyte/remote/_console.py +19 -0
  171. flyte/remote/_data.py +161 -0
  172. flyte/remote/_logs.py +185 -0
  173. flyte/remote/_project.py +88 -0
  174. flyte/remote/_run.py +386 -0
  175. flyte/remote/_secret.py +142 -0
  176. flyte/remote/_task.py +527 -0
  177. flyte/remote/_trigger.py +306 -0
  178. flyte/remote/_user.py +33 -0
  179. flyte/report/__init__.py +3 -0
  180. flyte/report/_report.py +182 -0
  181. flyte/report/_template.html +124 -0
  182. flyte/storage/__init__.py +36 -0
  183. flyte/storage/_config.py +237 -0
  184. flyte/storage/_parallel_reader.py +274 -0
  185. flyte/storage/_remote_fs.py +34 -0
  186. flyte/storage/_storage.py +456 -0
  187. flyte/storage/_utils.py +5 -0
  188. flyte/syncify/__init__.py +56 -0
  189. flyte/syncify/_api.py +375 -0
  190. flyte/types/__init__.py +52 -0
  191. flyte/types/_interface.py +40 -0
  192. flyte/types/_pickle.py +145 -0
  193. flyte/types/_renderer.py +162 -0
  194. flyte/types/_string_literals.py +119 -0
  195. flyte/types/_type_engine.py +2254 -0
  196. flyte/types/_utils.py +80 -0
  197. flyte-2.0.0b32.data/scripts/debug.py +38 -0
  198. flyte-2.0.0b32.data/scripts/runtime.py +195 -0
  199. flyte-2.0.0b32.dist-info/METADATA +351 -0
  200. flyte-2.0.0b32.dist-info/RECORD +204 -0
  201. flyte-2.0.0b32.dist-info/WHEEL +5 -0
  202. flyte-2.0.0b32.dist-info/entry_points.txt +7 -0
  203. flyte-2.0.0b32.dist-info/licenses/LICENSE +201 -0
  204. flyte-2.0.0b32.dist-info/top_level.txt +1 -0
flyte/types/_utils.py ADDED
@@ -0,0 +1,80 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib
4
+ import typing
5
+
6
+ from flyteidl2.core.types_pb2 import EnumType, LiteralType, UnionType
7
+
8
+ T = typing.TypeVar("T")
9
+
10
+
11
+ def literal_types_match(downstream: LiteralType, upstream: LiteralType) -> bool:
12
+ """
13
+ Returns if two LiteralTypes are the same.
14
+ Takes into account arbitrary ordering of enums and unions, otherwise just an equivalence check.
15
+ """
16
+
17
+ # If the types are exactly the same, return True
18
+ if downstream == upstream:
19
+ return True
20
+
21
+ if downstream.collection_type:
22
+ if not upstream.collection_type:
23
+ return False
24
+ return literal_types_match(downstream.collection_type, upstream.collection_type)
25
+
26
+ if downstream.map_value_type:
27
+ if not upstream.map_value_type:
28
+ return False
29
+ return literal_types_match(downstream.map_value_type, upstream.map_value_type)
30
+
31
+ # Handle enum types
32
+ if downstream.enum_type and upstream.enum_type:
33
+ return _enum_types_match(downstream.enum_type, upstream.enum_type)
34
+
35
+ # Handle union types
36
+ if downstream.union_type and upstream.union_type:
37
+ return _union_types_match(downstream.union_type, upstream.union_type)
38
+
39
+ # If none of the above conditions are met, the types are not castable
40
+ return False
41
+
42
+
43
+ def _enum_types_match(downstream: EnumType, upstream: EnumType) -> bool:
44
+ return set(upstream.values) == set(downstream.values)
45
+
46
+
47
+ def _union_types_match(downstream: UnionType, upstream: UnionType) -> bool:
48
+ if len(downstream.variants) != len(upstream.variants):
49
+ return False
50
+
51
+ down_sorted = sorted(downstream.variants, key=lambda x: str(x))
52
+ up_sorted = sorted(upstream.variants, key=lambda x: str(x))
53
+
54
+ for downstream_variant, upstream_variant in zip(down_sorted, up_sorted):
55
+ if not literal_types_match(downstream_variant, upstream_variant):
56
+ return False
57
+
58
+ return True
59
+
60
+
61
+ def load_type_from_tag(tag: str) -> typing.Type[T]:
62
+ """
63
+ Helper function for proto buf compatibility only. Used in type transformer
64
+ """
65
+
66
+ if "." not in tag:
67
+ raise ValueError(
68
+ f"Protobuf tag must include at least one '.' to delineate package and object name got {tag}",
69
+ )
70
+
71
+ module, name = tag.rsplit(".", 1)
72
+ try:
73
+ pb_module = importlib.import_module(module)
74
+ except ImportError:
75
+ raise ValueError(f"Could not resolve the protobuf definition @ {module}. Is the protobuf library installed?")
76
+
77
+ if not hasattr(pb_module, name):
78
+ raise ValueError(f"Could not find the protobuf named: {name} @ {module}.")
79
+
80
+ return getattr(pb_module, name)
@@ -0,0 +1,38 @@
1
+ import click
2
+
3
+
4
+ @click.group()
5
+ def _debug():
6
+ """Debug commands for Flyte."""
7
+
8
+
9
+ @_debug.command("resume")
10
+ @click.option("--pid", "-m", type=int, required=True, help="PID of the vscode server.")
11
+ def resume(pid):
12
+ """
13
+ Resume a Flyte task for debugging purposes.
14
+
15
+ Args:
16
+ pid (int): PID of the vscode server.
17
+ """
18
+ import os
19
+ import signal
20
+
21
+ print("Terminating server and resuming task.")
22
+ answer = (
23
+ input(
24
+ "This operation will kill the server. All unsaved data will be lost,"
25
+ " and you will no longer be able to connect to it. Do you really want to terminate? (Y/N): "
26
+ )
27
+ .strip()
28
+ .upper()
29
+ )
30
+ if answer == "Y":
31
+ os.kill(pid, signal.SIGTERM)
32
+ print("The server has been terminated and the task has been resumed.")
33
+ else:
34
+ print("Operation canceled.")
35
+
36
+
37
+ if __name__ == "__main__":
38
+ _debug()
@@ -0,0 +1,195 @@
1
+ """
2
+ Flyte runtime module, this is the entrypoint script for the Flyte runtime.
3
+
4
+ Caution: Startup time for this module is very important, as it is the entrypoint for the Flyte runtime.
5
+ Refrain from importing any modules here. If you need to import any modules, do it inside the main function.
6
+ """
7
+
8
+ import asyncio
9
+ import os
10
+ import sys
11
+ from typing import List
12
+
13
+ import click
14
+
15
+ from flyte.models import PathRewrite
16
+
17
+ # Todo: work with pvditt to make these the names
18
+ # ACTION_NAME = "_U_ACTION_NAME"
19
+ # RUN_NAME = "_U_RUN_NAME"
20
+ # PROJECT_NAME = "_U_PROJECT_NAME"
21
+ # DOMAIN_NAME = "_U_DOMAIN_NAME"
22
+ # ORG_NAME = "_U_ORG_NAME"
23
+
24
+ ACTION_NAME = "ACTION_NAME"
25
+ RUN_NAME = "RUN_NAME"
26
+ PROJECT_NAME = "FLYTE_INTERNAL_EXECUTION_PROJECT"
27
+ DOMAIN_NAME = "FLYTE_INTERNAL_EXECUTION_DOMAIN"
28
+ ORG_NAME = "_U_ORG_NAME"
29
+ ENDPOINT_OVERRIDE = "_U_EP_OVERRIDE"
30
+ INSECURE_SKIP_VERIFY_OVERRIDE = "_U_INSECURE_SKIP_VERIFY"
31
+ RUN_OUTPUT_BASE_DIR = "_U_RUN_BASE"
32
+ FLYTE_ENABLE_VSCODE_KEY = "_F_E_VS"
33
+
34
+ _UNION_EAGER_API_KEY_ENV_VAR = "_UNION_EAGER_API_KEY"
35
+ _F_PATH_REWRITE = "_F_PATH_REWRITE"
36
+
37
+
38
+ @click.group()
39
+ def _pass_through():
40
+ pass
41
+
42
+
43
+ @_pass_through.command("a0")
44
+ @click.option("--inputs", "-i", required=True)
45
+ @click.option("--outputs-path", "-o", required=True)
46
+ @click.option("--version", "-v", required=True)
47
+ @click.option("--run-base-dir", envvar=RUN_OUTPUT_BASE_DIR, required=True)
48
+ @click.option("--raw-data-path", "-r", required=False)
49
+ @click.option("--checkpoint-path", "-c", required=False)
50
+ @click.option("--prev-checkpoint", "-p", required=False)
51
+ @click.option("--name", envvar=ACTION_NAME, required=False)
52
+ @click.option("--run-name", envvar=RUN_NAME, required=False)
53
+ @click.option("--project", envvar=PROJECT_NAME, required=False)
54
+ @click.option("--domain", envvar=DOMAIN_NAME, required=False)
55
+ @click.option("--org", envvar=ORG_NAME, required=False)
56
+ @click.option("--debug", envvar=FLYTE_ENABLE_VSCODE_KEY, type=click.BOOL, required=False)
57
+ @click.option("--interactive-mode", type=click.BOOL, required=False)
58
+ @click.option("--image-cache", required=False)
59
+ @click.option("--tgz", required=False)
60
+ @click.option("--pkl", required=False)
61
+ @click.option("--dest", required=False)
62
+ @click.option("--resolver", required=False)
63
+ @click.argument(
64
+ "resolver-args",
65
+ type=click.UNPROCESSED,
66
+ nargs=-1,
67
+ )
68
+ @click.pass_context
69
+ def main(
70
+ ctx: click.Context,
71
+ run_name: str,
72
+ name: str,
73
+ project: str,
74
+ domain: str,
75
+ org: str,
76
+ debug: bool,
77
+ interactive_mode: bool,
78
+ image_cache: str,
79
+ version: str,
80
+ inputs: str,
81
+ run_base_dir: str,
82
+ outputs_path: str,
83
+ raw_data_path: str,
84
+ checkpoint_path: str,
85
+ prev_checkpoint: str,
86
+ tgz: str,
87
+ pkl: str,
88
+ dest: str,
89
+ resolver: str,
90
+ resolver_args: List[str],
91
+ ):
92
+ sys.path.insert(0, ".")
93
+
94
+ import faulthandler
95
+ import signal
96
+
97
+ import flyte
98
+ import flyte._utils as utils
99
+ import flyte.errors
100
+ import flyte.storage as storage
101
+ from flyte._initialize import init_in_cluster
102
+ from flyte._internal.controllers import create_controller
103
+ from flyte._internal.imagebuild.image_builder import ImageCache
104
+ from flyte._internal.runtime.entrypoints import load_and_run_task
105
+ from flyte._logging import logger
106
+ from flyte.models import ActionID, Checkpoints, CodeBundle, RawDataPath
107
+
108
+ logger.info("Registering faulthandler for SIGUSR1")
109
+ faulthandler.register(signal.SIGUSR1)
110
+
111
+ logger.info(f"Initializing flyte runtime - version {flyte.__version__}")
112
+ assert org, "Org is required for now"
113
+ assert project, "Project is required"
114
+ assert domain, "Domain is required"
115
+ assert run_name, f"Run name is required {run_name}"
116
+ assert name, f"Action name is required {name}"
117
+
118
+ if run_name.startswith("{{"):
119
+ run_name = os.getenv("RUN_NAME", "")
120
+ if name.startswith("{{"):
121
+ name = os.getenv("ACTION_NAME", "")
122
+
123
+ logger.warning(f"Flyte runtime started for action {name} with run name {run_name}")
124
+
125
+ if debug and name == "a0":
126
+ from flyte._debug.vscode import _start_vscode_server
127
+
128
+ asyncio.run(_start_vscode_server(ctx))
129
+
130
+ controller_kwargs = init_in_cluster(org=org, project=project, domain=domain)
131
+ bundle = None
132
+ if tgz or pkl:
133
+ bundle = CodeBundle(tgz=tgz, pkl=pkl, destination=dest, computed_version=version)
134
+ # Controller is created with the same kwargs as init, so that it can be used to run tasks
135
+ controller = create_controller(ct="remote", **controller_kwargs)
136
+
137
+ ic = ImageCache.from_transport(image_cache) if image_cache else None
138
+
139
+ path_rewrite_cfg = os.getenv(_F_PATH_REWRITE, None)
140
+ path_rewrite = None
141
+ if path_rewrite_cfg:
142
+ potential_path_rewrite = PathRewrite.from_str(path_rewrite_cfg)
143
+ if storage.exists_sync(potential_path_rewrite.new_prefix):
144
+ path_rewrite = potential_path_rewrite
145
+ logger.info(f"Path rewrite configured for {path_rewrite.new_prefix}")
146
+ else:
147
+ logger.error(
148
+ f"Path rewrite failed for path {potential_path_rewrite.new_prefix}, "
149
+ f"not found, reverting to original path {potential_path_rewrite.old_prefix}"
150
+ )
151
+
152
+ # Create a coroutine to load the task and run it
153
+ task_coroutine = load_and_run_task(
154
+ resolver=resolver,
155
+ resolver_args=resolver_args,
156
+ action=ActionID(name=name, run_name=run_name, project=project, domain=domain, org=org),
157
+ raw_data_path=RawDataPath(path=raw_data_path, path_rewrite=path_rewrite),
158
+ checkpoints=Checkpoints(checkpoint_path, prev_checkpoint),
159
+ code_bundle=bundle,
160
+ input_path=inputs,
161
+ output_path=outputs_path,
162
+ run_base_dir=run_base_dir,
163
+ version=version,
164
+ controller=controller,
165
+ image_cache=ic,
166
+ interactive_mode=interactive_mode or debug,
167
+ )
168
+ # Create a coroutine to watch for errors
169
+ controller_failure = controller.watch_for_errors()
170
+
171
+ # Run both coroutines concurrently and wait for first to finish and cancel the other
172
+ async def _run_and_stop():
173
+ loop = asyncio.get_event_loop()
174
+ loop.set_exception_handler(flyte.errors.silence_grpc_polling_error)
175
+ try:
176
+ await utils.run_coros(controller_failure, task_coroutine)
177
+ await controller.stop()
178
+ except flyte.errors.RuntimeSystemError as e:
179
+ logger.error(f"Runtime system error: {e}")
180
+ from flyte._internal.runtime.convert import convert_from_native_to_error
181
+ from flyte._internal.runtime.io import upload_error
182
+
183
+ logger.error(f"Flyte runtime failed for action {name} with run name {run_name}, error: {e}")
184
+ err = convert_from_native_to_error(e)
185
+ path = await upload_error(err.err, outputs_path)
186
+ logger.error(f"Run {run_name} Action {name} failed with error: {err}. Uploaded error to {path}")
187
+ await controller.stop()
188
+ raise
189
+
190
+ asyncio.run(_run_and_stop())
191
+ logger.warning(f"Flyte runtime completed for action {name} with run name {run_name}")
192
+
193
+
194
+ if __name__ == "__main__":
195
+ _pass_through()
@@ -0,0 +1,351 @@
1
+ Metadata-Version: 2.4
2
+ Name: flyte
3
+ Version: 2.0.0b32
4
+ Summary: Add your description here
5
+ Author-email: Ketan Umare <kumare3@users.noreply.github.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: aiofiles>=24.1.0
10
+ Requires-Dist: click>=8.2.1
11
+ Requires-Dist: flyteidl<2.0.0,>=1.15.4b0
12
+ Requires-Dist: cloudpickle>=3.1.1
13
+ Requires-Dist: fsspec>=2025.3.0
14
+ Requires-Dist: grpcio>=1.71.0
15
+ Requires-Dist: obstore>=0.7.3
16
+ Requires-Dist: protobuf>=6.30.1
17
+ Requires-Dist: pydantic>=2.10.6
18
+ Requires-Dist: pyyaml>=6.0.2
19
+ Requires-Dist: rich-click==1.8.9
20
+ Requires-Dist: httpx<1.0.0,>=0.28.1
21
+ Requires-Dist: keyring>=25.6.0
22
+ Requires-Dist: msgpack>=1.1.0
23
+ Requires-Dist: toml>=0.10.2
24
+ Requires-Dist: async-lru>=2.0.5
25
+ Requires-Dist: mashumaro
26
+ Requires-Dist: dataclasses_json
27
+ Requires-Dist: aiolimiter>=1.2.1
28
+ Requires-Dist: flyteidl2==2.0.0a14
29
+ Provides-Extra: aiosqlite
30
+ Requires-Dist: aiosqlite>=0.21.0; extra == "aiosqlite"
31
+ Provides-Extra: connector
32
+ Requires-Dist: grpcio-health-checking; extra == "connector"
33
+ Requires-Dist: httpx; extra == "connector"
34
+ Requires-Dist: prometheus-client; extra == "connector"
35
+ Dynamic: license-file
36
+
37
+ # Flyte 2 SDK ๐Ÿš€
38
+
39
+ **Type-safe, distributed orchestration of agents, ML pipelines, and more โ€” in pure Python with async/await or sync!**
40
+
41
+ [![Version](https://img.shields.io/pypi/v/flyte?label=version&color=blue)](https://pypi.org/project/flyte/)
42
+ [![Python](https://img.shields.io/pypi/pyversions/flyte?color=brightgreen)](https://pypi.org/project/flyte/)
43
+ [![License](https://img.shields.io/badge/license-Apache%202.0-orange)](LICENSE)
44
+
45
+ > โšก **Pure Python workflows** โ€ข ๐Ÿ”„ **Async-first parallelism** โ€ข ๐Ÿ› ๏ธ **Zero DSL constraints** โ€ข ๐Ÿ“Š **Sub-task observability**
46
+
47
+ ## ๐ŸŒ Ecosystem & Resources
48
+
49
+ - **๐Ÿ“– Documentation**: [Docs Link](https://www.union.ai/docs/v2/flyte/user-guide/)
50
+ - **โ–ถ๏ธ Getting Started**: [Docs Link](https://www.union.ai/docs/v2/flyte/user-guide/getting-started/)
51
+ - **๐Ÿ’ฌ Community**: [Slack](https://slack.flyte.org/) | [GitHub Discussions](https://github.com/flyteorg/flyte/discussions)
52
+ - **๐ŸŽ“ Examples**: [GitHub Examples](https://github.com/flyteorg/flyte-sdk/tree/main/examples)
53
+ - **๐Ÿ› Issues**: [Bug Reports](https://github.com/flyteorg/flyte/issues)
54
+
55
+ ## What is Flyte 2?
56
+
57
+ 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.
58
+
59
+ ```python
60
+ import flyte
61
+
62
+ env = flyte.TaskEnvironment("hello_world")
63
+
64
+ @env.task
65
+ async def process_data(data: list[str]) -> list[str]:
66
+ # Use any Python construct: loops, conditionals, try/except
67
+ results = []
68
+ for item in data:
69
+ if len(item) > 5:
70
+ results.append(await transform_item(item))
71
+ return results
72
+
73
+ @env.task
74
+ async def transform_item(item: str) -> str:
75
+ return f"processed: {item.upper()}"
76
+
77
+ if __name__ == "__main__":
78
+ flyte.init()
79
+ result = flyte.run(process_data, data=["hello", "world", "flyte"])
80
+ ```
81
+
82
+ ## ๐ŸŒŸ Why Flyte 2?
83
+
84
+ | Feature Highlight | Flyte 1 | Flyte 2 |
85
+ |-| ------- | ------- |
86
+ | **No More Workflow DSL** | โŒ `@workflow` decorators with Python subset limitations | โœ… **Pure Python**: loops, conditionals, error handling, dynamic structures |
87
+ | **Async-First Parallelism** | โŒ Custom `map()` functions and workflow-specific parallel constructs | โœ… **Native `asyncio`**: `await asyncio.gather()` for distributed parallel execution |
88
+ | **Fine-Grained Observability** | โŒ Task-level logging only | โœ… **Function-level tracing** with `@flyte.trace` for sub-task checkpoints |
89
+
90
+ ## ๐Ÿš€ Quick Start
91
+
92
+ ### Installation
93
+
94
+ ```bash
95
+ # Install uv package manager
96
+ curl -LsSf https://astral.sh/uv/install.sh | sh
97
+
98
+ # Create virtual environment
99
+ uv venv && source .venv/bin/activate
100
+
101
+ # Install Flyte 2 (beta)
102
+ uv pip install --prerelease=allow flyte
103
+ ```
104
+
105
+ ### Your First Workflow
106
+
107
+ ```python
108
+ # hello.py
109
+ # /// script
110
+ # requires-python = ">=3.10"
111
+ # dependencies = ["flyte>=2.0.0b0"]
112
+ # ///
113
+
114
+ import flyte
115
+
116
+ env = flyte.TaskEnvironment(
117
+ name="hello_world",
118
+ resources=flyte.Resources(memory="250Mi")
119
+ )
120
+
121
+ @env.task
122
+ def calculate(x: int) -> int:
123
+ return x * 2 + 5
124
+
125
+ @env.task
126
+ async def main(numbers: list[int]) -> float:
127
+ # Parallel execution across distributed containers
128
+ results = await asyncio.gather(*[
129
+ calculate.aio(num) for num in numbers
130
+ ])
131
+ return sum(results) / len(results)
132
+
133
+ if __name__ == "__main__":
134
+ flyte.init_from_config("config.yaml")
135
+ run = flyte.run(main, numbers=list(range(10)))
136
+ print(f"Result: {run.result}")
137
+ print(f"View at: {run.url}")
138
+ ```
139
+
140
+ ```bash
141
+ # Run locally, execute remotely
142
+ uv run --prerelease=allow hello.py
143
+ ```
144
+
145
+ ## ๐Ÿ—๏ธ Core Concepts
146
+
147
+ ### **TaskEnvironments**: Container Configuration Made Simple
148
+
149
+ ```python
150
+ # Group tasks with shared configuration
151
+ env = flyte.TaskEnvironment(
152
+ name="ml_pipeline",
153
+ image=flyte.Image.from_debian_base().with_pip_packages(
154
+ "torch", "pandas", "scikit-learn"
155
+ ),
156
+ resources=flyte.Resources(cpu=4, memory="8Gi", gpu=1),
157
+ reusable=flyte.ReusePolicy(replicas=3, idle_ttl=300)
158
+ )
159
+
160
+ @env.task
161
+ def train_model(data: flyte.File) -> flyte.File:
162
+ # Runs in configured container with GPU access
163
+ pass
164
+
165
+ @env.task
166
+ def evaluate_model(model: flyte.File, test_data: flyte.File) -> dict:
167
+ # Same container configuration, different instance
168
+ pass
169
+ ```
170
+
171
+ ### **Pure Python Workflows**: No More DSL Constraints
172
+
173
+ ```python
174
+ @env.task
175
+ async def dynamic_pipeline(config: dict) -> list[str]:
176
+ results = []
177
+
178
+ # โœ… Use any Python construct
179
+ for dataset in config["datasets"]:
180
+ try:
181
+ # โœ… Native error handling
182
+ if dataset["type"] == "batch":
183
+ result = await process_batch(dataset)
184
+ else:
185
+ result = await process_stream(dataset)
186
+ results.append(result)
187
+ except ValidationError as e:
188
+ # โœ… Custom error recovery
189
+ result = await handle_error(dataset, e)
190
+ results.append(result)
191
+
192
+ return results
193
+ ```
194
+
195
+ ### **Async Parallelism**: Distributed by Default
196
+
197
+ ```python
198
+ @env.task
199
+ async def parallel_training(hyperparams: list[dict]) -> dict:
200
+ # Each model trains on separate infrastructure
201
+ models = await asyncio.gather(*[
202
+ train_model.aio(params) for params in hyperparams
203
+ ])
204
+
205
+ # Evaluate all models in parallel
206
+ evaluations = await asyncio.gather(*[
207
+ evaluate_model.aio(model) for model in models
208
+ ])
209
+
210
+ # Find best model
211
+ best_idx = max(range(len(evaluations)),
212
+ key=lambda i: evaluations[i]["accuracy"])
213
+ return {"best_model": models[best_idx], "accuracy": evaluations[best_idx]}
214
+ ```
215
+
216
+ ## ๐ŸŽฏ Advanced Features
217
+
218
+ ### **Sub-Task Observability with Tracing**
219
+
220
+ ```python
221
+ @flyte.trace
222
+ async def expensive_computation(data: str) -> str:
223
+ # Function-level checkpointing - recoverable on failure
224
+ result = await call_external_api(data)
225
+ return process_result(result)
226
+
227
+ @env.task(cache=flyte.Cache(behavior="auto"))
228
+ async def main_task(inputs: list[str]) -> list[str]:
229
+ results = []
230
+ for inp in inputs:
231
+ # If task fails here, it resumes from the last successful trace
232
+ result = await expensive_computation(inp)
233
+ results.append(result)
234
+ return results
235
+ ```
236
+
237
+ ### **Remote Task Execution**
238
+
239
+ ```python
240
+ import flyte.remote
241
+
242
+ # Reference tasks deployed elsewhere
243
+ torch_task = flyte.remote.Task.get("torch_env.train_model", auto_version="latest")
244
+ spark_task = flyte.remote.Task.get("spark_env.process_data", auto_version="latest")
245
+
246
+ @env.task
247
+ async def orchestrator(raw_data: flyte.File) -> flyte.File:
248
+ # Execute Spark job on big data cluster
249
+ processed = await spark_task(raw_data)
250
+
251
+ # Execute PyTorch training on GPU cluster
252
+ model = await torch_task(processed)
253
+
254
+ return model
255
+ ```
256
+
257
+ ## ๐Ÿ“Š Native Jupyter Integration
258
+
259
+ Run and monitor workflows directly from notebooks:
260
+
261
+ ```python
262
+ # In Jupyter cell
263
+ import flyte
264
+
265
+ flyte.init_from_config()
266
+ run = flyte.run(my_workflow, data=large_dataset)
267
+
268
+ # Stream logs in real-time
269
+ run.logs.stream()
270
+
271
+ # Get outputs when complete
272
+ results = run.wait()
273
+ ```
274
+
275
+ ## ๐Ÿ”ง Configuration & Deployment
276
+
277
+ ### Configuration File
278
+
279
+ ```yaml
280
+ # config.yaml
281
+ endpoint: https://my-flyte-instance.com
282
+ project: ml-team
283
+ domain: production
284
+ image:
285
+ builder: local
286
+ registry: ghcr.io/my-org
287
+ auth:
288
+ type: oauth2
289
+ ```
290
+
291
+ ### Deploy and Run
292
+
293
+ ```bash
294
+ # Deploy tasks to remote cluster
295
+ flyte deploy my_workflow.py
296
+
297
+ # Run deployed workflow
298
+ flyte run my_workflow --input-file params.json
299
+
300
+ # Monitor execution
301
+ flyte logs <execution-id>
302
+ ```
303
+
304
+ ## Migration from Flyte 1
305
+
306
+ | Flyte 1 | Flyte 2 |
307
+ |---------|---------|
308
+ | `@workflow` + `@task` | `@env.task` only |
309
+ | `flytekit.map()` | `await asyncio.gather()` |
310
+ | `@dynamic` workflows | Regular `@env.task` with loops |
311
+ | `flytekit.conditional()` | Python `if/else` |
312
+ | `LaunchPlan` schedules | `@env.task(on_schedule=...)` |
313
+ | Workflow failure handlers | Python `try/except` |
314
+
315
+ ## ๐Ÿค Contributing
316
+
317
+ We welcome contributions! Whether it's:
318
+
319
+ - ๐Ÿ› **Bug fixes**
320
+ - โœจ **New features**
321
+ - ๐Ÿ“š **Documentation improvements**
322
+ - ๐Ÿงช **Testing enhancements**
323
+
324
+ ### Setup & Iteration Cycle
325
+ 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.
326
+
327
+ ```bash
328
+ uv venv --python 3.13
329
+ uv pip install -e .
330
+ ```
331
+
332
+ Besides from picking up local code changes, installing the package in editable mode
333
+ also changes the definition of the default `Image()` object to use a locally
334
+ build wheel. You will need to build said wheel by yourself though, with the `make dist` target.
335
+
336
+ ```bash
337
+ make dist
338
+ python maint_tools/build_default_image.py
339
+ ```
340
+ You'll need to have a local docker daemon running for this. The build script does nothing
341
+ 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
342
+ access to push to the default registry. If you don't have access, please make sure to
343
+ specify the registry and name to the build script.
344
+
345
+ ```bash
346
+ python maint_tools/build_default_image.py --registry ghcr.io/my-org --name my-flyte-image
347
+ ```
348
+
349
+ ## ๐Ÿ“„ License
350
+
351
+ Flyte 2 is licensed under the [Apache 2.0 License](LICENSE).