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/__init__.py ADDED
@@ -0,0 +1,108 @@
1
+ """
2
+ Flyte SDK for authoring compound AI applications, services and workflows.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import sys
8
+
9
+ from ._build import build
10
+ from ._cache import Cache, CachePolicy, CacheRequest
11
+ from ._context import ctx
12
+ from ._custom_context import custom_context, get_custom_context
13
+ from ._deploy import build_images, deploy
14
+ from ._environment import Environment
15
+ from ._excepthook import custom_excepthook
16
+ from ._group import group
17
+ from ._image import Image
18
+ from ._initialize import current_domain, init, init_from_config, init_in_cluster
19
+ from ._logging import logger
20
+ from ._map import map
21
+ from ._pod import PodTemplate
22
+ from ._resources import AMD_GPU, GPU, HABANA_GAUDI, TPU, Device, DeviceClass, Neuron, Resources
23
+ from ._retry import RetryStrategy
24
+ from ._reusable_environment import ReusePolicy
25
+ from ._run import run, with_runcontext
26
+ from ._secret import Secret, SecretRequest
27
+ from ._task_environment import TaskEnvironment
28
+ from ._timeout import Timeout, TimeoutType
29
+ from ._trace import trace
30
+ from ._trigger import Cron, FixedRate, Trigger, TriggerTime
31
+ from ._version import __version__
32
+
33
+ sys.excepthook = custom_excepthook
34
+
35
+
36
+ def _silence_grpc_warnings():
37
+ """
38
+ Silences gRPC warnings that can clutter the output.
39
+ """
40
+ import os
41
+
42
+ # Set environment variables for gRPC, this reduces log spew and avoids unnecessary warnings
43
+ # before importing grpc
44
+ if "GRPC_VERBOSITY" not in os.environ:
45
+ os.environ["GRPC_VERBOSITY"] = "ERROR"
46
+ os.environ["GRPC_CPP_MIN_LOG_LEVEL"] = "ERROR"
47
+ # Disable fork support (stops "skipping fork() handlers")
48
+ os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "0"
49
+ # Reduce absl/glog verbosity
50
+ os.environ["GLOG_minloglevel"] = "2"
51
+ os.environ["ABSL_LOG"] = "0"
52
+
53
+
54
+ _silence_grpc_warnings()
55
+
56
+
57
+ def version() -> str:
58
+ """
59
+ Returns the version of the Flyte SDK.
60
+ """
61
+ return __version__
62
+
63
+
64
+ __all__ = [
65
+ "AMD_GPU",
66
+ "GPU",
67
+ "HABANA_GAUDI",
68
+ "TPU",
69
+ "Cache",
70
+ "CachePolicy",
71
+ "CacheRequest",
72
+ "Cron",
73
+ "Device",
74
+ "DeviceClass",
75
+ "Environment",
76
+ "FixedRate",
77
+ "Image",
78
+ "Neuron",
79
+ "PodTemplate",
80
+ "Resources",
81
+ "RetryStrategy",
82
+ "ReusePolicy",
83
+ "Secret",
84
+ "SecretRequest",
85
+ "TaskEnvironment",
86
+ "Timeout",
87
+ "TimeoutType",
88
+ "Trigger",
89
+ "TriggerTime",
90
+ "__version__",
91
+ "build",
92
+ "build_images",
93
+ "ctx",
94
+ "current_domain",
95
+ "custom_context",
96
+ "deploy",
97
+ "get_custom_context",
98
+ "group",
99
+ "init",
100
+ "init_from_config",
101
+ "init_in_cluster",
102
+ "logger",
103
+ "map",
104
+ "run",
105
+ "trace",
106
+ "version",
107
+ "with_runcontext",
108
+ ]
flyte/_bin/__init__.py ADDED
File without changes
flyte/_bin/debug.py ADDED
@@ -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()
flyte/_bin/runtime.py ADDED
@@ -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()
flyte/_bin/serve.py ADDED
@@ -0,0 +1,178 @@
1
+ """
2
+ Flyte runtime serve module. This is used to serve Apps/serving.
3
+ """
4
+
5
+ import asyncio
6
+ import logging
7
+ from typing import Tuple
8
+
9
+ import click
10
+
11
+ from flyte.models import CodeBundle
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ PROJECT_NAME = "FLYTE_INTERNAL_EXECUTION_PROJECT"
16
+ DOMAIN_NAME = "FLYTE_INTERNAL_EXECUTION_DOMAIN"
17
+ ORG_NAME = "_U_ORG_NAME"
18
+ _UNION_EAGER_API_KEY_ENV_VAR = "_UNION_EAGER_API_KEY"
19
+ _F_PATH_REWRITE = "_F_PATH_REWRITE"
20
+ ENDPOINT_OVERRIDE = "_U_EP_OVERRIDE"
21
+
22
+
23
+ async def sync_inputs(serialized_inputs: str, dest: str) -> Tuple[dict, dict]:
24
+ """
25
+ Converts inputs into simple dict of name to value, downloading any files/directories as needed.
26
+
27
+ Args:
28
+ serialized_inputs (str): The serialized inputs string.
29
+ dest: Destination to download inputs to
30
+
31
+ Returns:
32
+ Tuple[dict, dict]: A tuple containing the output dictionary and the environment variables dictionary.
33
+ The output dictionary maps input names to their values.
34
+ The environment variables dictionary maps environment variable names to their values.
35
+ """
36
+ import flyte.storage as storage
37
+ from flyte.app._input import SerializableInputCollection
38
+
39
+ user_inputs = SerializableInputCollection.from_transport(serialized_inputs)
40
+
41
+ output = {}
42
+ env_vars = {}
43
+
44
+ for input in user_inputs.inputs:
45
+ if input.download:
46
+ user_dest = input.dest or dest
47
+ if input.type == "file":
48
+ value = await storage.get(input.value, user_dest)
49
+ elif input.type == "directory":
50
+ value = await storage.get(input.value, user_dest, recursive=True)
51
+ else:
52
+ raise ValueError("Can only download files or directories")
53
+ else:
54
+ value = input.value
55
+
56
+ output[input.name] = value
57
+
58
+ if input.env_var:
59
+ env_vars[input.env_var] = value
60
+
61
+ return output, env_vars
62
+
63
+
64
+ async def download_code_inputs(
65
+ serialized_inputs: str, tgz: str, pkl: str, dest: str, version: str
66
+ ) -> Tuple[dict, dict, CodeBundle | None]:
67
+ from flyte._internal.runtime.entrypoints import download_code_bundle
68
+
69
+ user_inputs: dict[str, str] = {}
70
+ env_vars: dict[str, str] = {}
71
+ if serialized_inputs and len(serialized_inputs) > 0:
72
+ user_inputs, env_vars = await sync_inputs(serialized_inputs, dest)
73
+ code_bundle: CodeBundle | None = None
74
+ if tgz or pkl:
75
+ bundle = CodeBundle(tgz=tgz, pkl=pkl, destination=dest, computed_version=version)
76
+ code_bundle = await download_code_bundle(bundle)
77
+
78
+ return user_inputs, env_vars, code_bundle
79
+
80
+
81
+ @click.command()
82
+ @click.option("--inputs", "-i", required=False)
83
+ @click.option("--version", required=True)
84
+ @click.option("--interactive-mode", type=click.BOOL, required=False)
85
+ @click.option("--image-cache", required=False)
86
+ @click.option("--tgz", required=False)
87
+ @click.option("--pkl", required=False)
88
+ @click.option("--dest", required=False)
89
+ @click.option("--project", envvar=PROJECT_NAME, required=False)
90
+ @click.option("--domain", envvar=DOMAIN_NAME, required=False)
91
+ @click.option("--org", envvar=ORG_NAME, required=False)
92
+ @click.argument("command", nargs=-1, type=click.UNPROCESSED)
93
+ def main(
94
+ inputs: str | None,
95
+ version: str,
96
+ interactive_mode: bool,
97
+ image_cache: str,
98
+ tgz: str,
99
+ pkl: str,
100
+ dest: str,
101
+ command: Tuple[str, ...] | None = None,
102
+ project: str | None = None,
103
+ domain: str | None = None,
104
+ org: str | None = None,
105
+ ):
106
+ import json
107
+ import os
108
+ import signal
109
+ from subprocess import Popen
110
+
111
+ from flyte.app._input import RUNTIME_INPUTS_FILE
112
+
113
+ logger.info("Starting flyte-serve")
114
+ # TODO Do we need to init here?
115
+ # from flyte._initialize import init
116
+ # remote_kwargs: dict[str, Any] = {"insecure": False}
117
+ # if api_key := os.getenv(_UNION_EAGER_API_KEY_ENV_VAR):
118
+ # logger.info("Using api key from environment")
119
+ # remote_kwargs["api_key"] = api_key
120
+ # else:
121
+ # ep = os.environ.get(ENDPOINT_OVERRIDE, "host.docker.internal:8090")
122
+ # remote_kwargs["endpoint"] = ep
123
+ # if "localhost" in ep or "docker" in ep:
124
+ # remote_kwargs["insecure"] = True
125
+ # logger.debug(f"Using controller endpoint: {ep} with kwargs: {remote_kwargs}")
126
+ # init(org=org, project=project, domain=domain, image_builder="remote") # , **remote_kwargs)
127
+
128
+ materialized_inputs, env_vars, _code_bundle = asyncio.run(
129
+ download_code_inputs(
130
+ serialized_inputs=inputs or "",
131
+ tgz=tgz or "",
132
+ pkl=pkl or "",
133
+ dest=dest or os.getcwd(),
134
+ version=version,
135
+ )
136
+ )
137
+
138
+ for key, value in env_vars.items():
139
+ # set environment variables defined in the AppEnvironment Inputs
140
+ logger.info(f"Setting environment variable {key}='{value}'")
141
+ os.environ[key] = value
142
+
143
+ inputs_file = os.path.join(os.getcwd(), RUNTIME_INPUTS_FILE)
144
+ with open(inputs_file, "w") as f:
145
+ json.dump(materialized_inputs, f)
146
+
147
+ os.environ[RUNTIME_INPUTS_FILE] = inputs_file
148
+
149
+ if command is None or len(command) == 0:
150
+ raise ValueError("No command provided to execute")
151
+
152
+ command_list = []
153
+ for arg in command:
154
+ logger.info(f"Processing arg: {arg}")
155
+ if arg.startswith("$"):
156
+ # expand environment variables in the user-defined command
157
+ val = os.getenv(arg[1:])
158
+ if val is None:
159
+ raise ValueError(f"Environment variable {arg[1:]} not found")
160
+ logger.info(f"Found env var {arg}.")
161
+ command_list.append(val)
162
+ else:
163
+ command_list.append(arg)
164
+
165
+ command_joined = " ".join(command_list)
166
+ logger.info(f"Serving command: {command_joined}")
167
+ p = Popen(command_joined, env=os.environ, shell=True)
168
+
169
+ def handle_sigterm(signum, frame):
170
+ p.send_signal(signum)
171
+
172
+ signal.signal(signal.SIGTERM, handle_sigterm)
173
+ returncode = p.wait()
174
+ exit(returncode)
175
+
176
+
177
+ if __name__ == "__main__":
178
+ main()
flyte/_build.py ADDED
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ from flyte.syncify import syncify
4
+
5
+ from ._image import Image
6
+
7
+
8
+ @syncify
9
+ async def build(image: Image) -> str:
10
+ """
11
+ Build an image. The existing async context will be used.
12
+
13
+ Example:
14
+ ```
15
+ import flyte
16
+ image = flyte.Image("example_image")
17
+ if __name__ == "__main__":
18
+ asyncio.run(flyte.build.aio(image))
19
+ ```
20
+
21
+ :param image: The image(s) to build.
22
+ :return: The image URI.
23
+ """
24
+ from flyte._internal.imagebuild.image_builder import ImageBuildEngine
25
+
26
+ return await ImageBuildEngine.build(image)
@@ -0,0 +1,12 @@
1
+ from .cache import Cache, CacheBehavior, CachePolicy, CacheRequest
2
+ from .defaults import get_default_policies
3
+ from .policy_function_body import FunctionBodyPolicy
4
+
5
+ __all__ = [
6
+ "Cache",
7
+ "CacheBehavior",
8
+ "CachePolicy",
9
+ "CacheRequest",
10
+ "FunctionBodyPolicy",
11
+ "get_default_policies",
12
+ ]